Moin, ich habe eben festgestellt, dass die USART zwischen Konfiguration (9600-8-N-1, 8 MHz-Quarz) ein kleines bischen braucht um die Konfiguration abzuschließen. Erst nach dieser kleinen Pause von vielleicht 20 Takten, kann ich die ersten Zeichen korrekt senden. Sonst kommt nur Müll raus. Bzw. Mal geht es, mal nicht. Frage: Wo steht so etwas im Datenblatt? Ich nutze zur Zeit einen ATmega1284P Jefe
Das liegt wahrscheinlich an der "falschen" Reihenfolge beim Beschreiben der Register. Der BAUD-Genertor bekommt ein Update, wenn man UBRRnL schreibt. Man muss erst alles konfigurieren und am Schluss erst TXENn auf 1 setzen. Dann sollte es ohne Pause funktionieren.
Kannst du das mal näher erklären? Denn eigentlich sendest du gar nichts, du schreibst nur einen Wert ins Register. Senden macht die Uart dann ganz alleine, und das erst, wenn die fertig initialisiert ist. Ich vermute eher, daß dein TX-Pin vor der Initialisierung low ist, und damit der Receiver auf den anderen Seite Probleme hat, daß Startbit zu erkennen. Oliver
Jefe schrieb: > Ich nutze zur Zeit einen > ATmega1284P Ich nutze den sehr gerne und oft, viel Platz und 20 MHz :) Aber ich hatte noch nie Probleme. Ich betreibe den sogar mit 57.6K oder 250K. Aber ich mach die Config. wie: Falk B. schrieb: > Man muss erst alles konfigurieren und am Schluss erst TXENn > auf 1 setzen.
:
Bearbeitet durch User
Jefe schrieb: > Frage: Wo steht so etwas im Datenblatt? Zeig mal deine Init(). Dann sieht man es gleich, oder ich teste es morgen früh. Edit: Nebensächlich - warum wählt man einen 1284 und treibt den mit "nur" 8 Mhz?
:
Bearbeitet durch User
Adam P. schrieb: > Edit: > Nebensächlich - warum wählt man einen 1284 und treibt den mit "nur" 8 > Mhz? Hatte nur ein 8 MHz Quarz übrig. Ansonsten hat sich das Problem erledigt. Es ist wohl eher irgendetwas im Zusammenhang CH340 Windows 11 USB3. Warum auch immer klappt es nun ohne Probleme. Hier aber der Code. Vielleicht gibt es ja noch Potential ;-)
1 | .include "m1284Pdef.inc" |
2 | |
3 | .equ F_CPU = 8000000 |
4 | |
5 | .equ BAUD_9600 = 9600 |
6 | |
7 | .equ UBRR_VAL_9600 = ((F_CPU+BAUD_9600*8)/(BAUD_9600*16)-1) |
8 | .equ BAUD_REAL_9600 = (F_CPU/(16*(UBRR_VAL_9600+1))) |
9 | .equ BAUD_ERROR_9600 = ((BAUD_REAL_9600*1000)/BAUD_9600-1000) |
10 | |
11 | .if ((BAUD_ERROR_9600>10) || (BAUD_ERROR_9600<-10)) |
12 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent!" |
13 | .endif |
14 | |
15 | .cseg |
16 | |
17 | .org 0x0000 |
18 | ldi r16, HIGH(RAMEND) |
19 | out SPH, r16 |
20 | ldi r16, LOW(RAMEND) |
21 | out SPL, r16 |
22 | |
23 | ldi r17, HIGH(UBRR_VAL_9600) |
24 | ldi r18, LOW(UBRR_VAL_9600) |
25 | sts UBRR0H, r17 |
26 | sts UBRR0L, r18 |
27 | ldi r16, 0b00000110 |
28 | sts UCSR0C, r16 |
29 | |
30 | clr r16 |
31 | ldi r16, (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0) |
32 | sts UCSR0B, r16 |
33 | |
34 | ldi r16, 6 |
35 | call serout_raw |
36 | call serout_raw |
37 | call serout_raw |
38 | |
39 | loop: |
40 | jmp loop |
41 | |
42 | |
43 | serout_raw: |
44 | lds r19, UCSR0A |
45 | sbrs r19, UDRE0 |
46 | rjmp serout_raw |
47 | sts UDR0, r16 |
48 | ret
|
Jefe schrieb: > Es ist wohl eher irgendetwas im Zusammenhang CH340 Windows 11 USB3. > Warum auch immer klappt es nun ohne Probleme. Ein Oszilloskop würde hier in kurzer Zeit Klarheit bringen. Denn damit kann man genau sehen, was auf dem Bus los ist. Und wenn man parallel auf einem anderen Portpin noch ein Triggersignal ausgibt, dann kann man sogar ganz einfach messen, wie lange das Versenden dauert. > (1<<RXCIE0) Warum schaltest du da den Interrupt aktiv? Zum Glück ist da nirgends ein sei(). Kann lustig werden, wenn du die Interrupts später mal global aktivierst, weil du z.B. einen Pinchange-Interrupt verwenden willst.
:
Bearbeitet durch Moderator
Nach dem Reset sind alle Pins hochohmig, d.h. der Pegel ist undefiniert. Wenn der nachgeschaltete IC keinen Pullup hat, kann also Mumpitz anliegen. Sauber ist es daher, nach dem Reset den Pin als high oder mit Pullup zu setzen und in diesem Zustand für mindestens eine Bytezeit zu belassen. Danach ist der Empfänger garantiert für das nächste Startbit bereit.
:
Bearbeitet durch User
Peter D. schrieb: > Sauber ist es daher, nach dem Reset den Pin als high oder mit Pullup zu > setzen und in diesem Zustand für mindestens eine Bytezeit zu belassen. > Danach ist der Empfänger garantiert für das nächste Startbit bereit. OK, den RX auf high. Was ist mit TX?
Jefe schrieb: > OK, den RX auf high. Was ist mit TX? Ich glaube der TX-Pin war gemeint. Also vor dem ersten Senden entweder vor Aktivierung der UART den TX-Pin auf Output High stellen und eine Bytezeit warten, oder die UART aktivieren und danach noch eine Bytezeit warten. Andonsten kann die anscheinend der zunächst undefinierte TX-Pegel den Anfang der Übertragung korrumpieren. LG, Sebastian
Sebastian schrieb: > Ich glaube der TX-Pin war gemeint. Ja natürlich, habe ich auch schon so umgesetzt. Meinte RX
Könnte sein, dass Du Back to Back sendest und er sich nicht auf Start synchronisiert. 2 stopbits beim Sender und 1 beim Empfänger sorgen meist schnell für Abhilfe
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.