Hallo
ich habe folgendes Problem:
Mein Atmega32 bekommt über UART zu unbestimmten Zeiten je 5 Bytes
geschickt (Hintereinander). Ich nehme dafür den RXC-Interupt nehmen, in
dem die 5 Bytes in ein Array geschrieben werden. Sobald das 5. empfangen
empfangen wird, wird der Interupt ausgeschalten und ein Flag gesetzt.
Wenn ich nun aber mit dem PC einen großen Datenfluss sende, dürften
eigentlich nur die ersten 5 Byte empfangen und dann über das
Hauptprogramm auf dem LCD angezeigt werden.
Doch während des Sendens resetet sich der Atmega dauernd (sehe ich an
einem Counter auf dem Display) bis dieser schließlich ganz den Geist auf
gibt und nicht mehr reagiert.
Wo könnte der Fehler liegen???
Viele Grüße
Richi
Sorry, das ich das vergessen habe.
Kleine Anmerkung:
Wenn die 5 Bytes nicht annähernd hintereinander kommen, werden sie nicht
akzeptiert. (Siehe Code).
Die LCD-Funktionen habe ich nicht mit aufgeführt, sollten aber klar
sein.
Hoffe das Hilft (auch wenns ein bisschen viel ist)
Viele Grüße
Richi
Atmega32 mit 16MHz
Ein "andauerndes resetten" kommt in 99% aller Fälle durch einen
Interrupt, für den keine ISR vorhanden ist.
Da deine Interrupt-Freigaben aber etwas kryptisch sind, musst du dein
Programm schon selber auf dieses Problem hin untersuchen.
Oliver
Schmeiss mal den ganzen Sleep-Krempel raus.
Ein Programm, welches die halbe Zeit nur einen Sleep macht, will man
sowieso nicht haben und erhöht erst mal die Übersicht durch weniger
Code.
Für den Reset ist so erst mal keine Ursache direkt erkennbar. Bist du
sicher, dass ein Reset erfolgt?
Am Anfang Led ein, _delay_ms(500) und Led aus. Wenn die Led die ganze
Zeit ruhig bleibt, dann sind es keine Resets, sondern irgendwas bügelt
über deinen Counter drüber.
Nimm hier
volatile unsigned char UART[5], UART_counter, UART_Clock, UART_neu;
die Variable UART_counter aus dem Header File raus. Dieser Counter geht
ausser der ISR niemanden etwas an.
Stattdessen wandert die ins C-File
1
#include"USART.h"
2
3
staticunsignedcharUART_counter;
4
5
voidUsart_Init(void)
6
{
7
DDRD&=~(1<<0);
8
PORTD|=(1<<0);
9
10
UCSRA=0x00;
11
UCSRB=0x00;
12
UCSRC=0x86;
13
UBRRL=103;
14
UBRRH=0;
15
16
UART_neu=0;
17
UART_counter=0;// sicherheitshalber
18
}
19
20
ISR(USART_RXC_vect)
21
{
22
if(UART_Clock==10)
23
{
24
UART_counter=0;
25
}
26
27
UART_Clock=0;
28
29
UART[UART_counter]=UDR;
30
31
UART_counter++;
32
33
if(UART_counter>=5)
34
{
35
UART_Disable();
36
37
UART_counter=0;
38
UART_neu=1;
39
}
40
}
Sicherheitshalber in der Init auf 0 setzen (auch wenn sie das als
globale Variable sowieso sein sollte. Die Abfrage auf Buffer voll
defensiv mit einem >= anstelle des == programmieren.
Darüber
1
#define UART_Disable() UCSRB = 0x00;
2
#define UART_Enable() UCSRB = 0x90;
sag ich jetzt nichts. 0x90 ist so herrlich aussagekräftig, so dass man
mit einem Blick sofort sieht, was du da einschaltest :-)
Einen Grund für Resets hab ich allerdings immer noch nicht gefunden. Was
ist, wenn du dir die Bestätigung anstelle mit dem LCD mit ein paar LED
geben lässt? Ev. ein Fehler in den LCD Funktionen?
Also: 0x90 --> (1<<RXCIE) | (1<<RXEN)
Einen Fehler in den LCD_Funktionen schließe ich aus, da sich ja der
Counterwert, welcher angezeigt wird, ständig ändert.
Während dem Datenfluss stellt sich dieser dann plötzlich wieder auf 0.
--> Reset
Normalerweise müsste doch der Empfänger völlig abgeschalten sein und der
Interrupt darf nicht mehr ausgeführt werden.
Mir ist auch aufgefallen, dass in diesem Fall die Sleep-Routinen nicht
mehr ordentlich eingehalten werden.
Hallo,
ohne drüber zu schauen: Du löschst aber nach dem Ausschalten des RX-IRQ
ein evtl. schon wieder gesetztes RXC-Flag?
Sind so meine fallen, nach dem Abschalten des Krams macht man noch was,
dann wird die ISR beendet, die globalen IRQ wieder freigegen und es
lauert ein RXC-Flag, weil inzwischen ein Byte eingetroffen ist, das man
eigentlich garnicht mehr haben will...
Gruß aus Berlin
Michael
Hallo
Alles vorgeschlagene Nützt nichts, ich habe nun eine Extra-LED für den
Reset eingebaut und das LCD weggelassen.
Kann es sein, dass es evtl. Probleme mit dem Data-Overrun gibt und dass
die ISR beim Starten einmal durchlaufen wird?
Gruß
Richi
Ich denke mitlerweile weiß ich wo der Fehler liegt:
Wieder einmal auf meinem Steckbrett!!!
Wenn ich die LEDs/UART über das STK500 laufen lasse, gehts einwandfrei,
auf dem Steckbrett nicht.
Ich weiß nur noch nicht, wo genau.
Gruß
Richi
Eine eigene Frage?
Dieser Thread ist über 16 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.