Frage zu meinem Program

OP #901413
Lesenswert?
• ▲
▼
Hallo,
arbeite erst seit gestern mit dem AVR und bin deswegen ziemlich 
unerfahren... Hab mir euer Tutorial durchgelesen und nun versucht, ein 
paar Dinge zu kombinieren... So z.b. dass ich jeweils eine 1 oder 0 per 
UART zum AVR schicke, der mir einen Motor an bzw. ausmacht und als 
gegennachricht ein "Ein" oder "Aus zurück an den Computer via UART 
schickt...
Ein und AUsschalten kann ich den Motor so... Nur kommt als Rückmeldung 
immer "Aus". Wenn ich eigentlich eingeschlatet habe, steht da 6x Aus und 
wenn ich richtig Ausgeschaltet habe steht nur einmal "Aus". Wie kommt 
das???
Unten findet ihr meinen Programmtext.
Vielen Dank für eure HIlfe!

.include "m8535def.inc"

.def temp = R16
.def zeichen = r17
.def wahl = r18

.equ F_CPU = 4000000                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille 
Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit 
zu hoch!"
.endif

    ; Stackpointer initialisieren

    ldi     temp, LOW(RAMEND)
    out     SPL, temp
    ldi     temp, HIGH(RAMEND)
    out     SPH, temp

    ; Port B = Ausgang

    ldi     temp, 0xFF
    out     DDRB, temp

    ; Baudrate einstellen

    ldi     temp, HIGH(UBRR_VAL)
    out     UBRRH, temp
    ldi     temp, LOW(UBRR_VAL)
    out     UBRRL, temp

receive_loop:

    ; Empfang

    ldi     temp, (1<<URSEL)|(3<<UCSZ0)
    out     UCSRC, temp

    sbi     UCSRB, RXEN                     ; RX (Empfang) aktivieren

   sbis     UCSRA, RXC                      ; warten bis ein Byte 
angekommen ist
   rjmp     receive_loop
   in       temp, UDR                       ; empfangenes Byte nach temp 
kopieren
   out      PORTB, temp                     ; und an Port B ausgeben.




    ; Senden

    ldi     temp, (1<<URSEL)|(3<<UCSZ0)
    out     UCSRC, temp

    sbi     UCSRB,TXEN                 ; TX aktivieren


    cpi     temp, 0b00000001         ; vergleiche r17 mit der Konstante 
1
    brne    nicht_gleich    ; wenn nicht gleich, dann mach bei 
nicht_gleich weiter



    ldi     zeichen, 'E'
    rcall   serout                      ; Unterprogramm aufrufen
    ldi     zeichen, 'i'
    rcall   serout                      ; Unterprogramm aufrufen
    ldi     zeichen, 'n'
    rcall   serout                      ; ...
    ldi     zeichen, 10
    rcall   serout
    ldi     zeichen, 13
    rcall   serout
    rjmp    receive_loop



nicht_gleich:


    ldi     zeichen, 'A'
    rcall   serout                      ; Unterprogramm aufrufen
    ldi     zeichen, 'u'
    rcall   serout                      ; Unterprogramm aufrufen
    ldi     zeichen, 's'
    rcall   serout                      ; ...
    ldi     zeichen, 10
    rcall   serout
    ldi     zeichen, 13
    rcall   serout
    rjmp    receive_loop


serout:
    sbis    UCSRA,UDRE                  ; Warten bis UDR für das nächste
                                        ; Byte bereit ist
    rjmp    serout
    out     UDR, zeichen
    ret
Gast #901452
Lesenswert?
• ▲
▼
Hi

Was sendest du als 1 bzw 0? Binär oder als ASCII-Zeichen. Die 
ASCII-Codes für 0 und 1 sind $30 bzw $31. Wahrscheinlich müsste dein 
Vergleich

cpi     temp, 0b00110001 ; $31

heißen.

MfG Spess
Gast #901508
Lesenswert?
• ▲
▼
Ja und: was kommt denn am Port B raus?
Da liegt das komplette empfangene Zeichen an.
Und das wird '1' sein, und zwar ASCII-'1', nicht binär 00000001!

Aber das eigentliche Problem ist:
Hast du eigentlich nur eine Variable für alles?
Muss temp alles machen?
:
:
   in       ###temp, UDR               ; empfangenes Byte nach temp
   out      PORTB, ###temp             ; und an Port B ausgeben.

   ldi     ###temp, (1<<URSEL)|(3<<UCSZ0)
   out     UCSRC, ###temp
   sbi     UCSRB,TXEN                  ; TX aktivieren

   cpi     ###temp, 0b00000001         ; vergleiche r17 mit der 
Konstante
:
:
Bis du die Abfrage machst, hat temp (wie sein Name schon andeutet)
das empfangene Zeichen längst vergessen!!
Gast #901515
Lesenswert?
• ▲
▼
Und vergleich doch vor dem AUS-Schalten,
ob es auch tatsächlich eine '0' ist,
die da anstelle der '1' gekommen ist.

Evtl. könnte es ja auch ein LF oder CR oder sonstwas gewesen sein ;-)

Deine Annahme ist
'1' = EIN
alles andere = AUS

Und schon wenn du nur 1, und dann Enter eingibst
in deinem Hyperdriveterminal, dann kommen da 3 Zeichen
über die serielle Schnitte!

Also: 1 mal EIN   und   2 mal AUS
Gast #901516
Lesenswert?
• ▲
▼
Hi

Lies dir mal durch was lkmiller geschrieben hat (habe ich glatt 
übersehen).

Du überschreibst mit den Befehlen nach 'out PortB...' den Inhalt von 
temp.
Lass das Geraffel mit den 'temp...'. Nimm die Registerbezeichnungen. Da 
weisst du wenigstens was du machst.

MfG Spess

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