PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit Interrupt durch verschiedene Programmteile Springen



Teddynator
04.01.2009, 22:17
Hallo,

Bin leider noch ziemlicher Anfänger in Sachen C. vielleicht kann mir einer von euch bei folgendem Problem helfen.

Ich habe eine PWM für eine RGB LED auf einen Atmega8 programmiert, so dass sie ständig die Farbe wechselt. nun soll man aber über einen Taster der einen Interrupt auslöst und eine Variable setzt die LED auf weiß schalten können. das ganze funktioniert soweit auch recht gut, nur dass die LED eben erst nach dem durchlauf der PWM sequenz auf weiß wechselt. Gibt es eine Möglichkeit nach dem Interrupt Programm direkt zum Programmteil "Weiß" zu springen? oder wüsstet ihr eine einfachere Lösung so etwas zu Programmieren?

hier mein Programm (ohne das delay Unterprogramm und die PWM unterprogramme)


#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

void delay(unsigned int ms);
void LED2DIMIN(void);
void LED1DIMIN(void);
void LED2DIMOUT(void);
void LED1DIMOUT(void);
void LED3DIMIN(void);
void LED3DIMOUT(void);
int i;
int a;
int b;
int c = 50; //geschwindigkeit Dimmer höherer Wert = langsamer
int d = 0;

ISR(INT0_vect) //Interrupt
{
if (d==0)
{
d=1;
}
else
{
d=0;
}
}

void main(void) //Hauptprogramm
{
DDRD = 0b11100000; //Pin 765 = Output 0-4 = Input
GICR|=(1<<INT0); //enables ext Interrupt (Pin 4, INT0)
MCUCR = 0b00000011; //Steigende Flanke an INT0 Löst aus
sei (); //Global Interrupt enable

while(1)
{
if (d==0)
{
PORTD &= ~(1 << PD5);
PORTD &= ~(1 << PD6);
PORTD |= (1 << PD7);
LED2DIMIN(); //blau
LED3DIMOUT(); //rot weg
LED1DIMIN(); //grün
LED2DIMOUT(); //blau weg
LED3DIMIN(); //rot
LED1DIMOUT(); //grün weg
}
else
{
PORTD |= (1 << PD7); //weiß
PORTD |= (1 << PD6);
PORTD |= (1 << PD5);
}
}
}


Wäre froh wenn Mir jemand helfen könnte

vielen Dank

thewulf00
05.01.2009, 13:08
Was machen die Funktionen
void LED2DIMIN(void);
void LED1DIMIN(void);
void LED2DIMOUT(void);
void LED1DIMOUT(void);
void LED3DIMIN(void);
void LED3DIMOUT(void);
?

Diese müsste man von einem Interrupt/Timer aus steuern, dann kann man jederzeit unterbrechen.

So habe ich es gemacht:
In einem Timer wird die PWM gesteuert. (eine Variable wird erhöht, ist der gewählte PWM-Wert über der Variable bleibt die LED an, ansonsten geht sie aus)

Die PWM-Werte an sich werden von einem 2. Timer aus langsam verändert. Dadurch kommt die Farbänderung zustande.

Nun kann man die weiß-Abfrage in beiden Timern realisieren, im Timer1 wäre es sicherlich sinnvoller.

Teddynator
05.01.2009, 16:44
Erst mal danke für deine Antwort, thewulf00

Was machen die Funktionen
void LED2DIMIN(void);
void LED1DIMIN(void);
void LED2DIMOUT(void);
void LED1DIMOUT(void);
void LED3DIMIN(void);
void LED3DIMOUT(void);
?

Diese Funktionen erzeugen per Software (ohne Timer, eben nur mit der delay Funktion) ein PWM signal, dass die jeweilige Farbe eben einblendet bzw ausblendet. jedes dieser Programme sieht in etwa so aus:

void LED2DIMIN(void) //Blau ein
{
a = 0;
for(i=1;i<256;i++)
{
for(b=1;b<c;b++)
{
PORTD |= (1 << PD5); //high
delay (a);
PORTD &= ~(1 << PD5); //low
delay (256-a);
}
a++;
}
PORTD |= (1 << PD5);
}

ich weiß dass das ganze Programm ziemlich Chaotisch ist, und dass sich die PWM Signale auch mit Timern realisieren lassen würden. Leider hab ich davon noch weniger Ahnung wie ich das anstellen sollte. Wie gesagt hab erst angefangen C zu programmieren bzw überhaupt zu Programmieren. Kannst du mir vielleicht irgend ein Beispiel geben, wie du das mit Timern machen würdest?