Forum: Mikrocontroller und Digitale Elektronik ATMEGA16 Revision & USART receive buffer


von Klaus 2. (klaus2m5)


Lesenswert?

Weiß zufällig jemand, ob es alte ATMEGA16 gibt, die nur ein Byte 
Receiver UDR haben. Das Datasheet sagt zwei Byte und zusätzlich kann das 
Schieberegister das dritte Byte halten.

Bei einem Loopback Test verliere ich das erste Byte, wenn drei Bytes 
gesendet wurden bevor ich anfange zu lesen. Wenn ich mit dem lesen > 1 
Frame warte, bekomme ich sogar nur das letzte Byte. UCSRA.OVR wird nie 
gesetzt. Habe leider gerade keinen neueren ATMEGA16, um es zu testen.

Es ist ein ATMEGA16-16PI 0309 (9. Woche 2003)

Der Code ist simpel, die Umgebung leider nicht (6502 Emulator auf einem 
ATMEGA32 steuert IO-Register auf einem ATMEGA16).
1
start
2
        lda #isc_usart      ;init USART
3
        sta ios_cr
4
        lda #$19            ;38400 Baud @ 16MHz
5
        sta ios_r0          ;ubrrl
6
        lda #(1<<is_rxen)|(1<<is_txen) ;enable USART
7
        sta ios_r1          ;ucsrb         
8
        lda #0
9
        sta send_cnt
10
        sta rcv_cnt
11
        
12
loop:
13
        jsr send
14
        jsr send
15
        jsr send
16
        jsr receive
17
        jsr receive
18
        jsr receive
19
        jmp loop
20
21
send:
22
        lda ios_r2          ;ucsra
23
        and #(1<<is_udre)
24
        beq send            ;wait udre = 1
25
        ldx send_cnt
26
        stx ios_dr          ;udr
27
        inc send_cnt
28
        rts
29
        
30
receive:
31
        lda ios_r2          ;ucsra
32
        bpl receive         ;wait rxc = 1
33
        ldx ios_dr          ;udr
34
        and #(1<<is_fe|1<<is_dor|1<<is_upe) ;check for errors
35
        bne *
36
        cpx rcv_cnt         ;check for dropped count/byte
37
        bne *
38
        inc rcv_cnt
39
        rts
So funktionierts:
1
loop:
2
        jsr send
3
        jsr send
4
;        jsr send
5
        jsr receive
6
        jsr receive
7
;        jsr receive
8
        jmp loop

von Stefan F. (Gast)


Lesenswert?

>  Das Datasheet sagt zwei Byte

Das überrascht mich aber. Ich war bisher stets davon ausgegangen, dass 
der Serielle Port bei allen AVR Typen nur ein einfaches UDR Register hat 
+ ein Schieberegister.

Ich würde mich freuen, wenn du mal den entsprechenden Abschnitt des 
Datenblattes als Screenshot reinstellen würdest, oder zittieren.

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

@ Stefan Us (stefanus)

>>  Das Datasheet sagt zwei Byte

>Das überrascht mich aber. Ich war bisher stets davon ausgegangen, dass
>der Serielle Port bei allen AVR Typen nur ein einfaches UDR Register hat
>+ ein Schieberegister.

Das sind die ganz alten AVRs aus der Anfangszeit.

>Ich würde mich freuen, wenn du mal den entsprechenden Abschnitt des
>Datenblattes als Screenshot reinstellen würdest, oder zittieren.

Siehe Anhang.

von Klaus 2. (klaus2m5)


Lesenswert?

Danke, Falk

UCSRA.OVR soll natürlich UCSRA.DOR heißen. UCSRA.DOR wird nie gesetzt, 
also auch kein Overrun erkannt. Es fehlt einfach das erste Byte.

von S. Landolt (Gast)


Lesenswert?

Und wie sieht das Programm auf dem ATmega16 aus?

von Stefan F. (Gast)


Lesenswert?

>> Ich würde mich freuen, wenn du mal den entsprechenden Abschnitt des
>> Datenblattes als Screenshot reinstellen würdest, oder zittieren.
> Siehe Anhang.

Dankeschön!

von Peter D. (peda)


Lesenswert?

Die AVRs haben 2,9 Byte Empfangspuffer, d.h. das letzte Stop-Bit darf 
noch nicht empfangen worden sein.
Sind 3 volle Bytes empfangen worden, geht eins verloren.

Klaus 2. schrieb:
> Wenn ich mit dem lesen > 1
> Frame warte, bekomme ich sogar nur das letzte Byte.

Dann ist Dein 6502 Interpreter Schrott.

von Falk B. (falk)


Lesenswert?

@ Peter Dannegger (peda)

>Die AVRs haben 2,9 Byte Empfangspuffer, d.h. das letzte Stop-Bit darf
>noch nicht empfangen worden sein.
>Sind 3 volle Bytes empfangen worden, geht eins verloren.

Das Datenblatt sagt aber was anderes, es spricht vom 4. START-Bit!

von S. Landolt (Gast)


Lesenswert?

(Irgendwo steht es, aber ich finde die Stelle nicht)

Wurden 3 Zeichen 'a' 'b' 'c' empfangen, so erhält man beim nachfolgenden 
Auslesen 'a' 'b' 'c'.

Wurden 4 Zeichen 'a' 'b' 'c' 'd' empfangen, so erhält man beim 
nachfolgenden Auslesen 'a' 'b' 'd'.

von Klaus 2. (klaus2m5)


Angehängte Dateien:

Lesenswert?

Falk B. schrieb:
> @ Peter Dannegger (peda)
>
>>Die AVRs haben 2,9 Byte Empfangspuffer, d.h. das letzte Stop-Bit darf
>>noch nicht empfangen worden sein.
>>Sind 3 volle Bytes empfangen worden, geht eins verloren.
>
> Das Datenblatt sagt aber was anderes, es spricht vom 4. START-Bit!

So sehe ich das auch! Wie auch immer, mein ATMEGA16 verhält sich so, als 
ob nur ein Byte gepuffert würde, also

'a' 'b' 'c' gesendet
   - lesen während 'c' noch gesendet wird ergibt 'b' 'c'
   - lesen nachdem 'c' gesendet wurde (TXC) ergibt nur noch 'c'

Ich werde das morgen mal direkt auf dem ATMEGA16 testen ohne den Umweg 
über den Emulator. Da wird sich hoffentlich zeigen, wo der Fehler liegt.

Danke erst mal an alle!

Ich habe spaßeshalber mal den ATMEGA16 Code angehängt. Ich bin ziemlich 
sicher, dass sich das niemand wirklich antun will.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Sie haben Recht, das will ich mir nicht antun. Mir ist auch unklar, 
weshalb man eine so grundlegende Fragestellung mit einem solchen Klotz 
von Programm überprüft.

Hier ist mein Programm, es verhält sich wie oben beschrieben. Bei 
Tastendruck (gegen GND) werden die angekommenen Zeichen zurückgesendet. 
Läuft auf einem ATmega16A-PU (1340) (und ich bin sicher, genauso auf 
meinem alten ATmega16L-8PI, wenn ich den denn wieder fände).
1
main:
2
    sbi     DDR_Taste,Taste
3
    ldi     tmp0,1
4
    out     UBRRL,tmp0
5
    ldi     tmp0,(1<<RXEN)+(1<<TXEN)
6
    out     UCSRB,tmp0
7
main_loop:
8
    sbic    PIN_Taste,Taste
9
   rjmp     main_loop
10
    sbis    UCSRA,RXC
11
  rjmp      main_loop
12
13
out_loop:
14
    in      tmp0,UDR
15
    out     UDR,tmp0
16
     sbis   UCSRA,TXC
17
    rjmp    pc-1
18
    sbi     UCSRA,TXC
19
    sbic    UCSRA,RXC
20
  rjmp      out_loop
21
    ldi     tmp0,$0D
22
    out     UDR,tmp0
23
    ldi     tmp0,$0A
24
    out     UDR,tmp0
25
     sbis   PIN_Taste,Taste
26
    rjmp    pc-1
27
   rjmp     main_loop

von Falk B. (falk)


Lesenswert?

@Klaus 2m5 (klaus2m5)

>Ich werde das morgen mal direkt auf dem ATMEGA16 testen ohne den Umweg
>über den Emulator. Da wird sich hoffentlich zeigen, wo der Fehler liegt.

