UART Frage betreffs startbit stopbit etc.

OP #623093
Lesenswert?

hi,
ich habe mal ne Frage ich möchte eine Verbindung zwichen meinem Atmega 
und meinem taschenrechner herstellen. Ich hätte dazu zwei Fragen:

1. Ich brauche: 1 startbit, 8 databits, no parity, 2 stopbits, 9600 baud


wie stell ich das ein Ich weis nur wie das mit der Baudrate geht.

2. ich muss z.B. laut protokoll 13h senden was kann damit gemeint sein?

nur 13 13 und h oder steht das h für hexa also 19?


hier der Link dazu:

http://users.pandora.be/gp/casio/
Gast #623163
Lesenswert?

@ Florentin Schirmer (tuxianer)


>wie stell ich das ein Ich weis nur wie das mit der Baudrate geht.

Steuerregister des USART.

>2. ich muss z.B. laut protokoll 13h senden was kann damit gemeint sein?

Bit du sicher, dass du mit dem AVR umgehen kannst, wen du schon über 13h 
stolperst?

13h heisst 13 in hexadezinaler Darstellung. 0x13 oder $13, dezimal 19

>nur 13 13 und h oder steht das h für hexa also 19?

ja.

MfG
Falk
OP #623179
Lesenswert?

also mit dem 0x13 ist klar das hatte cih auch so gemacht, ich wollt mich 
nur nochmal versichern ich habe mich vlt blöd ausgedrückt. Leider 
funktioniert mein programm nicht so wie es soll...zumindestens gehen 
keine Dioden an und auf dem Re4chner bekomme ich ein error...
1
 
2
.include "m32def.inc"                    ; bzw. 2333def.inc
3
 
4
.def temp = R16
5
.def RX = R17
6
.def TX = R18
7
.equ CLOCK = 16000000
8
.equ BAUD = 9600
9
.equ UBRRVAL = CLOCK/(BAUD*16)-1
10
 
11
.org 0x00
12
        rjmp main
13
 
14
.org URXCaddr                             ; Interruptvektor für UART-Empfang
15
        rjmp int_rxc
16
 
17
; Hauptprogramm
18
main:
19
        ldi temp, LOW(RAMEND)
20
        out SPL, temp
21
        ldi temp, HIGH(RAMEND)
22
        out SPH, temp
23

24
    ldi temp, 0xFF                    ; Port D = Ausgang
25
        out DDRD, temp
26

27
    ldi temp, 0xFF
28
    out PortD, temp
29
 
30
        ; Baudrate einstellen
31
        ldi temp, HIGH(UBRRVAL)
32
        out UBRRH, temp
33
        ldi temp, LOW(UBRRVAL)
34
        out UBRRL, temp
35
 
36
        ; Frame-Format: 8 Bit
37
    ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)
38
        out UCSRC, temp
39
 
40
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
41
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
42
    sbi UCSRB, TXEN            ; TX (Senden) aktivieren 
43
        
44
        sei                               ; Interrupts global aktivieren
45
        
46
loop:   rjmp loop                         ; Endlosschleife
47
 
48
; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
49
int_rxc:
50
        push temp                         ; temp auf dem Stack sichern
51
    cbi  PORTD, 5 
52
    in RX, UDR                ; Empfangenes Byte in RX speichern
53

54
    cpi  RX,0x16
55
    
56
      breq Transmit
57

58
    pop temp                          ; temp wiederherstellenerrupt beenden
59
        reti                              ; Int
60
        
61

62

63
Transmit:
64

65
        ldi TX, 0x13
66
    sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste Byte bereit ist
67
    rjmp Transmit
68
        out UDR, TX
69
    cbi  PORTD, 6
70
        reti                              ; zurück zum Hauptprogramm
Gast #623198
Lesenswert?

breq Transmit

    pop temp                          ; temp wiederherstellenerrupt 
beenden
    reti                              ; Int

Transmit:

    ldi TX, 0x13
    sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste

    rjmp Transmit
    out UDR, TX
    cbi  PORTD, 6
    reti                              ; zurück zum Hauptprogramm


das funktioniert nicht, weil Du am Ende von Transmit
kein "pop" ausführst.....

Otto
OP #623206
Lesenswert?

so...ich habegerade gemerkt aus TX kommt dauerhaft strom ist das 
normal???


ich dachte es liegt daran das habe ich mal geändert.


    ldi temp, 0b01100000
    out PortD, temp

aber es kommt immer noch strom...


so es geht jetzt bis zur ersten LED allerdings wenn ich die LED nach 
erfolgreichen Vergleich schlate gehts nicht...
OP #623219
Lesenswert?

1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp = R16
4
.def RX = R17
5
.def TX = R18
6
.equ CLOCK = 16000000
7
.equ BAUD = 9600
8
.equ UBRRVAL = CLOCK/(BAUD*16)-1
9
 
10
.org 0x00
11
        rjmp main
12
 
13
.org URXCaddr                             ; Interruptvektor für UART-Empfang
14
        rjmp int_rxc
15

16

17
;Hauptprogramm
18
main:
19
        ldi temp, LOW(RAMEND)
20
        out SPL, temp
21
        ldi temp, HIGH(RAMEND)
22
        out SPH, temp
23

24
        ldi temp, 0xFF                    ; Port D = Ausgang
25
        out DDRD, temp
26

27
        ldi temp, 0b01100000
28
        out PortD, temp
29
 
30
        ; Baudrate einstellen
31
        ldi temp, HIGH(UBRRVAL)
32
        out UBRRH, temp
33
        ldi temp, LOW(UBRRVAL)
34
        out UBRRL, temp
35
 
36
        ; Frame-Format: 8 Bit
37
        ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)
38
        out UCSRC, temp
39
 
40
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
41
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
42
        sbi UCSRB, TXEN        ; TX (Senden) aktivieren 
43
        
44
        sei                               ; Interrupts global aktivieren
45
        
46
loop:   rjmp loop                         ; Endlosschleife
47
 
48
; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
49
int_rxc:
50
    
51
       push temp                        ; temp auf dem Stack sichern
52
    
53
       cbi  PORTD, 5
54
       in RX, UDR             ;Empfangenes Byte in RX speichern
55

56
       cpi  RX,0x16
57
    
58
       breq Transmit
59

60
       pop temp                          ; temp wiederherstellenerrupt beenden
61
      reti                              ; Int
62
        
63

64

65
Transmit:
66
       cbi  PORTD, 6
67
       ldi TX, 0x13
68
       sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste Byte bereit ist
69
       rjmp Transmit
70
       out UDR, TX
71
    
72
       reti                              ; zurück zum Hauptprogramm
OP #623234
Lesenswert?

also daran kanns ja nicht liegen mit dem Pop aber danke für den 
hinweis...temp wird ja eh nirgendwo anders verwendet...und ich habe 2 
Dioden über widerstand zu Ground an Portd 5 und 6


Ps.: im Moment leuchtet Diode 1 nur wenn ich die TX Leitung abklemme
Gast #623237
Lesenswert?

>also daran kanns ja nicht liegen mit dem Pop aber danke für den

Ich glaube es hackt ! Zu JEDEM PUSH gehört genau ein POP.
Egal wo, aber es muss getan werden. Sonst läuft dir der Stack über !
Gast #623242
Lesenswert?

Du mußt auch bei erfolgreichem Vergleich das Temp-Register wieder pop'en
Und so ist schöner:
1
int_rxc:
2
       push temp                ; temp auf dem Stack sichern
3
    
4
       cbi  PORTD, 5
5
       in RX, UDR               ;Empfangenes Byte in RX speichern
6
       cpi  RX, 0x16
7
       brne ende
8

9
       cbi  PORTD, 6
10
       ldi TX, 0x13
11
Transmit:
12
       sbis UCSRA, UDRE         ; Warten bis UDR ist
13
       rjmp Transmit
14
       out UDR, TX
15
ende:
16
       pop temp                 ; temp wiederherstellen
17
       reti                     ; zurück zum Hauptprogramm
Allerdings brauchst du nur die Register zu pushen, die du auch benutzt 
;)

