Ich habe für die Hochschule einen Datenlogger auf Basis eines ATMega88
programmiert. Dieser soll, wenn er ein "R|" über den UART empfängt, die
im externen EEPROM abgelegten Daten per UART rausschicken. Im Grunde
funktioniert das ganze. Problem ist allerding:
Beim Erstmaligem Auslesen muss ich die oben genannte Zeichenkette zwei
mal schicken damit ich die Messdaten bekomme. Das erste "R|" wird
einfach igoniriert. Die Daten kommen eben erst beim zweiten "R|".
Möchte ich das EEPROM ein zweites mal auslesen, so genügt ein einziges
"R|", was ja auch richtig ist.
Jemand eine Ahnung woran sowas liegen könnte?
Kannst du debuggen? wie hast du den uart/usart implementiert? (isr,
polling)
zeig mal den code und am besten auch den schaltplan, ohne diese
grundlegenden dinge können wir auch nur raten!
Rush ... schrieb:> Jemand eine Ahnung woran sowas liegen könnte?
Ich würde, ohne den Programmcode nun konkret gesehen zu haben, sagen,
dass du den UART nicht ausreichen initialisiert hast. Simulier das Ganze
doch mal im Simulator des AVR-Studios und schau da wo es beim ersten Mal
hängt?
Richtig initialisiert sollte er eigentlich sein, denn die Zeichen werden
korrekt übertragen.
Hab mir einfach mal das zurückschicken lassen was ich hinteschickt habe.
Habe den Code mal dran gehängt.
Ich sag es ja ungern, aber Deine ISR (INT0_vect)
ist sch...
Mit den Aktionen wie "delay(20ms)" und weiteren EEPROM Schreibaktionen,
wird dem µC der Interrupt lange Zeit voll gesperrt. Da können keine
anderen Interrupts durchkommen.
Sieh einen Interrupt wie die Haustürklingel: wenn du da einen Topf mit
Milch auf dem Herd hast, dann fertigst du den Postboten an der Haustür
am besten möglichst schnell ab...
Schmeiß als ersten mal die _delay_ms in den ISR's raus. Eine ISR sollte
so langsam wir möglich sein, da du sonst den rest deines programms
komplett blockierst.
und wenn du ein problem mit dem usart hast, solltest du uns schon noch
die usart.h und die usart.c geben!
Ok, nur kurz zum verständnis.
an dem INT0 hängt mein RTC dran der in dem angegebenen Intervall einen
Interrupt auslöst und somit die Messung startet. Das delay kommt noch
weg.
Der INT1 wird ausgelöst, nachdem ich meinen Stecker für den UART
angeschlossen habe. Und in dieser ISR wird INT0 deaktiviert. Von daher
dürfte das delay in der ISR INT0 nicht von Bedeutung sein.
Hier nochmal die Initialisierung des UARTS:
Es mag eine dumme Frage sein aber warum wartest du nach Eintreten des
ISR 20ms (500!!! ms)? Welchen Sinn hat das denn? Und bei deinem UART
fragst du auch nicht ob ein 'R|' kam sondern lediglich nach '|'.
Initialisiert wird er richtig sein, nutzt ja die AVR-Bibliothek dafür.
Wie gesagt, schau mal wo der Simulator dir sagt, dass es hängt und
klemmt.
Achja, was mir noch auffällt: Ich kann auf Anhieb in den ISRs nicht
sehen, dass du die Interrupts deaktivierst....ist das gewollt? In 20ms
(500ms) kann ne Menge passieren.
ähm...
du hast den usart-interrupt per RXCIE eingeschaltet, aber keine
entsprechende IST drin. mich wundert, dass das überhaupt geht. einen
aktivierten interrupt ohne entsprechende ISR bringt den AVR dazu, zu
resetten.
Die lezte konfiguration war so gewesen, dass der Controller im Powerdown
war, über den INT0 aufgeweckt wurde, dann wurde die Messung gemacht.
Laut Tutorial und Datenblatt kann man den Controll in diesem Modus nicht
flankengesteuert sondern nur levelgesteuert aus dem Powerdown holen.
Durch den Interrupt vom RTC wurde die Routine aber mehrmals durchlaufen.
Deswegen hatte ich als Provisorium das Delay mit reingeschrieben.
Und das 500ms delay in der INT1 habe ich schon rausgeschmissen, ändert
aber nichts an der Problematik.
@Michael
Das | dient nur als Abschlusszeichen und gehört nicht zum eigentlichen
Befehl.
Hier wird nur überprüft ob die Zeichen komplett sind und dann
rx_valid_command auf 1 gesetzt. Diese 1 wird unten in der main
abgefragt.
wenn der interrupt auslöst, steht das zeichen schon bereit und du kannst
es direkt abgreifen. ich würde es so machen:
1
ISR(USART_RX_vect)
2
{
3
rx[rx_i]=UDR;
4
5
if(rx[rx_i]=='|')
6
{
7
rx_valid_command=1;
8
}
9
10
rx_i++;
11
}
ansonsten schmeiß mal den rest des codes, der nix mit den usart zu tun
hat raus und kümmre dich nur um den usart, um sicherzustellen, das der
erstmal läuft und nix anderes dazwischen funkt
toogle in der isr mal nen freien portpin, um zu schaun, ob er beim
erstmaligen senden des befehls überhaupt die isr anspringt
[EDIT]Sorry, für den Doppelpost!
Er schein beim ersten zeichen garnicht den interrupt aus zu lösen. Denn
habe alles in der ISR mal auskommentiert und nur das Zeichen
zurückschicken lassen was angekommen ist. Da kommt es beim ersten mal
auch nicht zurück.
ist ja gut zu wissen, nur wie zu lösen?
mir fällt einfach nichts mehr ein warum es beim ersten mal nicht geht
und sonst aber immer.
> Der INT1 wird ausgelöst, nachdem ich meinen Stecker für den UART> angeschlossen habe.
Wie genau ist das zu verstehen?
Steckst du die UART ein/aus?
Ist das in deinem jetzigen Testcode noch relevant?
Mach deine Tests so einfach wie möglich. Ohne irgendwelche Sonderfälle
oder Spezialzuckerl.
Zeichn kommt rein - Zeichen wird zurückgeschickt. Alles andere fliegt
aus dem Testcode raus. Und zwar wirklich: fliegt raus. Nicht "dürfte gar
nicht mehr aufgerufen werden" oder "hat eh keinen Effekt", sondern
"fliegt raus".
Alternativ: neues Programm anfangen und von 0 an beginnend aufbauen. Das
ist schneller gemacht, als das vorhandene abzuspecken.
ja du verstehst schon richtig. Im fertigen Zustand soll das Einstecke
des UARTs das Aufwachen des Controllers und das Stoppen der Messung
bewirken. Außerdem wird noch Konfigurationsmöglichket per UART
relaisiert werden.
Ehm mir ist was ganz anderes aufgefallen. Undzwar das die LED am Wandler
ab und an mal blinkt obwohl ich nichts über den Port schicke.
Habe mal einen Logic Analyzer an den Controller gehangen und gesehen
dass in regelmäßigen Zeitabständen immer das selbe ankommt. Nur was
könnte das sein? Normalerweise kommt doch nichts über den Port wenn ich
nicht wirklich was sende...
Rush ... schrieb:> ja du verstehst schon richtig. Im fertigen Zustand soll das Einstecke> des UARTs das Aufwachen des Controllers und das Stoppen der Messung> bewirken. Außerdem wird noch Konfigurationsmöglichket per UART> relaisiert werden.
Ich frage deshalb, weil es beim Einstecken eines Steckers schon mal zu
Knacksern auf den Leitungen kommt. Die UART interpretiert die aber als
den Beginn einer Übertragung und macht ein Zeichen daraus, welches dem
Empfängercode dann zugeführt wird. Mit diesem falschen, zufälligem
Zeichen muss der klar kommen.
Daher hat man oft auch ein einleitendes Zeichen in einer Übertragung.
Der Empfänger ignoriert alles, bis er dieses Zeichen sieht.