Hallo liebe Gemeinde, tut mir schon leid dass ich damit komme, aber ich sehe wohl den Wald vor lauter Bäumen nicht? Hatte jetzt ein paar Jahre Programmierpause und jetzt bekomme ich UART am ATMega644A nicht zum laufen. (Init und senden) ich habe die Suche schon durch und auch das Datenblatt. Es wird was gesendet (gemessen mit einem DSO mit Decoder) aber viel zu wenig und auch falsch. Den Takt habe ich auf den Pin ausgeben lassen und gemessen, es sind die eingestellt und eingetragenen 8 Mhz. Die Einstellung soll 9600 Baud (8,n,1) sein, zur Berechnung beutze ich setbaud.h Hier meine init: #define F_CPU 8000000UL #define BAUD 9600UL #include <util/setbaud.h> void serial_init() } UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1 } und hiermit sende ich in einem timer Interrupt ca. 3Hz ISR(TIMER0_OVF_vect) // { //cli(); //weitere Interrupts deaktivieren PORTB ^= (1<<PB0); // Toggelt den Ausgänge an PORTB0 while(!(UCSR0A & (1<<UDRE0))); UDR0=48; //sei(); //alle Interrupts wieder aktivieren } Vielen Dank im voraus !
Das vollständige Programm vorzustellen wäre sinnvoll gewesen. Was passiert, wenn Sie statt dieses "setbaud" den Wert aus dem Datenblatt, nämlich 51, nehmen?
Danke für die Antwort! Ich habe auch schon den Zahlenwert direkt eingetragen aber es ändert nichts. Um das Problem zu isolieren habe ich jetzt ein Programm wo ich nur immer wieder was über die Schnittstelle raus schicke. Ich bin so langsam am verzweifeln. Am DSO wird der Pin geschaltet, aber immer nur ein-zwei lange Flanken und nie die kompletten Daten mit 8,n,1
1 | #define F_CPU 8000000UL
|
2 | #define BAUD 9600UL
|
3 | |
4 | #include <avr/io.h> |
5 | #include <util/setbaud.h> |
6 | #include <util/delay.h> |
7 | |
8 | |
9 | void uart_init(void) |
10 | {
|
11 | UBRR0L = UBRRL_VALUE; |
12 | UBRR0H = UBRRH_VALUE; |
13 | UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); |
14 | UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1 |
15 | }
|
16 | |
17 | |
18 | int main(void) |
19 | {
|
20 | uart_init(); |
21 | /* Replace with your application code */
|
22 | while (1) |
23 | {
|
24 | while(!(UCSR0A & (1<<UDRE0))) |
25 | {
|
26 | |
27 | }
|
28 | UDR0 = "42"; |
29 | |
30 | _delay_ms(100); |
31 | }
|
32 | }
|
René K. schrieb: > UDR0 = "42"; Das ist Quark. In UDR0 muss ein einzelnes Zeichen und kein String übergeben werden. Schreibe also:
1 | void putc (uint8_t ch) |
2 | {
|
3 | while(!(UCSR0A & (1<<UDRE0))) |
4 | {
|
5 | ;
|
6 | }
|
7 | UDR0 = ch; |
8 | }
|
9 | |
10 | int main(void) |
11 | {
|
12 | uart_init(); |
13 | |
14 | while (1) |
15 | {
|
16 | putc ('4'); |
17 | putc ('2'); |
18 | _delay_ms(100); |
19 | }
|
20 | }
|
Das Schreiben einer Funktion puts(), die einen String wie "42" ausgeben kann, überlasse ich jetzt einmal Dir.
:
Bearbeitet durch Moderator
Versuch mal...
1 | void UartInit (void) |
2 | {
|
3 | UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); // UART TX einschalten |
4 | UCSR0C |= (3 << UCSZ00); // Asynchron 8N1 |
5 | UBRR0H = UBRR_VAL >> 8; // Baudrate setzen |
6 | UBRR0L = UBRR_VAL & 0xFF; |
7 | }
|
an René K. Also bei mir läuft das (mit UDR0='L';). Vielleicht eine Fehlinterpretation der DSO-Ausgabe.
Ich habe auch das Gefühl das am DSO liegt, aber ich habe alles schon zig mal durchgeschaut.... Aber selbst wenn das DSO nicht richtig decodiert, dann müsste ich doch dennoch die 8n1 sehen wenn ich ein Zeichen sende. oder ? Hier nochmal der aktuelle Code:
1 | #define F_CPU 8000000UL
|
2 | #define BAUD 9600UL
|
3 | |
4 | #include <avr/io.h> |
5 | #include <util/setbaud.h> |
6 | #include <util/delay.h> |
7 | #include <stdio.h> |
8 | |
9 | |
10 | |
11 | |
12 | void uart_init(void) |
13 | {
|
14 | //UBRR0L = UBRRL_VALUE;
|
15 | //UBRR0H = UBRRH_VALUE;
|
16 | //UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
|
17 | //UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); //8,n,1
|
18 | |
19 | UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); // UART TX einschalten |
20 | UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00); // Asynchron 8N1 |
21 | UBRR0H = (UBRR_VALUE>>8); // Baudrate setzen |
22 | UBRR0L = (UBRRL_VALUE & 0xff); |
23 | }
|
24 | |
25 | |
26 | |
27 | int main(void) |
28 | {
|
29 | uart_init(); |
30 | |
31 | while (1) |
32 | {
|
33 | while(!(UCSR0A & (1<<UDRE0))) |
34 | {
|
35 | |
36 | }
|
37 | UDR0 = 'L'; |
38 | |
39 | _delay_ms(10); |
40 | }
|
41 | }
|
Tja, auch Ihr aktuelles Programm läuft bei mir einwandfrei. Der Watchdog ist ja sicher ausgeschaltet, sonst hätten Sie nicht die 8 MHz verifizieren können, wie eingangs geschildert.
Es funktioniert mit dem einzelnen Zeichen... so was blödes: LSB first und am DSO war MSB first. Aber irgendwie hatte ich das mit den Bits anders in Erinnerung... Jetzt hoffe ich das ich den anderen Kram noch hinbekomme. Ich muss einen String basteln (nur Zahlen) und der soll zyklisch übertragen werden. Dieser setzt sich dann aus mehreren Variablen zusammen. Danke für eure Hilfe bis hierhin!!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.