Forum: Mikrocontroller und Digitale Elektronik Programm bleibt stehen


von Tim (Gast)


Lesenswert?

Hy,

hoffe man hält mich nicht für bekl...
habe ein ganz einfaches Prgramm für einen Attiny 2313 geschrieben, das 
signal von 2 eingängen soll ausgewertet werden, und dann auf 4 led´s 
ausgegeben werden.

Das ist der quellcode (mit SiSy erstellt):

begin:
    rjmp    main                ; RESET External Reset, Power-on Reset
    reti                        ; INT0 External Interrupt Request 0
    reti                        ; INT1 External Interrupt Request 1
    reti                        ; TIMER1 CAPT Timer/Counter1 Capture
    reti                        ; TIMER1 COMPA Timer/Counter1 Compare
    reti                        ; TIMER1 OVF Timer/Counter1 Overflow
    reti                        ; TIMER0 OVF Timer/Counter0 Overflow
    reti                        ; USART, RX USART, Rx Complete
    reti                        ; USART, UDRE USART Data Register Empty
    reti                        ; USART, TX USART, Tx Complete
    reti                        ; ANA COMP Analog Comparator
    reti                        ; PCINT
    reti                        ; TIMER1 COMPB
    reti                        ; TIMER0 COMPA
    reti                        ; TIMER0 COMPB
    reti                        ; USI START USI Start Condition
    reti                        ; USI OVERFLOW USI Overflow
    reti                        ; EEPROM Ready
    reti                        ; WDT OVERFLOW Watchdog Timer Overflow
;----------------------------------------------------------------------- 
-------
main:
    ldi r16,lo8(RAMEND)         ; Main program start
    out SPL,r16                 ; Set Stack Pointer to top of RAM



    sbi DDRB,0                          ;out Port B.0
    sbi DDRB,1                          ;out Port B.1
    sbi DDRB,2                          ;out Port B.2
    sbi DDRB,3                          ;out Port B.3
    cbi DDRB,6                          ;IN Port B.6

    cbi DDRB,7                          ;IN Port B.7


;----------------------------------------------------------------------- 
-------
mainloop:
    in r16, PINB                        ;lade Port B in r16
    ror r16                             ;schiebe r16 nach rechts
    ror r16                             ;schiebe r16 nach rechts
    ror r16                             ;schiebe r16 nach rechts
    ror r16                             ;schiebe r16 nach rechts
    ror r16                             ;schiebe r16 nach rechts
    ror r16                             ;schiebe r16 nach rechts

    cpi r16, 1                          ;vergleiche r16 = 1
    breq LED1                           ;springe zu "LED1" wenn r16 = 1
    cpi r16, 0                          ;vergleiche r16 = 0
    breq LED2                           ;springe zu "LED2" wenn r16 = 0
    cpi r16, 3                          ;vergleiche r16 = 3
    breq LED3                           ;springe zu "LED3" wenn r16 = 3
    cpi r16, 2                          ;vergleiche r16 = 2
    breq LED4                           ;springe zu "LED4" wenn r16 = 2

    rjmp mainloop


;----------------------------------------------------------------------- 
-------
LED1:
    sbi PORTB, 0                        ;LED1 = on
    cbi PORTB, 1                        ;LED2 = off
    cbi PORTB, 2                        ;LED3 = off
    cbi PORTB, 3                        ;LED4 = off
    rjmp mainloop                       ;zurück zu "mainloop"

;----------------------------------------------------------------------- 
-------
LED2:
    sbi PORTB, 0                        ;LED1 = on
    sbi PORTB, 1                        ;LED2 = on
    cbi PORTB, 2                        ;LED3 = off
    cbi PORTB, 3                        ;LED4 = off
    rjmp mainloop                       ;zurück zu "mainloop"

;----------------------------------------------------------------------- 
-------
LED3:
    sbi PORTB, 0                        ;LED1 = on
    sbi PORTB, 1                        ;LED2 = on
    sbi PORTB, 2                        ;LED3 = on
    cbi PORTB, 3                        ;LED4 = off
    rjmp mainloop                       ;zurück zu "mainloop"