hth. Jörg
Gast #623277
Lesenswert?

Es wird nur dann nicht gesprungen wenn 0x16 empfangen wird (das ist kein 
druckbares ASCII zeichen, btw) und um den Empfang zu simulieren 
müsstest du Stimuli-Files benutzen (dabei kann ich dir nicht helfen) 
oder nach dem "in RX, UDR" das Register RX mit 0x16 von Hand 
beschreiben.
Wenn du direkt mit dem AVR "redest" solltest du vielleicht 0x16 in ein 
druckbares zeichen ändern, z.B. 'A' (MIT ' in den Code schreiben)

hth. Jörg
Gast #623299
Lesenswert?

einfach geht es erst mal so:

loop:   ldi temp, 0b01100000   ; LED aus
        out PortD, temp        ;
        rjmp loop              ; Endlosschleife

int_rxc:
       push temp                ; temp auf dem Stack sichern

       cbi  PORTD, 5
       in RX, UDR               ;Empfangenes Byte in RX speichern
       cpi  RX, 0x16
       brne ende

       cbi  PORTD, 6
       ldi TX, 0x13
Transmit:
       sbis UCSRA, UDRE         ; Warten bis UDR ist
       rjmp Transmit
       out UDR, TX
ende:
       pop temp                 ; temp wiederherstellen
       reti                     ; zurück zum Hauptprogramm

Otto
Gast #623318
Lesenswert?

Bitte etwas genauer:

1. die LED werden ausgeschaltet

2. bei Empfang irgendeines Zeichens geht LED 1 an

3. bei Empfang "0x16" LED 2 - aber "0x16" kannst Du wahrscheinlich nicht 
senden.

Versuche, den AVR an den PC anzuschliessen und arbeite z. B. mit 
Hyperterminal, bis alles läuft.

Dann kannst Du, wie Joerg riet, auf 'A' abfragen und siehst 
anschliessend auch das "13" (CR)

Otto
Gast #623335
Lesenswert?

"hex abfragen" geht natürlich beim AVR - die Frage ist, ob Du das 
Zeichen senden kannst.

Anders ist die Anzahl der Stoppbits:

; Set frame format: 8data, 2stop bit
ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)

Gruß Otto
Gast #623348
Lesenswert?

Hallo,

das kann nicht gehen. Der Rechner will immer einen kompletten Block 
haben mit Checksumme usw. Du sendest nur 1 byte und dann nix mehr. -> 
Error

Dann läuft das Programm auch sehr schnell, da wirst du keine LED An/Aus 
erkennen. Wenn doch, dann stimmt was nicht mit der Clockrate oder so.
Nicht stören lassen, der Taschenrechner kommt mit 1 und 2 Stoppbits 
zurecht.

Condi
OP #623392
Lesenswert?

Also zum Senden komm ich ja garnicht...wenn ich eine LED nach den 
Vergleich setzte springt diese nicht an. Die Cehcksum kommt erst im 
Header soweit bin ich leider noch nicht. Und wie muss die Einstellung 
nun lauten für die Stopbits?

die LED wird ja angeschalten wenns klappt und leibt dann an! Siehe die 
erste.
Gast #623497
Lesenswert?

Beschreib mal deinen Aufbau: Was ist womit verbunden (v.A. der USART)?, 
Wo/Wie sind die LEDs angeschlossen?
Wenn dein Atmega auf bestimmte Zeichen reagieren soll: wo kommen diese 
Zeichen her (Taschenrechner, PC...)?

Indem Beispielcode den du (ganz weit) oben verlinkt hast, wird ein 
Atmega162 verwendet, der hat 2 USART: einer ist mit dem PC verbunden, 
der andere mit dem Taschenrechner. Deshalb komm ich auf die Frage: Was 
hast du eigentlich vor?

hth. Jörg
OP #623504
Lesenswert?

Also das hatte ich eigentlich alles schon beschrieben...ist leider etwas 
verstreut deshalb nochmal:

ich will vom GTR Variablen ec. an den Controller senden.

Der ist via Kabel an den RX und TX Port verkabelt PortD0 und 1.

