logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8] Timer0 nie generuje przerwania

dondu 16 Lis 2010 07:46 4236 13
  • #1 8749730
    dondu
    Moderator na urlopie...
    Nie wiem dlaczego Timer0 nie generuje przerwania przepełnienia licznika.
    Zegar 12MHz
    Preskaler 1024
    Każde przerwanie zmienia bit głośnika na przeciwny (XOR) czyli częstotliwość dźwięku to częstotliwość przerwań podzielona przez 2.
    Głośnik ma zakres od 20Hz - 20kHz

    Częstotliwość oczekiwana: f = 12MHz / 1024 / 2 = 5860Hz

    Dźwięk się nie pojawia niezależnie od ustawienia preskalera na jeden z 5 trybów.
    Gdzieś robię prosty błąd, ale chyba się zablokowałem z myśleniem :)

    
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    
    
    
    
    ISR(TIMER0_OVF_vect){ 	// przerwanie INT0 po przepełnieniu TIMER0
    
    	PORTB ^= (1<<PB0);
    
    }
    
    
    
    
    int main(void){
    
    
    		// włącz przerwania 
    		TIMSK = 1<<TOIE0; 					//zezwolenie na przerwania od TC0
    		TCCR0 = (1<<CS02) | (1<<CS00); 		//preskaler XTAL/1024,
    		sei();
    
    		//ustaw pin dźwięku
    		DDRB |= (1<<PB0);
    			
    
     		// --- PĘTLA GŁÓWNA ----------------------------------------------------------------------- //
    
              for(;;) {	
    
              }
              return(0);
    }
    
  • Pomocny post
    #2 8750208
    ginar
    Poziom 21  
    na pierwszy rzut oka wygląda ok..
    jedynie co przychodzi na myśl ingerencja kompilatora który zoptymalizował funkcję. Sprawdź może czy program dochodzi za pętle for(;; ) (może daj mu cos tam do roboty).
    TIMSK = 1<<TOIE0;   
    lepiej
    TIMSK| = 1<<TOIE0;   

    Sprzwdź (np. na diodzie ) czy wchodzi w przerwanie..
  • Pomocny post
    #3 8750215
    Andrzej__S
    Poziom 28  
    dondu napisał:

    Częstotliwość oczekiwana: f = 12MHz / 1024 / 2 = 5860Hz

    Częstotliwość oczekiwana: f = 12MHz / 1024 / 256 / 2 = ~22Hz (gdzie 256 to wartość przepełnienia licznika)
  • #4 8750248
    dondu
    Moderator na urlopie...
    Andrzej__S napisał:
    Częstotliwość oczekiwana: f = 12MHz / 1024 / 256 / 2 = ~22Hz (gdzie 256 to wartość przepełnienia licznika)

    Faktycznie, się ale tak jak pisałem wcześniej nie ma znaczenia jaki preskaler ustawię także nie działa.


    ginar napisał:
    jedynie co przychodzi na myśl ingerencja kompilatora który zoptymalizował funkcję. Sprawdź może czy program dochodzi za pętle for(;; ) (może daj mu cos tam do roboty).

    Także próbowałem wcześniej wstawić w pętli powiększanie zmiennej w pamięci i nawet wyłączyłem optymalizaję i nic to nie dało.

    Z diody wynika, że wchodzi w przerwanie tylko raz.
  • Pomocny post
    #5 8750312
    ginar
    Poziom 21  
    spróbuj skasować flagę na końcu przerwania (chociaż powinna być kasowana sprz.)
    TIFR|=1<<TOV0;
  • Pomocny post
    #7 8750593
    michalko12
    Specjalista - Mikrokontrolery
    Nawigator napisał:
    A może by tak:
          //ustaw pin dźwięku 
          PINB |= (1<<PB0); 
    


    N.


    W ATmega8 ta opcja nie działa.

    Dodano po 4 [minuty]:


    a nie?


    chiciaz nie powinno to mieć znaczenia...
  • #8 8751302
    dondu
    Moderator na urlopie...
    A więc jednak to sprawka kompilatora. Usuwa pętlę niezależnie od trybu optymalizacji lub jej braku.

    
    +00000000:   940C0046    JMP       0x00000046     Jump
    +00000002:   940C0065    JMP       0x00000065     Jump
    +00000004:   940C0065    JMP       0x00000065     Jump
    +00000006:   940C0065    JMP       0x00000065     Jump
    +00000008:   940C0065    JMP       0x00000065     Jump
    +0000000A:   940C0065    JMP       0x00000065     Jump
    +0000000C:   940C0065    JMP       0x00000065     Jump
    +0000000E:   940C0065    JMP       0x00000065     Jump
    +00000010:   940C0065    JMP       0x00000065     Jump
    +00000012:   940C0065    JMP       0x00000065     Jump
    +00000014:   940C0065    JMP       0x00000065     Jump
    +00000016:   940C0065    JMP       0x00000065     Jump
    +00000018:   940C0065    JMP       0x00000065     Jump
    +0000001A:   940C0065    JMP       0x00000065     Jump
    +0000001C:   940C0065    JMP       0x00000065     Jump
    +0000001E:   940C0065    JMP       0x00000065     Jump
    +00000020:   940C0067    JMP       0x00000067     Jump
    +00000022:   940C0065    JMP       0x00000065     Jump
    +00000024:   940C0065    JMP       0x00000065     Jump
    +00000026:   940C0065    JMP       0x00000065     Jump
    +00000028:   940C0065    JMP       0x00000065     Jump
    +0000002A:   940C0065    JMP       0x00000065     Jump
    +0000002C:   940C0065    JMP       0x00000065     Jump
    +0000002E:   940C0065    JMP       0x00000065     Jump
    +00000030:   940C0065    JMP       0x00000065     Jump
    +00000032:   940C0065    JMP       0x00000065     Jump
    +00000034:   940C0065    JMP       0x00000065     Jump
    +00000036:   940C0065    JMP       0x00000065     Jump
    +00000038:   940C0065    JMP       0x00000065     Jump
    +0000003A:   940C0065    JMP       0x00000065     Jump
    +0000003C:   940C0065    JMP       0x00000065     Jump
    +0000003E:   940C0065    JMP       0x00000065     Jump
    +00000040:   940C0065    JMP       0x00000065     Jump
    +00000042:   940C0065    JMP       0x00000065     Jump
    +00000044:   940C0065    JMP       0x00000065     Jump
    +00000046:   2411        CLR       R1             Clear Register
    +00000047:   BE1F        OUT       0x3F,R1        Out to I/O location
    +00000048:   EFCF        SER       R28            Set Register
    +00000049:   E1D0        LDI       R29,0x10       Load immediate
    +0000004A:   BFDE        OUT       0x3E,R29       Out to I/O location
    +0000004B:   BFCD        OUT       0x3D,R28       Out to I/O location
    +0000004C:   E011        LDI       R17,0x01       Load immediate
    +0000004D:   E0A0        LDI       R26,0x00       Load immediate
    +0000004E:   E0B1        LDI       R27,0x01       Load immediate
    +0000004F:   E0E4        LDI       R30,0x04       Load immediate
    +00000050:   E0F1        LDI       R31,0x01       Load immediate
    +00000051:   E000        LDI       R16,0x00       Load immediate
    +00000052:   BF0B        OUT       0x3B,R16       Out to I/O location
    +00000053:   C002        RJMP      PC+0x0003      Relative jump
    +00000054:   9007        ELPM      R0,Z+          Extended load program memory and postincrement
    +00000055:   920D        ST        X+,R0          Store indirect and postincrement
    +00000056:   30A0        CPI       R26,0x00       Compare with immediate
    +00000057:   07B1        CPC       R27,R17        Compare with carry
    +00000058:   F7D9        BRNE      PC-0x04        Branch if not equal
    +00000059:   E011        LDI       R17,0x01       Load immediate
    +0000005A:   E0A0        LDI       R26,0x00       Load immediate
    +0000005B:   E0B1        LDI       R27,0x01       Load immediate
    +0000005C:   C001        RJMP      PC+0x0002      Relative jump
    +0000005D:   921D        ST        X+,R1          Store indirect and postincrement
    +0000005E:   30A1        CPI       R26,0x01       Compare with immediate
    +0000005F:   07B1        CPC       R27,R17        Compare with carry
    +00000060:   F7E1        BRNE      PC-0x03        Branch if not equal
    +00000061:   940E0079    CALL      0x00000079     Call subroutine
    +00000063:   940C0080    JMP       0x00000080     Jump
    +00000065:   940C0000    JMP       0x00000000     Jump
    @00000067: __vector_16
    ---- D2D2_main.c ----------------------------------------------------------------------------------
    7:        ISR(TIMER0_OVF_vect){ 	// przerwanie INT0 po przepełnieniu TIMER0
    +00000067:   921F        PUSH      R1             Push register on stack
    +00000068:   920F        PUSH      R0             Push register on stack
    +00000069:   B60F        IN        R0,0x3F        In from I/O location
    +0000006A:   920F        PUSH      R0             Push register on stack
    +0000006B:   2411        CLR       R1             Clear Register
    +0000006C:   938F        PUSH      R24            Push register on stack
    +0000006D:   939F        PUSH      R25            Push register on stack
    9:        	PORTB ^= (1<<PB0);
    +0000006E:   B388        IN        R24,0x18       In from I/O location
    +0000006F:   E091        LDI       R25,0x01       Load immediate
    +00000070:   2789        EOR       R24,R25        Exclusive OR
    +00000071:   BB88        OUT       0x18,R24       Out to I/O location
    12:       }
    +00000072:   919F        POP       R25            Pop register from stack
    +00000073:   918F        POP       R24            Pop register from stack
    +00000074:   900F        POP       R0             Pop register from stack
    +00000075:   BE0F        OUT       0x3F,R0        Out to I/O location
    +00000076:   900F        POP       R0             Pop register from stack
    +00000077:   901F        POP       R1             Pop register from stack
    +00000078:   9518        RETI                     Interrupt return
    @00000079: main
    21:       		TIMSK = 1<<TOIE0; 					//zezwolenie na przerwania od TC0
    +00000079:   E081        LDI       R24,0x01       Load immediate
    +0000007A:   BF87        OUT       0x37,R24       Out to I/O location
    22:       		TCCR0 = (1<<CS02) | (1<<CS00); 		//preskaler XTAL/1024,
    +0000007B:   E085        LDI       R24,0x05       Load immediate
    +0000007C:   BF83        OUT       0x33,R24       Out to I/O location
    23:       		sei();
    +0000007D:   9478        SEI                      Global Interrupt Enable
    26:       		DDRB |= (1<<PB0);
    +0000007E:   9AB8        SBI       0x17,0         Set bit in I/O register
    +0000007F:   CFFF        RJMP      PC-0x0000      Relative jump
    26:       		DDRB |= (1<<PB0);
    +00000080:   94F8        CLI                      Global Interrupt Disable
    +00000081:   CFFF        RJMP      PC-0x0000      Relative jump
    




    I nie wiem co mam z tym począć - jaki rozkaz dać do pętli by pętlę dołączył?
    Próbowałem różnych a nawet coś takiego:


    
              for(;;) {	
    		  		
    				zmienna++;
    				if(zmienna >200) zmienna = 0;
              }
    
  • Pomocny post
    #9 8751326
    michalko12
    Specjalista - Mikrokontrolery
    No a co to jest jak nie pętla for(;;); ?
    +0000007F:   CFFF        RJMP      PC-0x0000      Relative jump
  • #10 8751345
    dondu
    Moderator na urlopie...
    Słusznie :) ... za szybki wniosek.
    Czyli nadal nie działa przerwanie. i już wiem dlaczego : CLI !!!

    2 ostatnie linijki:
    
    +00000080:   94F8        CLI                      Global Interrupt Disable 
    +00000081:   CFFF        RJMP      PC-0x0000      Relative jump 
    


    Tylko ja go w kodzie nie mam.
  • Pomocny post
    #11 8751361
    michalko12
    Specjalista - Mikrokontrolery
    CLI ma tam być, to jest część returna.

    BOOTRST <- a co z tym? i innymi fusebitami jak np WDTON?
  • #12 8751377
    dondu
    Moderator na urlopie...
    michalko12 napisał:
    BOOTRST <- a co z tym? i innymi fusebitami jak np WDTON?

    W Pony Prog nie zaznaczony, pozostałe także nie z wyjątkiem SPIEN.



    michalko12 napisał:
    CLI ma tam być, to jest część returna.

    Faktycznie debuger nie dochodzi do tego rozkazu, więc problem nadal nie rozwiązany.
  • Pomocny post
    #13 8751465
    michalko12
    Specjalista - Mikrokontrolery
    Cos mi wektor przerwania nie pasuje, dobry typ procesora masz ustawiony w projekcie?
  • #14 8751490
    dondu
    Moderator na urlopie...
    michalko12 napisał:
    Cos mi wektor przerwania nie pasuje, dobry typ procesora masz ustawiony w projekcie?

    Trafiony zatopiony!
    Jak się człowiek spieszy to się diabeł cieszy i ogonem zakrywa:)

    Chciałem szybko sprawdzić parę drobnych algorytmów i zrobiłem nowy projekt zapominając o ustawieniu procesora.

    Teraz wszystko ok. Następna lekcja za mną.

    WIELKIE DZIĘKI!
REKLAMA