AHHHH!!! Sag das doch gleich! Der Simulator verhält sich in vielen 
Fällen NICHT 100% exakt zur Hardware!

von Klaus 2. (klaus2m5)


Lesenswert?

@ S.Landolf:
Vielen Dank fürs überprüfen. Durch Ihre ursprüngliche Frage habe ich mir 
erst mal Gedanken darüber gemacht, was bei einem echten Overrun 
eigentlich passieren sollte.

Ahhhhh! "Klatsch" (Geräusch einer auf der Stirn aufschlagenden 
Handfäche)

In meinem Programm für den ATMEGA16 wird verhindert, dass der Benutzer 
Bits ändern kann, die zum Interface des 6502 Emulators auf dem ATMEGA32 
gehören oder die einen Absturz des ATMEGA16 verursachen können (z.B. 
WDTCR.WDE). Das funktioniert auch sehr gut. Dummerweise müssen diese 
Bits irgendwie gesichert werden, damit die geschützten Bits wieder 
hergestellt werden können. Leider ist das UDR eins der wenigen Register, 
die beim Lesen eine Zusatzfunktion haben, nämlich den Reiceive Buffer zu 
leeren.

Die Lösung ist also, das Lesen zu unterdrücken wenn keine Bits geschützt 
werden müssen. Bei einem seriellen Datenregister macht es sowieso keinen 
Sinn, einzelne Bits zu schützen. Ich werde mich wieder melden, ob der 
Fix funktioniert.

@Falk:
Entschuldige, dass ich mich missverständlich ausgedrückt habe. Der 
Emulator ist ein 6502 Interpreter auf einem ATMEGA32, der über ein 
definiertes Interface mit dem ATMEGA16 kommuniziert und dort auf die 
IO-Register zugreift. Es ist also schon richtige Hardware, nicht nur 
eine Simulation auf einem PC zum Beispiel.

Deshalb finde ich es immer wichtig, zwischen Simulator und Emulator zu 
unterscheiden. In einem Flugsimulator fliegt man nicht wirklich. Wenn 
ich aber ein Cockpit einer 737 mit den Instrumenten eines A320 
ausstatte, dann ist das ein Emulator, denn ich kann dann als A320 Pilot 
eine 737 tatsächlich in die Luft bringen, ohne die 737 Instrumentierung 
im Detail zu kennen.

@Allgemein:
Noch einmal vielen Dank an Alle, die einen Teil ihrer Zeit für mein 
Problem geopfert haben. Nachdem ich gestern ein ATMEGA16 Preliminary 
Manual von 2002 gefunden hatte, dass auch schon die dreifach Pufferung 
beschreibt, dämmerte mir, dass der ATMEGA16 wohl genau so funktionieren 
muss und das Problem irgendwo in meinem Code auf der ATMEGA16 Seite zu 
finden sein muss.

Leider hatte ich gestern dann auch keine Zeit mehr, da ich mich mit 
Freunden zum Üben für unseren Sprachkurs verabredet hatte.

Τα λέμε, παιδιά! (griechisch: Tschüss Leute!)

von Klaus 2. (klaus2m5)


Lesenswert?

So jetzt kann ich bis zu 4 Bytes senden, bevor ich mit dem lesen anfange 
(1 Byte UDR TX Buffer, 1 Byte im Shifter, 2 Bytes UDR RX Buffer).

Wenn ich 5 Bytes sende (a b c d e), geht das Byte im Shifter verloren (a 
b d e, genau wie das S. Landolf beschrieben hat) und overrun wird für 
das folgende Byte (d) auch korrekt angezeigt.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Jetzt habe ich die Stelle wieder gefunden, steht aber in einem anderen 
Datenblatt unter 'USART in SPI mode':

Note: To keep the input buffer in sync with the number of data bytes 
transmitted, the UDRn register must be read once for each byte 
transmitted. The input buffer operation is identical to normal USART 
mode, that is, if an overflow occurs the character last received will be 
lost, not the first data in the buffer. This means that if four bytes 
are transferred, byte 1 first, then byte 2, byte 3, and byte 4, and the 
UDRn is not read before all transfers are completed, then byte 3 to be 
received will be lost, and not byte 1.

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.