Sehr geehrtes Forum, ich habe vor einen Atmega48PA per RS232 mit dem PC kommunizieren zu lassen. Ich verwende HTerm und AVR Studio. Dazu habe ich Pin 2 (RXD) und Pin 3 (TXD) des Atmegas mit meinem MAX232 Modul verbunden. (Mein Max232 Modul ist ein Fertigbauteil, ich habe schon zwei verschiedene Module verwenden, und die funktionieren eigentlich) Auf meinem MAX232 Modul gibt es sogar leds, die anzeigen ob die Stromversorgung korrekt angeschlossen ist, und LEDs für RXD und TXD. Nun habe ich nochmal nach diesem Tutorial und Code : http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART#Senden_von_Zeichen Das Programm auf meinen Atmega geflashed. Wenn ich nun mein Terminalprogramm öffne, die im Tutorial beschriebenen Einstellungen vornehme, und dann die Stromverbindung für den Atmega anstelle, kommen einfach keine Signale am PC an. Der Atmega, so zumindest die LEDs von MAX232 Modul, sendet einfach keine Signale. Sorry, vielleicht überseh ich einfach eine Kleinigkeit, aber ich weiß nicht woran es liegen sollte. Danke für eure Hilfe, m.f.G.: K.R.
Hast Du RXD vom AVR mit RXD oder mit TXD von MAX232 verbunden? Je nachdem wie der Entwickler gedacht hat, mußt Du die kreuzen.
:
Bearbeitet durch User
Nein ich habe sie nicht gekreuzt, müssten die LEDs aber nicht trotzdem blinken, oder müsste der PC dann nicht wenigstens Mist empfangen? *Edit: Es funktioniert gekreuzt auch nicht. Ich denke es liegt eher am Code. Es ist ein Atmega48 PA. Der Atmega funktioniert auch einwandfrei. Daran liegt es nicht. Ich vermute ein Softwareproblem. Kann es daran liegen dass der Code für Atmega8 geschrieben ist? (Sind doch eigentlich fast gleich ausgestattet auch von den Bezeichnungen)
:
Bearbeitet durch User
Wenn 2 Ausgänge aufeinander liegen gewinnt einmal der Stärke und bei 2 Eingängen passiert garnichts (außer daß vielleicht beide Unsinn einfangen). Um zu testen, ob der Adapter funktioniert kannst Du den AVR mal weglassen und RXD und TXD verbinden. Dann muß alles was Du tipst wieder angezeigt werden und die LED syncron flackern.
Dann zeig doch deinen Code und verweise nicht auf ein Tutorial, in dem drinsteht, wie es richtig sein soll. mfg.
Also: Erstmal danke für eure Hilfe. Wenn ich RXD und TXD verbinde, kommt dasselbe auch wieder am PC an, was abgesendet wurde. Hardwaretechnisch steht soweit alles. Mein Code:
1 | .include "m8def.inc" |
2 | |
3 | .def temp = r16 ; Register für kleinere Arbeiten |
4 | .def zeichen = r17 ; in diesem Register wird das Zeichen an die |
5 | ; Ausgabefunktion übergeben |
6 | |
7 | .equ F_CPU = 4000000 ; Systemtakt in Hz |
8 | .equ BAUD = 9600 ; Baudrate |
9 | |
10 | ; Berechnungen |
11 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden |
12 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate |
13 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille |
14 | |
15 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler |
16 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" |
17 | .endif |
18 | |
19 | ; Stackpointer initialisieren |
20 | |
21 | ldi temp, HIGH(RAMEND) |
22 | out SPH, temp |
23 | ldi temp, LOW(RAMEND) |
24 | out SPL, temp |
25 | |
26 | ; Baudrate einstellen |
27 | |
28 | ldi temp, HIGH(UBRR_VAL) |
29 | out UBRRH, temp |
30 | ldi temp, LOW(UBRR_VAL) |
31 | out UBRRL, temp |
32 | |
33 | ; Frame-Format: 8 Bit |
34 | |
35 | ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0) |
36 | out UCSRC, temp |
37 | |
38 | sbi UCSRB,TXEN ; TX aktivieren |
39 | |
40 | loop: |
41 | ldi zeichen, 'T' |
42 | rcall serout ; Unterprogramm aufrufen |
43 | ldi zeichen, 'e' |
44 | rcall serout ; Unterprogramm aufrufen |
45 | ldi zeichen, 's' |
46 | rcall serout ; ... |
47 | ldi zeichen, 't' |
48 | rcall serout |
49 | ldi zeichen, '!' |
50 | rcall serout |
51 | ldi zeichen, 10 |
52 | rcall serout |
53 | ldi zeichen, 13 |
54 | rcall serout |
55 | rcall sync |
56 | rjmp loop |
57 | |
58 | serout: |
59 | sbis UCSRA,UDRE ; Warten bis UDR für das nächste |
60 | ; Byte bereit ist |
61 | rjmp serout |
62 | out UDR, zeichen |
63 | ret ; zurück zum Hauptprogramm |
64 | |
65 | ; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich |
66 | ; das Kabel getrennt wurde |
67 | |
68 | sync: |
69 | ldi r16,0 |
70 | sync_1: |
71 | ldi r17,0 |
72 | sync_loop: |
73 | dec r17 |
74 | brne sync_loop |
75 | dec r16 |
76 | brne sync_1 |
77 | ret |
Du solltest zumindest die .include "m8def.inc" in .include "m48def.inc" oder .include "m48pdef.inc" ändern.
Einfach nur kopieren kann ins Auge gehen, wie schon mancher Minister erfahren musste. Im Datenblatt des ATmega48 das Kapitel Register Summary anschauen und danach den Unterschied zwischen out und sts ergründen.
Sorry, bin bisschen aus der Übung. Ich werde mich da im Datenblatt nochmal einlesen und melde mich gleich zurück.
> ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
URSEL hat da auch nichts verloren.
In C wäre das jetzt einfacher. Den Assemblercode musst du schon ein
bisschen mehr umkrempeln. Vor allen Dingen sind die Adressen nicht mehr
im I/O Space und daher nicht mehr mit out erreichbar.
mfg.
Wobei nach dem Tipp von Oliver R. vermutlich der Assembler mit seinen Fehlermeldungen bereits in die richtige Richtung weisen wird.
Mein Problem ist folgendes, und erinnert mich an die PWM Geschichte von mir: Ich habe ein Tutorial, in welchem mir erklärt wird was ich machen soll. Sogar im Datenblatt ist eine Art Tutorial, interessant wird es dann aber, wenn selbst der Code aus dem Datenblatt von meinem AVR Studio nicht akzeptiert wird, und ich nirgendwo eine Tabelle mit Bezeichnugnen der ganzen Bytes finde. Nun steh ich da und weiß nicht mehr weiter. Z.B.: http://www.atmel.com/images/doc2545.pdf S.178, den Assembler Code zur Initialisierung bei meinem AVR Studio wird gesagt, dass UBRRnH nicht existiert (Undefined Symbol). Hat jemand vielleicht ne gute Erklärung was ich machen könnte?
Hi
>Hat jemand vielleicht ne gute Erklärung was ich machen könnte?
Atmel hat da schöne Migration Notes. Auch eine vom Übergang vom ATMega8
zu ATMega48/88/168.
MfG Spess
Das 'n' steht für eine Ziffer, in diesem Fall wohl '0', denn wenn ich es richtig sehe, hat der ATmega48 nur einen USART, eben USART0.
K. R. schrieb: > http://www.atmel.com/images/doc2545.pdf > S.178, den Assembler Code zur Initialisierung > bei meinem AVR Studio wird gesagt, dass UBRRnH > nicht existiert (Undefined Symbol). > > Hat jemand vielleicht ne gute Erklärung was ich machen könnte? Dir ist aber klar, daß "n" in diesem Fall für "0" steht und entsprechend ersetzt werden muß? mfg.
Und womit denn? Ich habe '_', '0', 'A', 'B' versucht, nichts funktioniert. Sorry aber diese Erklärungen finde ich nicht gerade sinnvoll, man kann nicht einfach hingehen, einen Code hinklatschen, ohne ein einziges Mal zu erklären was n ist, bzw. womit es zu ersetzen ist. Im gesamten Kapitel kommt es als Index in allen Bezeichnungen vor, aber nirgendwo wird gesagt, was es ist. Sorry, aber was soll ich denn da einsetzen?
Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0' ersetzen?
Hi
>Sorry, aber was soll ich denn da einsetzen?
Das was im Datenblatt steht.
MfG Spess
K. R. schrieb: > Und womit denn? > > Ich habe '_', '0', 'A', 'B' versucht, nichts funktioniert. > Sorry aber diese Erklärungen finde ich nicht gerade sinnvoll, > man kann nicht einfach hingehen, einen Code hinklatschen, ohne > ein einziges Mal zu erklären was n ist, bzw. womit es zu ersetzen ist. > > Im gesamten Kapitel kommt es als Index in allen Bezeichnungen vor, > aber nirgendwo wird gesagt, was es ist. > > Sorry, aber was soll ich denn da einsetzen? "0". Aus RXC im UCSRA-Register wird RXC0 im UCSR0A-Register. mfg.
der alte Hanns schrieb: > Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0' > ersetzen? C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: Undefined symbol: UBRR0H
Dann sind Sie vermutlich nicht dem Hinweis von Oliver R. gefolgt, dieses aber ist unabdingbar.
K. R. schrieb: > der alte Hanns schrieb: >> Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0' >> ersetzen? > > C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: > Undefined symbol: UBRR0H Falsche xxdef.inc ? mfg.
Oliver R. schrieb: > Du solltest zumindest die > .include "m8def.inc" > in > .include "m48def.inc" oder .include "m48pdef.inc" > ändern. ^^^^^^^^ Das geändert? weil beim ATmega8 gibt es kein UBRR0H MfG Hans
Natürlich habe ich das schon geändert. Also das ist im Moment mein Verstümmelter Code, und ich weiß gar nicht so recht was jetzt konkret eingesetzt werden soll, weil, wenn ich das durch 0 ersetze kommen da Fehlermeldungen wie vorhin beschrieben.
1 | .include "m48def.inc" |
2 | |
3 | .def temp = r16 ; Register für kleinere Arbeiten |
4 | .def zeichen = r17 ; in diesem Register wird das Zeichen an die |
5 | ; Ausgabefunktion übergeben |
6 | |
7 | .equ F_CPU = 1000000 ; Systemtakt in Hz |
8 | .equ BAUD = 9600 ; Baudrate |
9 | |
10 | ; Berechnungen |
11 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden |
12 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate |
13 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille |
14 | |
15 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler |
16 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" |
17 | .endif |
18 | |
19 | ; Stackpointer initialisieren |
20 | |
21 | ldi temp, HIGH(RAMEND) |
22 | out SPH, temp |
23 | ldi temp, LOW(RAMEND) |
24 | out SPL, temp |
25 | |
26 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
27 | |
28 | ; Set baud rate |
29 | out UBRR0H, HIGH(UBRR_VAL) |
30 | out UBRR0L, LOW (UBRR_VAL) |
31 | ; Enable receiver and transmitter |
32 | ldi r16, (1<<RXEN0)|(1<<TXEN0) |
33 | out UCSR0B,r16 |
34 | ; Set frame format: 8data, 2stop bit |
35 | ldi r16, (1<<USBS0)|(3<<UCSZn0) |
36 | out UCSR0C,r16 |
37 | |
38 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
39 | |
40 | loop: |
41 | ldi zeichen, 'T' |
42 | rcall serout ; Unterprogramm aufrufen |
43 | ldi zeichen, 'e' |
44 | rcall serout ; Unterprogramm aufrufen |
45 | ldi zeichen, 's' |
46 | rcall serout ; ... |
47 | ldi zeichen, 't' |
48 | rcall serout |
49 | ldi zeichen, '!' |
50 | rcall serout |
51 | ldi zeichen, 10 |
52 | rcall serout |
53 | ldi zeichen, 13 |
54 | rcall serout |
55 | rcall sync |
56 | rjmp loop |
57 | |
58 | serout: |
59 | sbis UCSRA0,UDRE0 ; Warten bis UDR für das nächste |
60 | ; Byte bereit ist |
61 | rjmp serout |
62 | out UDR0, zeichen |
63 | ret ; zurück zum Hauptprogramm |
64 | |
65 | ; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich |
66 | ; das Kabel getrennt wurde |
67 | |
68 | sync: |
69 | ldi r16,0 |
70 | sync_1: |
71 | ldi r17,0 |
72 | sync_loop: |
73 | dec r17 |
74 | brne sync_loop |
75 | dec r16 |
76 | brne sync_1 |
77 | ret |
Fehlermeldungen
1 | AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36) |
2 | Copyright (C) 1995-2009 ATMEL Corporation |
3 | |
4 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(2): Including file 'C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc' |
5 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(17): error: Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch! |
6 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: Invalid register |
7 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(31): error: Invalid register |
8 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(34): error: Operand 1 out of range: 0xc1 |
9 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(36): error: Undefined symbol: UCSZn0 |
10 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(37): error: Operand 1 out of range: 0xc2 |
11 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(60): error: Undefined symbol: UCSRA0 |
12 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(63): error: Operand 1 out of range: 0xc6 |
13 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(79): No EEPROM data, deleting C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.eep |
14 | |
15 | Assembly failed, 8 errors, 0 warnings |
'... out of range' heißt in unserem Zusammenhang 'out' durch 'sts' ersetzen. 'Undefined symbol' weist meist auf einen Tippfehler hin. > ldi r16, (1<<USBS0)|(3<<UCSZn0) Was bedeutet dieses? UCSR0A liegt beim 48er im extended IO, also muss > serout: > sbis UCSRA0,UDRE0 ; Warten bis UDR für das nächste > ; Byte bereit ist > rjmp serout komplett umgeschrieben werden.
K. R. schrieb: > Undefined symbol: UCSRA0 Das Register heisst UCSR0A. Der Atmega48 hat ein paar grössere Verwandte, die mehrere USARTs haben. Um das konform zu gestalten, hat man bei dem die "0" da eingefügt. Nur derjenige, der die Namen für die Interruptvektoren festgelegt hat, ist bei dem Meeting, in dem das besprochen wurde, offenbar abwesend gewesen. Die Interruptvektoren heissen daher z.B. USART_RX. Das nur mal am Rande. mfg.
> bei dem Meeting, in dem das besprochen wurde, offenbar abwesend gewesen.
Es menschelt eben überall.
Also, einige Probleme habe ich lösen können, andere wiederum nicht. Ich habe neben den ganzen Problemen eine Frage: Welche Taktfrequenz hat denn ein 48PA Standardmäßig? Ich habe nie was umgestellt oder nen externen Quarz.
1 | .include "m48def.inc" |
2 | |
3 | .def temp = r16 ; Register für kleinere Arbeiten |
4 | .def zeichen = r17 ; in diesem Register wird das Zeichen an die |
5 | ; Ausgabefunktion übergeben |
6 | |
7 | .equ F_CPU = 4000000 ; Systemtakt in Hz |
8 | .equ BAUD = 9600 ; Baudrate |
9 | |
10 | ; Berechnungen |
11 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden |
12 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate |
13 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille |
14 | |
15 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler |
16 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" |
17 | .endif |
18 | |
19 | ; Stackpointer initialisieren |
20 | |
21 | ldi temp, HIGH(RAMEND) |
22 | out SPH, temp |
23 | ldi temp, LOW(RAMEND) |
24 | out SPL, temp |
25 | |
26 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
27 | |
28 | ; Set baud rate |
29 | out UBRR0H, HIGH(UBRR_VAL) |
30 | out UBRR0L, LOW (UBRR_VAL) |
31 | ; Enable receiver and transmitter |
32 | ldi r16, (1<<RXEN0)|(1<<TXEN0) |
33 | sts UCSR0B,r16 |
34 | ; Set frame format: 8data, 2stop bit |
35 | ldi r16, (1<<USBS0)|(3<<UCSZn0) |
36 | sts UCSR0C,r16 |
37 | |
38 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
39 | |
40 | loop: |
41 | ldi zeichen, 'T' |
42 | rcall serout ; Unterprogramm aufrufen |
43 | ldi zeichen, 'e' |
44 | rcall serout ; Unterprogramm aufrufen |
45 | ldi zeichen, 's' |
46 | rcall serout ; ... |
47 | ldi zeichen, 't' |
48 | rcall serout |
49 | ldi zeichen, '!' |
50 | rcall serout |
51 | ldi zeichen, 10 |
52 | rcall serout |
53 | ldi zeichen, 13 |
54 | rcall serout |
55 | rcall sync |
56 | rjmp loop |
57 | |
58 | serout: |
59 | sbis UCSR0A,UDRE0 ; Warten bis UDR für das nächste |
60 | ; Byte bereit ist |
61 | rjmp serout |
62 | sts UDR0, zeichen |
63 | ret ; zurück zum Hauptprogramm |
64 | |
65 | ; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich |
66 | ; das Kabel getrennt wurde |
67 | |
68 | sync: |
69 | ldi r16,0 |
70 | sync_1: |
71 | ldi r17,0 |
72 | sync_loop: |
73 | dec r17 |
74 | brne sync_loop |
75 | dec r16 |
76 | brne sync_1 |
77 | ret |
1 | AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36) |
2 | Copyright (C) 1995-2009 ATMEL Corporation |
3 | |
4 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(2): Including file 'C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc' |
5 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: Invalid register |
6 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(31): error: Invalid register |
7 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(36): error: Undefined symbol: UCSZn0 |
8 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(60): error: Operand 1 out of range: 0xc0 |
9 | C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(79): No EEPROM data, deleting C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.eep |
10 | |
11 | Assembly failed, 4 errors, 0 warnings |
Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit diesem Chaos hat: http://www.roboternetz.de/community/threads/45300-Atmega48-Uart-Wahnsinn Danke für eure Hilfe bis jetzt
*Update Ich habe jetzt mal in die m48def.inc geschaut, und da habe ich UCSZn0 in UCSZn00 umbenannt. Der Fehler is schonmal weg.
Natürlich habe ich das schon geändert Die erste Fehlermeldung sagt wohl, das die Datei nicht gefunden werden konnte. MfG Hans
Ausgeliefert wird er mit 1 MHz. Und die Zeile > ldi r16, (1<<USBS0)|(3<<UCSZn0) ist noch immer da. Dass Sie den Code nach serout: umschreiben müssen, haben Sie mitbekommen? > und da habe ich UCSZn0 in UCSZn00 umbenannt. > Der Fehler is schonmal weg. Definitiv nicht, Sie sind etwas von der Rolle.
K. R. schrieb: > *Update > Ich habe jetzt mal in die m48def.inc geschaut, > und da habe ich UCSZn0 in UCSZn00 umbenannt. > > Der Fehler is schonmal weg. Das sind noch 2: out UBRR0H, HIGH(UBRR_VAL) out UBRR0L, LOW (UBRR_VAL) mfg.
der alte Hanns schrieb: > Ausgeliefert wird er mit 1 MHz. > > Und die Zeile >> ldi r16, (1<<USBS0)|(3<<UCSZn0) > ist noch immer da. > > Dass Sie den Code nach serout: umschreiben müssen, haben Sie > mitbekommen? > >> und da habe ich UCSZn0 in UCSZn00 umbenannt. >> Der Fehler is schonmal weg. > Definitiv nicht, Sie sind etwas von der Rolle. Gott sei Dank muss man sich C um so einen Scheiss nicht kümmern. Das musste jetzt einfach mal gesagt werden. mfg.
Hi >Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit >diesem Chaos hat: >http://www.roboternetz.de/community/threads/45300-... Haben nur Leute, die nicht Lesen können oder wollen: http://www.atmel.com/Images/doc2553.pdf MfG Spess
1 | serout: |
2 | lds temp,UCSR0A |
3 | sbrs temp,UDRE0 |
4 | rjmp serout |
5 | sts UDR0,zeichen |
6 | ret |
Den Rest, Tippfehler &c., können Sie sicher alleine.
So alle Fehler behoben (mit F_CPU=4000000), aber es kommt immer noch nichts an, eine Idee woran es liegen könnte? (Die LED flackert trotzdem nicht) Wenn ich F_CPU auf 1000000 setze, dann funktioniert es nicht, weil der Compiler dann natürlich folgende Zeile ausspuckt: .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit geht es nicht. Was soll ich da machen?
1 | .include "m48def.inc" |
2 | |
3 | .def temp = r16 ; Register für kleinere Arbeiten |
4 | .def zeichen = r17 ; in diesem Register wird das Zeichen an die |
5 | ; Ausgabefunktion übergeben |
6 | |
7 | .equ F_CPU = 1000000 ; Systemtakt in Hz |
8 | .equ BAUD = 9600 ; Baudrate |
9 | |
10 | ; Berechnungen |
11 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden |
12 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate |
13 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille |
14 | |
15 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler |
16 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" |
17 | .endif |
18 | |
19 | ; Stackpointer initialisieren |
20 | |
21 | ldi temp, HIGH(RAMEND) |
22 | out SPH, temp |
23 | ldi temp, LOW(RAMEND) |
24 | out SPL, temp |
25 | |
26 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
27 | /* |
28 | ; Set baud rate |
29 | out UBRR0H, HIGH(UBRR_VAL) |
30 | out UBRR0L, LOW (UBRR_VAL) |
31 | ; Enable receiver and transmitter |
32 | ldi r16, (1<<RXEN0)|(1<<TXEN0) |
33 | sts UCSR0B,r16 |
34 | ; Set frame format: 8data, 2stop bit |
35 | ldi r16, (1<<USBS0)|(3<<UCSZ00) |
36 | sts UCSR0C,r16 |
37 | */ |
38 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
39 | |
40 | ; Baudrate einstellen |
41 | |
42 | ldi temp, HIGH(UBRR_VAL) |
43 | sts UBRR0H, temp |
44 | ldi temp, LOW(UBRR_VAL) |
45 | sts UBRR0L, temp |
46 | |
47 | ; Frame-Format: 8 Bit |
48 | |
49 | ldi temp, (1<<7)|(1<<2)|(1<<1) |
50 | sts UCSR0C, temp |
51 | |
52 | ldi temp, UCSR0B |
53 | ldi temp, (1<<TXEN0) |
54 | sts UCSR0B, temp |
55 | // sts UCSR0B,TXEN0 ; TX aktivieren |
56 | |
57 | ;;;;;;;;;;;;;;;;;;;;;;;;;;; |
58 | |
59 | loop: |
60 | ldi zeichen, 'T' |
61 | rcall serout ; Unterprogramm aufrufen |
62 | ldi zeichen, 'e' |
63 | rcall serout ; Unterprogramm aufrufen |
64 | ldi zeichen, 's' |
65 | rcall serout ; ... |
66 | ldi zeichen, 't' |
67 | rcall serout |
68 | ldi zeichen, '!' |
69 | rcall serout |
70 | ldi zeichen, 10 |
71 | rcall serout |
72 | ldi zeichen, 13 |
73 | rcall serout |
74 | rcall sync |
75 | rjmp loop |
76 | |
77 | serout: |
78 | // sbis UCSR0A,UDRE0 ; Warten bis UDR für das nächste |
79 | ; Byte bereit ist |
80 | ldi temp, UCSR0A |
81 | sbrs temp, UDRE0 |
82 | |
83 | rjmp serout |
84 | sts UDR0, zeichen |
85 | ret ; zurück zum Hauptprogramm |
86 | |
87 | ; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich |
88 | ; das Kabel getrennt wurde |
89 | |
90 | sync: |
91 | ldi r16,0 |
92 | sync_1: |
93 | ldi r17,0 |
94 | sync_loop: |
95 | dec r17 |
96 | brne sync_loop |
97 | dec r16 |
98 | brne sync_1 |
99 | ret |
K. R. schrieb: > So alle Fehler behoben (mit F_CPU=4000000), aber es kommt immer noch > nichts an, eine Idee woran es liegen könnte? > (Die LED flackert trotzdem nicht) > Das ist ja nun kompletter Unsinn. > Wenn ich F_CPU auf 1000000 setze, dann funktioniert es nicht, weil der > Compiler dann natürlich folgende Zeile ausspuckt: > .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit > geht es nicht. > > Was soll ich da machen? Setz die Baudrate auf 4800 und aktiviere das U2X0-Bit in UCSR0A. Damit verdoppelst du die Geschwindigkeit und hast wieder 9600. Aber dann passt der Teiler besser. mfg.
:
Bearbeitet durch User
Hi
>Was soll ich da machen?
Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.
MfG Spess
Ich habe mal die Baudrate auf 4800 gesetzt und dasselbe auch in HTERM gemacht, anstatt mein U2X0-Bit in UCSR0A zu setzen. Aber trotzdem sendet mein Atmega nichts.
Legen Sie vorläufig diese Berechnungen still und nehmen Sie die Werte
aus dem Datenblatt Examples of Baud Rate Setting:
ldi temp,high(12) ; 9600 Bd bei 1 MHz mit U2X0=1
sts UBRR0H,temp
ldi temp,low(12)
sts UBRR0L,temp
ldi temp,(1<<U2X0)
sts UCSR0A,temp
und weiter sollten Sie schreiben:
ldi temp,(1<<USBS0)+(1<<UCSZ01)+(1<<UCSZ00)
sts UCSR0C,temp
anstelle dieser Bitraterei bei UCSR0C.
Nebenbei:
> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.
Das stimmt so nicht ganz, siehe oben.
> ldi temp, UCSR0A > sbrs temp, UDRE0 Das haben Sie aber nicht von mir!
Eine geschlagene halbe Stunde ohne Reaktion ?! - Ich geh' schlafen. Kann mich aber doch nicht enthalten, bei allem Verständnis, Reinhard Mey zu zitieren: "Ich übe den Fortschritt, und das nicht faul, nehme zwei Schritt auf einmal und fall aufs Maul."
der alte Hanns schrieb: >> ldi temp, UCSR0A >> sbrs temp, UDRE0 > > Das haben Sie aber nicht von mir! Wie soll man das denn sonst lösen? der alte Hanns schrieb: > Eine geschlagene halbe Stunde ohne Reaktion ?! - Ich geh' > schlafen. > > Kann mich aber doch nicht enthalten, bei allem Verständnis, Reinhard Mey > zu zitieren: > "Ich übe den Fortschritt, und das nicht faul, > nehme zwei Schritt auf einmal und fall aufs Maul." Danke für Ihr Engagement, aber ich kann bedauerlicherweise erst morgen weiterarbeiten, ich muss zur Arbeit. der alte Hanns schrieb: > Legen Sie vorläufig diese Berechnungen still und nehmen Sie die > Werte > aus dem Datenblatt Examples of Baud Rate Setting: > > ldi temp,high(12) ; 9600 Bd bei 1 MHz mit U2X0=1 > sts UBRR0H,temp > ldi temp,low(12) > sts UBRR0L,temp > ldi temp,(1<<U2X0) > sts UCSR0A,temp > > und weiter sollten Sie schreiben: > ldi temp,(1<<USBS0)+(1<<UCSZ01)+(1<<UCSZ00) > sts UCSR0C,temp > anstelle dieser Bitraterei bei UCSR0C. > > Nebenbei: > >> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht. > > Das stimmt so nicht ganz, siehe oben. Ich werde morgen versuchen den Schritten zu folgen Danke!
Hi >> Nebenbei: >>> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht. >> Das stimmt so nicht ganz, siehe oben. >Ich werde morgen versuchen den Schritten zu folgen Bei 1MHz bekommst du bei 9600Bd einen Fehler von 7%. Mit Double Speed kommst du auf (theoretische) 0,2%. Allerdings mit verminderter Störsicherheit. Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal) nicht. MfG Spess
spess53 schrieb: > Hi > >>> Nebenbei: > >>>> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht. > >>> Das stimmt so nicht ganz, siehe oben. >>Ich werde morgen versuchen den Schritten zu folgen > > Bei 1MHz bekommst du bei 9600Bd einen Fehler von 7%. Mit Double Speed > kommst du auf (theoretische) 0,2%. Allerdings mit verminderter > Störsicherheit. > > Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh > zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal) > nicht. Nein. Das funktioniert sehr zuverlässig. Sofern man die Bedingungen, unter denen der Oszillator werkskalibriert ist, einigermassen einhält. Daß es ohne Neukalibrierung über den gesamten Temperatur- und Spannungsbereich nicht funktioniert, ist klar. mfg.
K. R. schrieb: > der alte Hanns schrieb: >>> ldi temp, UCSR0A >>> sbrs temp, UDRE0 >> >> Das haben Sie aber nicht von mir! > > Wie soll man das denn sonst lösen? Sie sollten korrekt kopieren: ich hatte lds geschrieben, nicht ldi (da UCSR0A=C0 und UDRE0=5, wird die Schleife nie verlassen). spess53 schrieb: > Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh > zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal) > nicht. Schon, spess53, aber wir wären ja bereits froh gewesen, wenn K.R. irgendeine Reaktion auf dem Monitor gesehen hätte.
K. R. schrieb: > Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit > diesem Chaos hat: > http://www.roboternetz.de/community/threads/45300-Atmega48-Uart-Wahnsinn > > Danke für eure Hilfe bis jetzt Das hier ist wiedermal ein schoenes Beispiel fuer jemanden, der offensichtlich nicht zu Ende gelesen hat. Im verlinkten Thread lag es eben gerade nicht an "diesem Chaos", sondern wie so oft sass die Fehlerursache vor dem Computer. wendelsberg
Nur die Geschwindigkeit ist auf 9600 Baud gedrosselt. Wenn ich dieses eine Bit setze, damit der Chip doppelt so schnell arbeitet, klappt das nicht, aber egal.
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.