PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit UART und TIMER Interrupt



MT2009
15.06.2010, 12:27
Hallo,

ich bin neu hier im Forum und benötige eure Hilfe zum angehängten Code für einen ATMega128.

Ziel ist es zunächst, bei einer bestimmten Anzahl von Timer-Overflows einen Ausgang zu togglen. Die Anzahl der Overflows soll dabei über die serielle Schnittstelle (Programm HTERM) eingestellt werden.

Doch leider ist das bisher nicht möglich. Gebe ich zum Beispiel die Zahl 256 (Timer-Overflow = 2sec.) in HTerm ein, so wird die Zahl gesendet und ich kriege auch ein Echo zurück, aber das Relais toggled nicht im 2sec. Takt. Was ist falsch an meinem Code?

Vielen Dank für eure Hilfe.

Gruß,
Matze

radbruch
15.06.2010, 13:49
Hallo

ISR (USART0_RX_vect) //USART, Rx Complete
{
Time = UDR0; //UDR0 in Variable 'Time'
UDR0 = Time; //Echo
}

Liest ein Zeichen und sendet es zurück. Wenn du 255 sendest sind die Zeichen "2", "5" und "5". Nun wird der Overflow neu gesetzt:

if (overflow == Time)

Time enthält nun aber nicht wie erwartet 255, es enthält nacheinander die Ascii-Werte der Zeichen: "2", "5" und "5".

Ganz einfacher Lösungsansatz:

volatile unsigned int Time;
ISR (USART0_RX_vect) //USART, Rx Complete
{
Time = UDR0; //UDR0 in Variable 'Time'
UDR0 = Time; //Echo
Time = (1+Time-'0')*25;
}

'0' wäre dann overflow==25, '9' wäre 250.

Steiniger Weg: Die USART-ISR erkennt den Start eines neuen Wertes (der sich aus mehreren Ascii-Zeichen '0'-'9' zusammensetzt), speichert alle zum Wert gehörenden Zeichen bis das Ende erkannt wird. Dann werden die gespeicherten Zeichen in einen Wert umgerechnet und an Time übergeben. Hier könnte ein Ansatz etwa so aussehen:


volatile unsigned int Time=0;
ISR (USART0_RX_vect) //USART, Rx Complete
{
static unsigned char zeichennummer=0; // Zeiger im String
static unsigned char zeichenkette[4]={0,0,0,0}; // String mit Endekennung '0'!
unsigned char zeichen;
zeichen = UDR0; //UDR0 in Variable 'zeichen' ???

switch(zeichen)
{
case '*': zeichennummer=0; break; // Start des Parameters erkannt
case '#': if(zeichennummer==3) // 3 Zeichen im String?
{
Time=atoi(zeichenkette); // Wert berechenen und übergeben
}
else
{
zeichennummer=0; // Neustart!
zeichen='!'; // Fehlermeldung senden
}
break;
default: if((zeichen >= '0') && (zeichen <= '9') && (zeichennummer < 3))
{
zeichenkette[zeichennummer++]=zeichen; // Zeichen im String speichern
}
else
{
zeichennummer=0; // Neustart!
zeichen='!'; // Fehlermeldung senden
}
break;
}
UDR0 = zeichen; //Echo oder Fehler senden
}(Nicht getestet!)

Der Parameter sollte in dieser Form gesendet werden: "*123#"

* = Startkennung
123 = Wert
# = Endekennung

Gruß

mic

MT2009
15.06.2010, 14:06
Hallo radbruch,

danke für die Hilfe.

Leider funktioniert aber schon der einfache Lösungsansatz nicht...????

radbruch
15.06.2010, 14:20
Sorry, ich hab's nochmals editiert. Vielleicht funktioniert es nun.

Willkommen im RN-Forum:)

Gruß

mic

[Edit]
if (overflow >= Time) // !!!