-         

+ Antworten
Ergebnis 1 bis 9 von 9

Thema: Ampelsteuerung, AVR AT90S8535 ,TimerOverflow Interrupt

  1. #1

    Ampelsteuerung, AVR AT90S8535 ,TimerOverflow Interrupt

    Anzeige

    GearBest Black Friday Verbraucherelektronik Promotion
    Hallo,

    hab ein kleines "Problemchen" mit meinen kleinen Programm.
    Es scheint so dass der TimerOverflow Interrupt nie ausgelöst wird und somit auch die Ampelphasen:

    .include "8535def.inc"

    .device AT90S8535

    .def highB =r22 ; extra temps
    .def lowB =r23
    .def temp =r16
    .def cnt =r17
    .def temp2 =r18

    AMPEL_TABELLE:
    .db 0b00000010,0b11111111,0b10110110,0b10110011 ;1.BYTE: AMPEL HAUPTREICHTUNG
    .db 0b10000000,0b11111111,0b01100010,0b11111000 ;2.BYTE: AMPEL FUSSGÄNGER
    .db 0b01000000,0b11111111,0b01100010,0b11111000 ;3.BYTE: COUNTER HIGHBYTE
    .db 0b00010000,0b11111111,0b10001000,0b11100001 ;4.BYTE: COUNTER LOWBYTE
    .db 0b00001000,0b11111111,0b01100010,0b11111000
    .db 0b00000100,0b11111111,0b01100010,0b11111000
    .db 0b00000000,0b00000000,0b00000000,0b00000000


    rjmp RESET ;POWER ON RESET
    reti ; 2 Int0-Interrupt
    reti ; 3 Int1-Interrupt
    reti ; 4 TC2 Compare Match
    reti ; 5 TC2 Overflow
    reti ; 6 TC1 Capture
    reti ; 7 TC1 Compare Match A
    reti ; 8 TC1 Compare Match B
    rjmp OVERFLOW ; 9 TC1 Overflow
    reti ; 10 TC0 Overflow
    reti ; 11 SPI, STC Serial Transfer Complete
    reti ; 12 UART Rx Complete
    reti ; 13 UART Data Register Empty
    reti ; 14 UART Tx complete
    reti ; 15 ADC Conversion Complete
    reti ; 16 EEPROM Ready
    reti ; 17 Analog Comparator
    reti ; 18 TWI (I²C) Serial Interface
    reti ; 19 St

    RESET: ;initialize the machine

    ; stack pointer
    ldi temp, low(RAMEND)
    out SPL, temp
    ldi temp, high(RAMEND)
    out SPH, temp
    ldi temp,0b00000100
    out TIMSK,temp
    ldi temp,0b00111111
    out DDRB,temp
    ldi temp,0b11111111
    out DDRD,temp
    ldi temp,0b00000101
    out TCCR1B,temp
    ldi lowB,0b11111000
    ldi highB,0b11111111
    out TCNT1H,highB
    out TCNT1L,lowB
    sei

    START:

    nop
    rjmp START


    OVERFLOW:

    rcall OHNE_FUSS
    ret

    OHNE_FUSS:

    lpm
    tst R0 ;testet ob die letzte Ampelphase erreicht ist
    breq RESET_AMPEL
    mov temp2,R0
    out PORTB,temp2
    adiw ZL,1
    lpm
    mov temp2,R0
    out PORTD,temp2
    adiw ZL,1
    lpm
    mov temp2,R0
    out TCNT1H,temp2
    adiw ZL,1
    lpm
    mov temp2,R0
    out TCNT1L,temp2
    adiw ZL,1
    ret

    RESET_AMPEL:

    ldi ZH,high(AMPEL_TABELLE*2) ; init Zldi
    ldi ZL,low(AMPEL_TABELLE*2)
    rjmp OHNE_FUSS


    ich hoffe der Code ist einigermaßen verständlich.

    Danke

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    44
    Beiträge
    2.234
    O weh,

    Was ist das für eine ISR ????

    OVERFLOW:

    ist doch Deine ISR oder ?

    1. an welcher Stelle sicherst Du SREG ?
    2. den rcall OHNE_FUSS verstehe ich auch nicht wozu das ganze ?
    3. schön daß Du ret benutzt, aber damit schaltest Du die Interrupts garnicht mehr an.
    Ein reti wäre sinvoller gewesen

    Ich hoffe, daß ich helfen konnte, sonst müßen wir das in ruhe mal durchgehen.

    Gruß Sebastian

    P.S.
    Was ich noch gerade sehe,
    Die .db's gehören nicht am Anfang sondern am Schluß des Programms, sonst fangen sie bei 0x0000 an, wo normalerweise die Vektoren liegen.
    Wenn Du die Tabelle am Anfang schreiben willst mußt Du die Vektoren so definieren :
    Code:
    .org 0x0000
           rjmp reset
    .org INT0addr
           reti
    ...
    ...
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #3
    Zitat Zitat von izaseba
    O weh,

    Was ist das für eine ISR ????

    OVERFLOW:

    ist doch Deine ISR oder ?

    1. an welcher Stelle sicherst Du SREG ?
    2. den rcall OHNE_FUSS verstehe ich auch nicht wozu das ganze ?
    3. schön daß Du ret benutzt, aber damit schaltest Du die Interrupts garnicht mehr an.
    Ein reti wäre sinvoller gewesen

    Ich hoffe, daß ich helfen konnte, sonst müßen wir das in ruhe mal durchgehen.
    Gruß Sebastian
    Danke für deine Antwort , bin erst seit einer Woche an der Thematik dran *g*
    Bitte um ein wenig Nachsicht

    1. Muss ich das Status Register unbedingt sichern ? Wozu genau ?
    2. der rcall in der ISR hat schon seinen Sinn , da kommen noch mehr rcall´s rein. Ist noch nicht ganz komplett das programm.
    3. sorry kleiner Fehler beim abtippen, hab hier reti auch drin stehen.

    Also wird wohl das SREG register schuld sein oder ?


    EDIT: Ohh jee das mit der Tabelle hab ich total verplannt, klar müssen die Interruptvektoren am Anfang stehen *schäm*


    Danke nochmal

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    44
    Beiträge
    2.234
    Bitte um ein wenig Nachsicht
    Kein Problem, jeder hat mal igrendwann angefangen

    Zum SREG, nein Du mußt Ihn nicht unbedingt sichern, wenn Deine Hauptschleife aus loop: rjmp loop besteht und/oder wenn Du in der ISR keine Operationen vornimmst, die den SREG verändern, ist es nicht notwendig SREG zu sichern.
    Ich mache es persönlich immer, weil :
    1. wenn mein Programm mit der Zeit wächst, kann ich es nicht mehr vergessen.
    2. In jedem Programm mache ich irgendwas in der Hauptschleife....

    zu 2.
    Versuche es zu vermeiden rcalls in eine ISR zu benutzen, es geht fast immer anders, rcalls belasten den Stack, machen die ISR langsammer, und Dein Programm unübersichtilicher.
    Setze lieber ein Flag in der ISR und prüfe Ihn in der Hauptschleife.

    zu 3.

    zu EDIT , ich hoffe daß wir damit den Wurm gefunden haben.

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Hallo,

    vielleicht hilft es dir, wenn ich hier mal ein paar allgemeine Tips zur Programmierung von Mikrocontrollern in Assembler gebe.

    Ich nutze dazu einmal deinen Code, um zu zeigen wie es besser geht.

    1. geize nicht mit Kommentaren aber vermeide "sinnfreie" oder selbsterklärende Komentare.

    Beispiel:

    dein Code:
    Code:
    mov temp2,R0
    besser:
    Code:
    mov temp2,R0  ; um dieses oder jenes zu erreichen
    wesentlich schlechter:
    Code:
    mov temp2,R0  ; Inhalt von R0 -> temp2
    2. vermeide wann immer es geht die binäre Schreibweise, da diese meistens ziemlich nichtssagend ist.

    dein Code:
    Code:
    ldi temp,0b00000101
    out TCCR1B,temp
    besser:
    Code:
    ldi temp, (1<<CS12) | (1<<CS10)
    out TCCR1B,temp
    der Vorteil:
    wenn man in einigen Wochen doch noch einmal in den Code schaut, wird es fast auf einen Blick klar, was dort nun in das entsprechende Register wandert (in dem Fall die Prescaler Einstellungen für den Timer Takt).

    3. Sichere wann immer es geht das Statusregister, auch wenn du es im Moment nicht benötigst.

    Der Vorteil: du vergisst es nicht, wenn du doch einmal dein Programm erweiterst und du es dann doch mal brauchst.

    Beispiel:
    Code:
    : ------- irgendwo am Anfang:
    .def sregsave = r3
    
    ; in der ISR
    ISR:
    in sregsave, SREG ; Statusregister sichern
    
    
    out SREG, sregsave
    
    reti
    4. egal was du machst, vermeide lange ISR's (Interupt Service Routinen)

    defakto ist es wesentlich besser und eleganter sich ein eigenes Statusregister zu definieren und anschließend dort ein Bit zu setzen als durch lange ISR's den controller zu blockieren.

    Beispiel:
    Code:
    : ------- irgendwo am Anfang:
    .def status = r17 ; statusregister
                             ; 7             = 
                             ;  6            = 
                             ;   5           = 
                             ;    4          = 
                             ;     3         = 
                             ;      2        = 
                             ;       1       = 
                             ;        0      = Ampel aktuallisieren
    
    ; im Code
    sbrc status, 0 ; ampel aktuallisieren ?
    rcall ampel_update ; -> Ja
    
    ; restlicher Code
    
    
    ampel_update:
    andi status, 0b11111110 ; Ampel aktuallisieren Flag löschen
    
    ; Code
    
    ret
    
    
    
    ; in der ISR
    ISR:
    in sregsave, SREG ; Statusregister sichern
    
    ori status, 0b00000001 ; Ampel aktuallisieren Flag setzen
    
    out SREG, sregsave
    
    reti

    So, ich hoffe dir damit ein klein wenig geholfen zu haben.

    BTW: Der Wurm bei dir liegt nicht an der fehlenden Sicherung des Statusregisters, sondern an der etwas deplazierten Wertetabelle.

    Hier noch einmal ein grober Strukturansatz:

    1. nötiges Include File laden
    2. Aliase für Register definieren
    3. Aliase für speicheradressen definieren
    4. Konstanten definieren
    (danach nen .cseg & .org 0x00)
    5. Interupt Vektoren
    6. Reset Rioutine mit:
    - Stack initialisieren
    - Speicher leeren
    - Peripherie initialisieren (Timer, Ports etc)
    7. Main Loop
    8. Sub Routinen
    9. ISR Routinen
    10. Diverse Datentabellen.


    Grüße,

    da Hanni.

  6. #6
    Zitat Zitat von Hanni
    Hallo,

    vielleicht hilft es dir, wenn ich hier mal ein paar allgemeine Tips zur Programmierung von Mikrocontrollern in Assembler gebe.

    Ich nutze dazu einmal deinen Code, um zu zeigen wie es besser geht.

    1. geize nicht mit Kommentaren aber vermeide "sinnfreie" oder selbsterklärende Komentare.

    Beispiel:

    dein Code:
    Code:
    mov temp2,R0
    besser:
    Code:
    mov temp2,R0  ; um dieses oder jenes zu erreichen
    wesentlich schlechter:
    Code:
    mov temp2,R0  ; Inhalt von R0 -> temp2
    2. vermeide wann immer es geht die binäre Schreibweise, da diese meistens ziemlich nichtssagend ist.

    dein Code:
    Code:
    ldi temp,0b00000101
    out TCCR1B,temp
    besser:
    Code:
    ldi temp, (1<<CS12) | (1<<CS10)
    out TCCR1B,temp
    der Vorteil:
    wenn man in einigen Wochen doch noch einmal in den Code schaut, wird es fast auf einen Blick klar, was dort nun in das entsprechende Register wandert (in dem Fall die Prescaler Einstellungen für den Timer Takt).

    3. Sichere wann immer es geht das Statusregister, auch wenn du es im Moment nicht benötigst.

    Der Vorteil: du vergisst es nicht, wenn du doch einmal dein Programm erweiterst und du es dann doch mal brauchst.

    Beispiel:
    Code:
    : ------- irgendwo am Anfang:
    .def sregsave = r3
    
    ; in der ISR
    ISR:
    in sregsave, SREG ; Statusregister sichern
    
    
    out SREG, sregsave
    
    reti
    4. egal was du machst, vermeide lange ISR's (Interupt Service Routinen)

    defakto ist es wesentlich besser und eleganter sich ein eigenes Statusregister zu definieren und anschließend dort ein Bit zu setzen als durch lange ISR's den controller zu blockieren.

    Beispiel:
    Code:
    : ------- irgendwo am Anfang:
    .def status = r17 ; statusregister
                             ; 7             = 
                             ;  6            = 
                             ;   5           = 
                             ;    4          = 
                             ;     3         = 
                             ;      2        = 
                             ;       1       = 
                             ;        0      = Ampel aktuallisieren
    
    ; im Code
    sbrc status, 0 ; ampel aktuallisieren ?
    rcall ampel_update ; -> Ja
    
    ; restlicher Code
    
    
    ampel_update:
    andi status, 0b11111110 ; Ampel aktuallisieren Flag löschen
    
    ; Code
    
    ret
    
    
    
    ; in der ISR
    ISR:
    in sregsave, SREG ; Statusregister sichern
    
    ori status, 0b00000001 ; Ampel aktuallisieren Flag setzen
    
    out SREG, sregsave
    
    reti

    So, ich hoffe dir damit ein klein wenig geholfen zu haben.

    BTW: Der Wurm bei dir liegt nicht an der fehlenden Sicherung des Statusregisters, sondern an der etwas deplazierten Wertetabelle.

    Hier noch einmal ein grober Strukturansatz:

    1. nötiges Include File laden
    2. Aliase für Register definieren
    3. Aliase für speicheradressen definieren
    4. Konstanten definieren
    (danach nen .cseg & .org 0x00)
    5. Interupt Vektoren
    6. Reset Rioutine mit:
    - Stack initialisieren
    - Speicher leeren
    - Peripherie initialisieren (Timer, Ports etc)
    7. Main Loop
    8. Sub Routinen
    9. ISR Routinen
    10. Diverse Datentabellen.


    Grüße,

    da Hanni.
    SUPER!!! vielen Dank für die Tipps

    mfg

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    44
    Beiträge
    2.234
    Und wenn wir gerade bei den Tipps sind poste ich hiermit einen Link, den ich schon 300 mal gepostet habe, aber ich find Ihn soooooo gut, daß ich Ihn nochmal poste

    Wenn Du nach dieser
    Seite vorgehst, schreibst Du bald sehr gute Programme.
    Es gab hier schonmal Stimmen wie :
    "Das ist blöd, steht nichts zu Mega 32 drin", oder
    "das ist zu schwer"
    naja, die Stimmen haben sich nachhinein Bascom runtergeladen und sind jetzt auch zufrieden.

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Zitat Zitat von gizzi

    SUPER!!! vielen Dank für die Tipps

    mfg
    Kein Problem, ich hab selbst mal von Null angefangen, und es hat ne ganze Weile gedauert, bis ich des Sinn oder Unsinn einer gewissen Struktur verstanden und eingesehen habe.

    Ich übrigen, den Speicher könnte man z.B. wie folgt leeren (auf einen definierten zustand bringen)

    Code:
    			clr			temp							; Clear Mem Routine
    
    			ldi			YH,			high(RAMEND)
    			ldi			YL,			low(RAMEND)
    
    			ldi			ZH,			high(SRAM_START)
    			ldi			ZL,			low(SRAM_START)
    	clr_mem:
    			st			Z+,			temp
    			cp			YL,			ZL
    			cpc			YH,			ZH
    			brne		clr_mem
    
    			st			Z, 	 		 temp
    Vielleicht hilft dir das ja mal weiter.

    @ izaseba:

    Zitat Zitat von izaseba
    Und wenn wir gerade bei den Tipps sind poste ich hiermit einen Link, den ich schon 300 mal gepostet habe, aber ich find Ihn soooooo gut, daß ich Ihn nochmal poste

    Wenn Du nach dieser
    Seite vorgehst, schreibst Du bald sehr gute Programme.
    Sehr schöne Übersicht
    Und ob du es glaubst oder nicht, ich hab sowas in der Art als PDF Datei bei mit aufm Rechner ...
    und ob man es glaubt oder nicht, ich schau immer mal wieder rein ... insbesondere, wenn es um Flags geht (die sich bei diversen Befehlen verändern können)


    Grüße,
    da Hanni

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    44
    Beiträge
    2.234
    Und ob du es glaubst oder nicht,
    Ich glaub es Dir gerne, die Seite ist bei mir ganz oben in der Lesezeichenliste.
    In meinen Augen ist es die beste Seite, zum Thema.

    In diesem Sinne gutes gelingen mit der Ampel !

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

+ Antworten

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •