Forum: Mikrocontroller und Digitale Elektronik ATmega1284 braucht Pause zwischen USART-Konfiguration und ersten Zeichen


von Jefe (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

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.

von Ingo Less (Gast)


Lesenswert?

Zeig mal

von Oliver S. (oliverso)


Lesenswert?

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

von Adam P. (adamap)


Lesenswert?

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
von Adam P. (adamap)


Lesenswert?

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
von Jefe (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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
von Jefe (Gast)


Lesenswert?

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?

von Sebastian (Gast)


Lesenswert?

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

von Jefe (Gast)


Lesenswert?

Sebastian schrieb:
> Ich glaube der TX-Pin war gemeint.

Ja natürlich, habe ich auch schon so umgesetzt. Meinte RX

von A. S. (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.