Die Leds hängen nach folgendem Schema an PortD 5/6:


Controller-->Widerstand-->-Diode+-->VCC
#623509
Lesenswert?

So wie ich das sehe, hast du 2 Baustellen.
Die eine die UART am AVR, die andere das Protokoll welches
du einhalten musst um mit dem Casio zu kommunizieren.
Das ist nicht gut, weil du nie weist, wo denn ein Fehler
liegt.

Ich würde mal hergehen und eine Baustelle stilllegen:
An den AVR einen MAX232 anschliessen und damit eine
serielle Verbindung zum PC aufbauen. Am PC läuft dann
ein einfaches Terminalprogramm, welches alles was von
der Seriellen kommt mitprotokolliert. Dadurch hast du
schon mal das Casio-Protokoll Problem weg und kannst dich
nur auf die UART am AVR konzentrieren.

Läuft die dann irgendwann, dann gehts wieder zurück auf die
Casio Schnittstelle und das Protokoll ist drann.

Das andere:
Wenn ich mir deinen Assembler-Code und das daraufhin
gezeigte Verständnis so ansehe, wäre vielleicht eine
Programmierung in C nicht das schlechteste.
Gast #623536
Lesenswert?

Sorry, aber dann hat er noch eine Baustelle mehr !

Da ist einfach etwas Zeit erforderlich um sich einzuarbeiten - und ich 
persönlich halte assembler für sehr sinnvoll um die Hardware erst mal 
kennenzulernen. C vielleicht dann mal später.

@ Florentin: Also nicht aufgeben - notfalls erst mal ein einfacheres 
Thema angehen !!!

Gruß
Stefan
#623546
Lesenswert?

Stefan wrote:
> Sorry, aber dann hat er noch eine Baustelle mehr !

Einen Max232 anschliessen ist aber keine Raktentechnik.
Das wär mir auf jeden Fall lieber als mit einem Gerät
zu kommunizieren, welches ein bestimmtes Protokoll
erwartet und ich nicht weiss ob meine UART grundsätzlich
funktioniert oder ob ich im Protokoll einen Fehler hab.

Die Hilfs-Baustelle Mega - MAX232 - Kabel - PC - Hyperterminal
ist in 20 Minuten befahrbar und: da kann eigentlich nicht
viel schief gehen (ausser der ewigen Frage: Modem oder Nullmodem-
Kabel). Wenn die UART an dieser Baustelle nicht funktioniert,
dann wird sie auch an der Casio Baustelle nicht funktionieren.
Umgekehrt: Wenn die PC Baustelle funktioniert, dann hab ich
bei einem Casio-Baustellenproblem schon mal eine Fehlerquelle
weniger.

Und: Im Schlimmsten Fall hat man damit auf dem PC mit HTerm ein
mächtiges Werkzeug um sich anzusehen, was denn der AVR/Casio
nun wirklich sendet und kann dann am PC auch mal die Gegenstelle
vorgaukeln.

Aber: Jeder wie er mag.
Gast #624145
Lesenswert?

Also der Mega162 wurde gewählt da 2 Taschenrechner sich in einem 
Programm nicht direkt unterhalten können. Er dient so als Puffer und 
Umsetzer.

Und nochmals, auf dem Rechner kommt immer ein Error wenn du nicht den 
Start und Stop Header sendest. Es ist dabei vollkommen egal ob du ein 
Programm, Matrix oder nur eine Variable sendest.


In der main loop von otto werden die LED's ausgeschalten. Nun kommt ein 
Zeichen und der geht in den interrupt. Da wird die LED 1 eingeschalten.
Wenn keine 0x16 empfangen wurde, geht der wieder ind die Main und die 
LED's gehen aus. Wurde 0x16 empfangen, setzt er die LED 2 auf ein sendet 
und geht in die Main wo die LED's ausgeschalten werden. Das geht so 
schnell, da kann man höchstens ein sehr kurzes flackern sehen. Bleiben 
die LED's an, dann läuft der Stack über oder das UDR wird nie leer.... 
oder du hast nen komplett anderen Code.

Condi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren