Programm bleibt stehen

Gast #3026399
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
Gast #3026427
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.
Gast #3026902
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.
Gast #3026907
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.
#3026913
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
Gast #3026982
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.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.