;----------------------------------------------------------------------- 
-------
LED4:
    sbi PORTB, 0                        ;LED1 = on
    sbi PORTB, 1                        ;LED2 = on
    sbi PORTB, 2                        ;LED3 = on
    sbi PORTB, 3                        ;LED4 = on
    rjmp mainloop                       ;zurück zu "mainloop"

;----------------------------------------------------------------------- 
------

das Ganze wird aber nur ein mal durchgelaufen, wenn sich das signal am 
eingang ändert passiert nichts.
erst wenn ich die Betriebsspannung kurz unterbreche, werden die LED´s 
"aktuallisiert"
kann mir aber nicht erklären warum :-(

MfG
Tim

von amateur (Gast)


Lesenswert?

Versuchs mal mit LSR R16

von amateur (Gast)


Lesenswert?

Alternativ kannst Du Dir das ganze geschubse auch sparen indem Du:

ANDI R16,192 ; 11000000
CPI  R16,64  ; 01000000
BREQ LED1
CPI  R16,0   ; 00000000
BREQ LED2
CPI  R16,192 ; 11000000
BREQ LED3
CPI  R16,128 ; 10000000
BREQ LED4

verwendest.

von Klaus D. (kolisson)


Lesenswert?

genau das wollte ich auch schreiben...
bin zwar nicht wirklich assebmlerfest aber ich hätte durchaus ein 
Problem
in dem ROR (Rotieren)  gesehen. Ein wahres Shift wird besser sein, da 
dann die anschliessenden Bedingungen auch erfüllt werden können.

Gruss k.

von Tim (Gast)


Lesenswert?

Danke, jetzt geht es.:-)

aber theoretisch hätte es doch mit dem rotieren auch funktionieren 
müssen, oder?

euch allen ein schönes WE noch.


mFg
Tim

von Floh (Gast)


Lesenswert?

Tim schrieb:
> aber theoretisch hätte es doch mit dem rotieren auch funktionieren
>
> müssen, oder?

Nein. Ein Rotieren füllt dir das Register wieder mit den ausgeschobenen 
Daten (durch das Carrybit).
Daher musst du deine geschobenen Daten trotzdem maskieren, bevor du sie 
vergleichst.

von Hmm (Gast)


Lesenswert?

>aber theoretisch hätte es doch mit dem rotieren auch funktionieren
>müssen, oder?
Ja und? Was nützt die Theorie nach der es gehen sollte, wenn sie nicht 
funktioniert?

Guck Dir doch mal den Unterschied zwischen LSR und ROR an.

von Peter D. (peda)


Lesenswert?

Tim schrieb:
> aber theoretisch hätte es doch mit dem rotieren auch funktionieren
> müssen, oder?

Nein, das ROR ist hier absoluter Unsinn. Es schiebt nämlich das Carry 
mit rein und das ist wohl durch andere Pins gesetzt.

Nimm das LSR, das schiebt 0-Bits rein.
Oder maskieren nach dem Schieben die nicht benötigten Bits aus:
andi r1, 0x03

von amateur (Gast)


Lesenswert?

@Tim

Beim Schieben oder Rotieren ist immer die Überlegung: "Was schiebe ich 
rein".

>aber theoretisch hätte es doch mit dem rotieren auch funktionieren
>müssen, oder?

Die Antwort hierauf ist ein klares Jein.

6 Mal ror r16
und einmal
andi r16,3

hätten Dich auch glücklich gemacht.

L=LED; C=Carry; I=Input

PINB = II??LLLL
6 X ROR
LLLL?CII  ; Ist nur beim ersten Mal 000000II

Nur weil Deine LEDs beim Start=0 waren hat die erste Abfrage etwas 
ergeben.
Nur solange alle LEDs aus sind ist LLLL=0000. Auch Dein Carry-Bit ist 
nach einer positiver Abfrage gesetzt und wird "reinrotiert".

Solche Fehler sind später sehr schwer zu finden da von "außen" kein 
System erkennbar ist.

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.