Zeichenkette vom UART auswerten AVR Assembler

Gast #1146986
Lesenswert?

Hallo Leute,

ich möchte eine Zeichenkette (3 Zeichen) die über die serielle 
Schnittstelle kommt auswerten und hab mir auch ein kurze Routine 
geschrieben.
Leider nimmt der MC die Zeichenkette nicht an. Die Schnittstelle selbst 
funktioniert, weil die Initialisierungsroutine eine Zeichenkette an das 
Terminal schickt.
Im ersten Teil hab ich sowas wie ein Blinkprogramm eingefügt, damit ich 
sehen kann ob der MC irgendwo hängen leibt, was nicht der Fall ist.
Den Empfang hab ich freigeschalten:   sbi UCSRB,RXEN

Kann mir vielleicht jemand sagen warum, das Programm nicht so wie ich 
will?
Ich komm nicht von allein drauf
1
main:
2
        ldi r16, 0xf0
3
  out portb, r16
4
  rcall warte_1s
5

6
  ldi r16, 0x0f
7
  out portb, r16
8
  rcall warte_1s
9

10
  in r16, UDR    ; Zeichen auslesen
11
  cpi r16,0x74    ; prüfen ob t gedrückt wurde
12
  brne no_enter  
13
  out UDR, r16
14
 wait_RX1:
15
  sbis UCSRA,RXC
16
  rjmp wait_RX1
17

18
no_m:
19
  in r16, UDR    ; Zeichen auslesen
20
  cpi r16,0x6D    ; prüfen ob m gedrückt wurde
21
  brne no_m
22
  out UDR, r16
23
 wait_RX2:
24
  sbis UCSRA,RXC
25
  rjmp wait_RX2
26

27
no_p:
28
  in r16, UDR    ; Zeichen auslesen
29
  cpi r16,0x70    ; prüfen ob p gedrückt wurde
30
  brne no_p
31
  out UDR, r16
32
 wait_RX3:
33
 
34
  rcall get_temp
35
no_enter:
36
rjmp main
Persönliche Seite #1147004
Lesenswert?

Wird denn die Datadirection des UART-Ports richtig initialisiert, ich 
kann im Code keine Initialisierung finden. Standardmäßig ist nach dem 
Einschalten jeder Pin ein Eingang, das musst du aber geändert haben, 
sonst würde der AVR keine Zeichen senden können. Rxd muss als Eingang 
konfiguriert sein, vielleicht ist da ein Fehler passiert.

Man kann als Konstanten auch character schreiben, das wäre besser 
lesbar:

  cpi r16,'t'    ; prüfen ob t gedrückt wurde

Hast du mal eine einfache Loopback-Schleife getestet oder zumindest ein 
Hardwareloopback ausprobiert?

Grüße,

Peter
Gast #1147012
Lesenswert?

Hallo Peter,

ich wüsste nicht, dass RX und TX extra als Eingang bzw. Ausgang 
geschalten werden müssen, ich nutze die eingebaute serielle 
Schnittstelle.
Hier meine Initalisierungsroutine:
1
UART_INIT:
2
.equ BAUD = 38400
3
.equ UBRRVAL = F_CPU/(BAUD*16)-1
4
; Baudrate einstellen
5
  ldi r16, LOW(UBRRVAL)
6
  out UBRRL, r16
7
  ldi r16, HIGH(UBRRVAL)
8
  out UBRRH, r16
9
; Frame-Format: 8 Bit
10
  ldi r16, (1<<URSEL)|(3<<UCSZ0)
11
  out UCSRC, r16
12
  sbi UCSRB,TXEN    ; TX aktivieren
13
  sbi UCSRB,RXEN    ; RX aktivieren

Das mit dem Charater ist ein guter Hinweis...
Was meinst du mit Hardwareloopback?
Ich habe auch schon versucht, gleich nach dem Auslesen des Zeichens es 
wieder an die UART zurückzusenden, leider ohne Erfolg.
Das Senden an das Terminal funktioniert aber definitiv
Persönliche Seite #1148393
Lesenswert?

Hast du dir eigentlich genau überlegt, was diese Zeile macht?
ldi r16, (1<<URSEL)|(3<<UCSZ0)

Vor allem das mit der 3 in 3<<UCSZ0?

Ich habe das jetzt nicht nachgeprüft, aber die vordefinierten Bits (z.B. 
UCSZ0) sind eine Zahl von 0 bis 7 und geben die Stelle des jeweiligen 
Bits im Register an. Normalerweise verwendet man sie um den Code 
lesbarer zu machen und shiftet um eben die damit definierte Konstante 
eine 1 in das Register. Aber eine 3 setzt ja zwei Bits. Damit ist die 
Lesbarkeit verloren gegangen und zudem größere Verwirrung erzeugt, denn 
wer weiß dadurch intuitiv eindeutig, welches das zweite gesetzte Bit 
ist?

Also sollte man es entweder so machen:

ldi r16, (1<<URSEL)|(1<<UCSZ0)|(1<< das andere, was gemeint war)

Oder gleich ohne lesbare Konstanten:

ldi r16, 0xirgendwas

Grüße,

Peter
Gast #1148722
Lesenswert?

Hallo Peter,

ich muss natürlich gestehen, dass viele Codeteile nicht von mir sind.
Ich hatte ursprünglich begonnen einen Temperatursensor (DS1632) per TWI 
auszulesen.
Da ohne Vorkenntnisse habe ich mir den Code von Metaller geschnappt, 
siehe Blutrausch I2C. Nach einigen Wochen rumgefrickel und 
Datenblätterlesen hab ich es doch noch hinbekommen den Code entsprechend 
anzupassen.

Da die Ausgabe über den UART immer funktioniert hat, habe ich mir keine 
Gedanken drum gemacht. Erst als ich versucht habe den Code dahingehend 
zu erweitern, dass ich auch Befehle an den Temperatursensor schicken 
kann.
Wie wieder mal unschwer zu erkennen, spart man mit copy and paste 
mitnichten Zeit :-(

Um zurückzukommen zum Thema, das mit 3<<UCSZ0 ist mir gestern auch 
aufgefallen. Das hatte den Vorteil, dass mir einige Unstimmigkeiten in 
meinen alten selbstgeschriebenen Programmen aufgefallen sind.
Grundsätzlich kommt ja nach UCSZ0 gleich UCSZ1. wird jetzt eine 3 
reingeschoben, werden beide Bits gesetzt.

Ich werde mir das heute alles nochmal anschauen, kann ja nicht sein, 
dass ich für dieses Fuzelchen an Programmcode 2 Wochen brauche.

Nun werde ich wohl nochmal einen Schritt zurückgehen und die 
Befehlserkennung separat programmieren, das macht das debuggen dann 
hoffentlich einfacher.

Mein Controller ist übrigens der Mega8

Ich melde mich dann wieder,
Gruß, Jürgen

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