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

atmega8 - przerwania od timer0 i timer1 nie działają razem

abancer 28 Lis 2009 21:33 2579 2
REKLAMA
  • #1 7320861
    abancer
    Poziom 12  
    Mam taki problem: chcę w programie wykorzystywać przerwania od przepełnienia dwóch timerów (0 i 1). W timer0 mam obsługę wyśw. LED i opóźnienie dla klawiatury a w timer1, z założenia wywoływanym co 100ms, coś jakby zegar z minutami i sekundami, choć nie jest to najważniejsze bo to program testowy. Problem w tym, że przerwanie od timer1 wcale się nie wywołuje. Próbowałem włączać obsługę przerwań (sei()) na początku każdego przerwania ale to nic nie daje. Czuje, że błąd jest kretyński, ale takie najciężej mi znaleźć.

    A oto kod programu:
    #include <io.h>
    #include <iom8.h>
    #include <interrupt.h>
    #include <util/delay.h>
    
    #define		D0		0xC0
    #define		D1		0xF9
    #define		D2		0xA4
    #define		D3		0xB0
    #define		D4		0x99	
    #define		D5		0x92
    #define		D6		0x82
    #define		D7		0xF8
    #define		D8		0x80
    #define 	D9		0x90
    #define		DA		0x88	
    #define		DB		0x83
    #define		DC		0xC6
    #define		DD		0xA1
    #define		DE		0x86
    #define 	DF		0x8E
    #define		S_st	0x9C
    #define		S_C		0xC6
    
    #define		D_t		0x07
    #define		D_c		0x27
    
    #define 	SEG_PORT		PORTB
    #define		SEG_PORT_DDR	DDRB
    
    #define		DISP_PORT		PORTD
    #define		DISP_PORT_DDR	DDRD
    
    unsigned char volatile digit_array[16];   	//tablica znakow
    
    unsigned char volatile digit_reg[4];				//przechowuje cyfry dla poszczególnych wyswietlaczy
    
    unsigned char volatile disp_n = 0;			//numer aktualnie aktywnego wyswietlacza
    
    unsigned char volatile button_delay = 0;		//licznik wywolan przerwania
    
    unsigned char volatile temperature = 0;
    
    unsigned char volatile lpb = 0;				//ostatnio wcisniety przycisk
    
    unsigned char volatile state_reg = 0;		//rejestr stanu urzadzenia
    
    unsigned char volatile min_reg = 38;
    unsigned char volatile sec_reg = 25;                                                                                                                            
    
    
    
    
    
    ISR(SIG_OVERFLOW1)
    {
    	TCNT1 = 0xF3CB;
    
    	if(sec_reg == 0)
    	{
    		sec_reg = 59;
    		min_reg--;
    	}
    	else
    	{
    		sec_reg--;
    	}
    }
    
    
    ISR(SIG_OVERFLOW0)
    {
      	TCNT0 = 0xDF;        			// przeladuj timer 2
    
    	if(button_delay > 0)
    		button_delay--;
    
    	SEG_PORT = digit_reg[disp_n];
    	DISP_PORT |= (255 - (1 << disp_n));
    	DISP_PORT &= (255 - (1 << disp_n));
    	disp_n ++;
    	if(disp_n > 3)
    		disp_n = 0;
    
    }
    
    
    
    int main()
    {
    	digit_array[0] = D0;
    	digit_array[1] = D1;
    	digit_array[2] = D2;
    	digit_array[3] = D3;
    	digit_array[4] = D4;
    	digit_array[5] = D5;
    	digit_array[6] = D6;
    	digit_array[7] = D7;
    	digit_array[8] = D8;
    	digit_array[9] = D9;
    	digit_array[10] = DA;
    	digit_array[11] = DB;
    	digit_array[12] = DC;
    	digit_array[13] = DD;
    	digit_array[14] = DE;
    	digit_array[15] = DF;
    
    	
    	
    	SEG_PORT_DDR = 0xFF;
    	DISP_PORT_DDR = 0x0F;
    	DISP_PORT = 0xF0;
    
    
    
    	
    	TIMSK = _BV(TOIE1);        				// wlacz obsluge przerwan T/C1
    	TIMSK = _BV(TOIE0);						//jw dla T/C2
      	TCNT1 = 0xF3CB;         				// wartosc poczatkowa T/C1
    	TCNT0 = 0xFA;	
    	TCCR1A = 0x00;						
      	TCCR1B = _BV(CS12);						//ustawienie preskalera dla TC1 na clk/256
    	TCCR0 = _BV(CS20)|_BV(CS22);  //ustawienie preskalera dla TC2 na clk/1024
    	
      	sei();                					// wlacz obsluge przerwan
      	while(1)
    	{
    		if(button_delay == 0)
    		{
    			if((PIND & 0x80) == 0)
    			{
    				button_delay = 150;
    				lpb = 0x80;
    			}
    
    			if((PIND & 0x40) == 0)
    			{
    				button_delay = 150;
    				lpb = 0x40;
    			}
    
    			if((PIND & 0x20) == 0)
    			{
    				button_delay = 150;
    				lpb = 0x20;
    			}
    
    			if((PIND & 0x10) == 0)
    			{
    				button_delay = 150;
    				lpb = 0x10;
    			}
    
    		}
    		if((PIND & lpb))
    		{
    			button_delay = 14;
    			lpb = 0;
    		}
    
    
    			digit_reg[0] = digit_array[sec_reg - ((sec_reg/10)*10)];
    			digit_reg[1] = digit_array[sec_reg/10];
    			digit_reg[2] = digit_array[min_reg - ((min_reg/10)*10)];
    			digit_reg[3] = digit_array[min_reg/10];
    
    	}
    
    	return 0;
    }
    

    Część kodu w tym programie teraz nic nie robi ale tak jak pisałem to tylko test i problem jest z przerwaniem od timer0.
    Proszę o pomoc.
  • REKLAMA
  • Pomocny post
    #2 7320901
    michalko12
    Specjalista - Mikrokontrolery
    No jest kretyński :)
     TIMSK = _BV(TOIE1);                    // wlacz obsluge przerwan T/C1
    TIMSK = _BV(TOIE0);                  //jw dla T/C2 


     TIMSK = _BV(TOIE1) ;                    // wlacz obsluge przerwan T/C1
    TIMSK |= _BV(TOIE0);                  //jw dla T/C2


    albo

    TIMSK = _BV(TOIE1) | _BV(TOIE0) ;

    ;)
  • #3 7321144
    abancer
    Poziom 12  
    :oops:
    Nic nie napisze, bo to co napisałem powinno wylądować w koszu.
    Wielkie dzięki. Osiem godzin poszło się ...... .
REKLAMA