Hallo zusammen
Ich hab nen Problem mit der UART-Schnittstelle bei einem Mega8. Ich will
vom Rechner ein Zeichen senden (also 8bit) und wenn der Controller
dieses empfängt, soll er eine LED an PortC anschalten.
Geht auch alles, nur bleibt die LED nicht an. Er empfängt, die LED
blitzt auf und geht wieder aus und ich weiß nicht warum.
Wenn ich die zweite While-Schleife wegnehme, bleibt die LED an, wenn
aber was empfängt, gehts kurz an und wieder aus, das macht keinen Sinn
finde ich. Wenn der Port einmal auf 1 gesetzt wurde, bleibt er doch auf
1, da er ja nirgendwo auf 0 setzt.
Hier erstmal der Code:
Bitte entschuldigt die komische Frage, aber ich komm einfach nicht
weiter an dem Punkt und hoffe ihr könnt mir helfen. Vielen Dank schonmal
Viele Grüße
André
An der 0 kann es nicht liegen, wenn ich "while (((UCSRA >> RXC) & 1)
==0)" wegnehme, dann geht die LED an und bleibt es auch.
Kann es sein, dass es einen Reset gibt, sobald wieder oben in die
while(1)-schleife gegangen wird?
Der watchdog ist doch standartmäßig aus oder? ich hab ihn jedenfalls
nicht wissendlich angeschaltet.
Was im Emfangsregister steht, ist mir erstmal egal, ich will nur
unterscheiden, ob was drin steht, oder nicht. Wenn was drin steht, soll
er die LED anschalten und sie soll an bleiben.
nochmal eine andere Idee Code, vllt wird dann eher klar, wo mein Problem
liegt:
Find erst mal raus, ob dein µC ungewollt resettet.
Häng an einen 2.ten Pin noch eine Led.
In main schaltest du die LED ein, wartest ein Weilchen und schaltest sie
wieder aus
Ok, das mit der Pin hab ich gemacht, aber das delay mag er nicht. er
schaltet die LED an, aber nicht wieder aus.
Der fehler muss bei der zweiten while schleife liegen, die muss
irgendwie den Port zurücksetzen auf den wert, der vor aufruf da war.
irgendwie macht das alles keinen sinn ... :S
André schrieb:
> Ok, das mit der Pin hab ich gemacht, aber das delay mag er nicht. er> schaltet die LED an, aber nicht wieder aus.
Ich bin mal davon ausgegangen, dass deine LED bei einer 1 am
Port-Ausgang angehen. Meistens allerdings macht man es genau anders rum.
> Der fehler muss bei der zweiten while schleife liegen, die muss> irgendwie den Port zurücksetzen auf den wert, der vor aufruf da war.
Das tut sie mit Sicherheit nicht.
> irgendwie macht das alles keinen sinn ... :S
Du sagst es.
Bist du absolut, 100% sicher, dass bei dir die LED angehen, wenn der
Portpin auf 1 gesetzt wird?
ich würde dir empfehlen erstmal die korrekte funktion deiner serriellen
verbindung zu testen:
auf zeichen auf der usart warten und per usart wieder zurücksenden ...
mit einem terminalprogramm (z.b. HTerm) kannst du dann sicherstellen ,
dass der mega8 überhaupt was empfängt etc.
dann würde ich im mainloop einfach die empfangenen zeichen auswerten
(per if oder switch) und z.b. bei 'a' ein ausgang togglen : PORTB=PORTB
^ 0xFF;
und dazu noch ein echo zurück an den pc senden.
und was mich dann noch stört: bevor PORTC dann auf 0x01 gesetzt wird ist
er quasi undefiniert (eigentlich sollte er immer 0x00 sein, aber da du
ihm das nie gesagt hast, kannst du dir nicht sicher sein)
in der C-programmierung gibt es doch auch eine warnung wenn man
nichtinitialisierte variablen benutzt, weil man den inhalt eben nicht
kennt.
Hallo, da bin ich wieder. Hab jetzt ne Weile experimentiert und mir
einiges durchgelesen und einiges klappt und das eigentlich gewollte
immernoch nicht.
Ich hab mir einen Beispielquellcode aus dem Internet geladen, was per
UART ein Byte empfängt und wieder zurücksendet. Das macht er, aber nicht
immer, manchmal kommt quatsch, ich denke, wenn ich zu schnell
hintereinander sende. Er empfängt aber auch das richtige, Einstellung
müssten also stimmen.
Was aber immernoch nicht geht, egal ob LED bei 0 oder bei 1 an sein
soll, ist das Halten des Status. Er setzt immer wieder zurück, ich weiß
nicht warum.
Hier mal der Text, bei 0 soll die LED jetzt an sein:
1
#define OSCSPEED 4000000 /* in Hz */
2
3
#include"avr/io.h"
4
5
voidInitialize(void)
6
{
7
PORTB=0x0;
8
PORTC=1<<2;/* turn the LED off */
9
PORTD=0x0;
10
11
DDRB=0x0;
12
DDRC=1<<2;/* PC2 as output - the LED is there */
13
DDRD=0x0;
14
15
}
16
17
voidInitUART(uint32_tbaud)/* here a simple int will not suffice*/
18
{
19
intbaudrate=(OSCSPEED/(16*baud))-1;/* as per pg. 133 of the user manual */
20
/* Set baud rate */
21
UBRRH=(unsignedchar)(baudrate>>8);
22
UBRRL=(unsignedchar)baudrate;
23
/* Enable Receiver and Transmitter */
24
UCSRB=(1<<RXEN)|(1<<TXEN);
25
/* Set frame format: 8data, 1stop bit */
26
UCSRC=(1<<URSEL)|(3<<UCSZ0);
27
28
}
29
30
unsignedcharUARTReceive(void)
31
{
32
if(UCSRA&(1<<RXC))
33
returnUDR;
34
else/* no data pending */
35
return0;
36
}
37
38
voidUARTTransmit(unsignedchardata)
39
{
40
while(!(UCSRA&(1<<UDRE)));
41
/* Put data into buffer, sends the data */
42
UDR=data;
43
}
44
45
intmain(void)
46
{
47
unsignedcharch;
48
Initialize();
49
InitUART(9600);
50
51
while(1)
52
{
53
ch=UARTReceive();
54
if(ch==0x41)
55
PORTC&=~(1<<2);
56
57
if(ch)
58
{
59
UARTTransmit(ch);
60
}
61
62
}
63
return0;
64
}
Wann kann es denn allgemein sein, dass der Controller resetet? Wenn ich
sonst den PORT setze, bleibt er doch auch.
Viele Dank aber schonmal für die ganzen Vorschläge und natürlich auch
vorab vielen Dank :)
Grüße
André
1. Frage die sich mir stellt:
Woher kommt der Takt? Sind die Fuses richtig gesetzt (ist zwar eine
zweite Frage, hängt aber mit demTaktproblem zusammen).
2. Findet der Kommunikationsabbruch in regelmäßigen Abständen statt?
(Watchdog immer noch an?)
3. Wieso machst du dein Programm so unnötig kompliziert?
1
#define OSCSPEED 4000000 /* in Hz */
2
#define baudrate=(OSCSPEED/(16L*baud))-1; /* as per pg. 133 of the user manual */
3
4
#include"avr/io.h"
5
6
voidInitialize(void)
7
{
8
PORTB=0x0;
9
PORTC=1<<2;/* turn the LED off */
10
PORTD=0x0;
11
12
DDRB=0x0;
13
DDRC=1<<2;/* PC2 as output - the LED is there */
14
DDRD=0x0;
15
16
}
17
18
voidInitUART(uint32_tbaud)/* here a simple int will not suffice*/
19
{
20
21
/* Set baud rate */
22
UBRRH=(unsignedchar)(baudrate>>8);
23
UBRRL=(unsignedchar)baudrate;
24
/* Enable Receiver and Transmitter */
25
UCSRB=(1<<RXEN)|(1<<TXEN);
26
/* Set frame format: 8data, 1stop bit */
27
UCSRC=(1<<URSEL)|(3<<UCSZ0);
28
29
}
30
31
32
intmain(void)
33
{
34
unsignedcharch;
35
Initialize();
36
InitUART(9600);
37
38
while(1)
39
{
40
while(!(UCSRA&(1<<RXC)));// Warten bis ein Zeichen eingetroffen ist
41
ch=UDR;
42
if(ch==0x41)// Empfangenes Zeichen ist eine '1' (*)
43
PORTC&=~(1<<2);
44
45
while(!(UCSRA&(1<<UDRE)));// auf leeren Sendepuffer warten
46
UDR=ch;// Zeichen versenden
47
}
48
49
}
50
return0;
51
}
Sollte völlig reichen.
Die mit (*) markierte Zeile kann man auch auskommentieren, was zu einem
Blinken der LED bei jeden empfangenen Zeichen führt.
zu 1:
Der Takt kommt von einem Quarz, 4MHz zwischen PB6 und PB7 und von jedem
nen 22pF Kondensator gegen Masse. Die Fuses hab ich mit "myAVR Workpad"
eingestellt. Ich hab "Ext. Crystal/Resonator High Freq.; Start-up time:
258 CK + 4 ms" gewählt, hab ich irgendwo so gelesen. Der berechnet die
Fusebits dann, kam raus: Low Fuse (0xCE) High Fuse (0x99) Lockbits
(0xFF)
Könnt ihr damit was anfangen? Mir wäre es auch lieber, wenn ich
verstehen würde, was ich da machen lasse. Ich wollte aber nichts kaputt
machen ...
zu 2. Watchdog war nie an bzw nie wissentlich angemacht. Hab schon
versucht, nen System zu erkennen, aber ich finde keins, wann es nicht
richtig geht.
Zu 3. Du meintest, wenn ich "if (ch == 0x41)" weglasse, blinkt er beim
Empfangenen aus ... das ist ja genau mein Problem. Das will ich nicht,
die Lampe soll an bleiben. Weil ich setze doch den Port und sage
nirgendwo, dass wenn er nichts empfängt, er den Port zurückschalten
soll.
Ich will den Controller letztendlich als Steuereinheut einsetzen, ich
sende ihm z.b. ein "E" und er schaltet eine Lampe ein und wenn ich ihm
irgendwann ein "A" sende, geht die Lampe wieder aus. Aber das geht ja
nur, wenn der PORT nach dem Empfangen auch so bleibt wie ich ihn setze.
Versteht ihr was ich meine und vorhabe? :)
Danke für die Geduld
André schrieb:
> nur, wenn der PORT nach dem Empfangen auch so bleibt wie ich ihn setze.> Versteht ihr was ich meine und vorhabe? :)
Ja.
Wenn es auf deinem System mit deinem Programm so ist, dass die LED beim
empfang eines Zeichens an geht und kurz darauf wieder aus, dann hast du
ein Hardwareproblem. Das hat nichts mit deinem µC (ausser wenn der
defekt wäre, was aber unwahrscheinlich ist) oder dem Programm zu tun.
Hier sind wir raus. Dein Hardwareproblem können wir so nicht lösen, da
musst du ran. Mal die üblichen Verdächtigen abklopfen.
Versorgungsspannung, Blockkondensatoren etc.
Hallo
ich möchte über USART zeichen empfangen und auswerten. USART
fukntioniert auch soweit aber ich hab ein Problem mit der Funktion
"test". Komischerweise wird die LED nur dann eingeschaltet wenn ich in
der if-abfrage eine andere Funktion aufrufe oder eine Verzögerungszeit
drin habe, die größer als 90 ms ist. Beim Ausschalten gibts keine
Probleme. Hat jemand eine Idee woran das liegen könnte?
Danke im Voraus.
Hast du die LED direkt an den µC angeschlossen? Mir ist es schonmal
passiert, dass an der LED zu viel Strom fließt und der µC deswegen
"abstürzt". Liegt es vllt. daran?
An wie vielen Stellen im Code wird das Ausgangsregister neu gesetzt?
Kann es sein, dass das Bit für die LED aus Versehen gelöscht wird?
grüssse
g.