Forum: Mikrocontroller und Digitale Elektronik Frage zu meinem Program


von Marc R. (planet-rieke)


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

von Spess53 (Gast)


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

von Marc R. (planet-rieke)


Lesenswert?

Hallo,
danke für die Antwort.
Hab das probiert aber es passiert immer noch das gleiche wie vorher...
Zu deiner ersten Frage: Gut frage. Ich schreibe eine 1 in einen 
TextEditor und schicke das ganze per Hyper Terminal zum AVR.

von Spess53 (Gast)


Lesenswert?

Hi

Also dann ist 1 auf jeden fall nicht 0b00000001.

Teste mal: cpi     temp, '1'

MfG Spess

von Marc R. (planet-rieke)


Lesenswert?

oh ok. Also ich hab gemerkt, dass ich in der TextEditor-Datei für Ein 
gleich 6 Einsen stehen hatte. Deswegen auch das 6x Aus. Es klappt nur 
immer noch nicht 100%ig, weil er mir egal ob ich eine 1 oder eine0 
schicke, immer ein "Aus" anzeigt.
Danke für eure Hilfe!

von Spess53 (Gast)


Lesenswert?

Hi

Was für ein Bitmuster hast du an PortB. Evtl. mal Leds dranhängen. Und 
was für ein Board benutzt du?

MfG Spess

von lkmiller (Gast)


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!!

von Marc R. (planet-rieke)


Lesenswert?

Hallo,

ich benutz den ATmega8535. Board hab ich selber zusammengebaut und so.
Der Transistor, über den der Motor angeschlossen ist, habe ich mit PB0 
verbunden.

Danke
-marc

von lkmiller (Gast)


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

von Spess53 (Gast)


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

von lkmiller (Gast)


Lesenswert?

Das Ein- und Aus-Schalten des Motors geht nur, weil das unterste Bit 
gerade mal die '1' und die '0' durchreicht.

Stichwort für Google: ASCII-Tabelle

von Marc R. (planet-rieke)


Lesenswert?

Danke... Jetzt klappt alles super!!!
Vielen Dank!
Gruß
-Marc

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.