www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu meinem Program


Autor: Marc Rie (planet-rieke)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marc Rie (planet-rieke)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Also dann ist 1 auf jeden fall nicht 0b00000001.

Teste mal: cpi     temp, '1'

MfG Spess

Autor: Marc Rie (planet-rieke)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!

Autor: Marc Rie (planet-rieke)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marc Rie (planet-rieke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke... Jetzt klappt alles super!!!
Vielen Dank!
Gruß
-Marc

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.