Problem z przerwaniami

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
zeroberto1980
-
Posty: 1
Rejestracja: 26 sty 2009, 22:55
Lokalizacja: Białystok

Problem z przerwaniami

Post autor: zeroberto1980 » 27 maja 2009, 18:55

Napisałem program odmierzający czas z budzkiem. Program nie działa prawidłowo. Jak sądze spowodowane jest to nieprawidłową obsługą przerwań. Powiedzcie co robię źle

Kod: Zaznacz cały

// Zegar cyfrowy
// S1- ustawia godziny S2- ustawia minuty


#include <avr\io.h>
#include <inttypes.h>
#include <avr\interrupt.h>
#include <avr\pgmspace.h>
#include <avr\signal.h>
#include <avr\delay.h>

#define ledport PORTB
#define ledddr DDRB
#define comport PORTD
#define comddr DDRD

#define LED_A 0
#define LED_B 1
#define LED_C 2
#define LED_D 3
#define LED_E 4
#define LED_F 5
#define LED_G 6
#define LED_DP 7

#define T2 2
#define T3 3
#define T4 4
#define T5 5
#define T6 6 

#define swpin PIND
#define sw1 0
#define sw2 1



volatile uint8_t minuty_budzika=10;
volatile uint8_t godziny_budzika=10;
volatile uint8_t sekundy=0;
volatile uint8_t minuty=12;
volatile uint8_t godziny=21;
uint8_t migaj=0b00000000;
uint8_t alarm=0b00000000;
uint8_t trybustawiania_budzika=0b00;//wył tryb ustawiania budzika
uint8_t wyjscie=0b00;
uint8_t jednostki_minut;
uint8_t dziesiatki_minut;
uint8_t jednostki_godzin;
uint8_t dziesiatki_godzin;
uint8_t czas=200;
uint8_t czas1=20;
uint8_t predkosc1=100;
uint8_t predkosc2=100;
uint8_t czas2=20;
volatile uint8_t powrot;
const czas3=3;
static uint8_t numer_wyswietlacza=0;
uint8_t wlacz_alarm=0b00;
uint8_t blokada=0b00;


prog_uint8_t tablicacyfr[10]=
{
	
	~(1<<LED_A | 1<< LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_F),//0 
	~(1<< LED_B | 1<<LED_C),//1 
	~(1<<LED_A | 1<<LED_B | 1<<LED_G | 1<<LED_E | 1<<LED_D),//2 
	~(1<<LED_A | 1<< LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_G),//3   zmienna tablicowa zapisana w pamięci programu
	~(1<<LED_B | 1<< LED_C | 1<<LED_G | 1<<LED_F),//4	 
	~(1<<LED_A | 1<< LED_F | 1<<LED_G | 1<<LED_C | 1<<LED_D),//5 
	~(1<<LED_A | 1<< LED_F | 1<<LED_E | 1<<LED_D | 1<<LED_C | 1<<LED_G),//6 
	~(1<<LED_A | 1<< LED_B | 1<<LED_C),//7
	~(1<<LED_A | 1<< LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_E | 1<<LED_F | 1<<LED_G),//8 
	~(1<<LED_A | 1<< LED_B | 1<<LED_C | 1<<LED_D | 1<<LED_G | 1<<LED_F),//9 

};




int main (void)
{
ledddr= 255;
comddr=0b1111100;
comport= 1<<sw1 | 1<<sw2 | 1<<T2;
//TCNT1=3036; //62500*16us=1s
//TCNT0=131; //125*16us=2ms(przerwanie co 2ms)
TCCR0 = 1<<CS01 | 1<<CS00;	//config timer0=timer,prescale=64
TCCR1A=0x00; // timer pracuje jako czasomierz
TCCR1B=1<<CS10 | 1<<CS11 ;//config timer1=timer,prescale=64 
TIMSK = 1<<TOIE0;			// odblokowanie przerwania od timera0
//TIMSK= 1<<TOIE1;			// odblokowanie przerwania od timera1
sei();						// globalne odblokowanie przerwań




	for(;;)
	{
		if(TIFR & (1<<7))
		{
				TIMSK = ~1<<TOIE0; //zablokuj przerwanie od timer0
				TIMSK |= _BV(TOIE1);//odblokuj od timera1	
		}
	}
	
return 0;


}




SIGNAL (SIG_OVERFLOW0)
{

TCNT0=131; //125*16us=2ms(przerwanie co 2ms)


	
	
	if((!( swpin & (1<<sw1)))  & (!(swpin & (1<<sw2))))
	{
				alarm^=_BV(7);
				powrot=czas3;
				trybustawiania_budzika=0b01;
				//--czas;
				_delay_ms(200);
		
		
	}
	
	if((swpin & (1<<sw1)) & (swpin & (1<<sw2)))
	{
		czas=200;
	}
	
	
				if(!(swpin & (1<<sw2)))
				{
					--czas2;
					if(czas2==0)
					{				
						if(!(swpin & (1<<sw2)))
						{
							powrot=czas3;
							czas2=predkosc2;
							predkosc2=predkosc2-8;
							if(predkosc2<8)
							{
								predkosc2=8;
							}
	
								if(trybustawiania_budzika & (1<<sw1)) //jeźeli oba wciśnięte klawiszy zegar jest 
								{										//w trybie ustawiania budzika

									++minuty_budzika;
								}
								else
								{
									if(!(blokada & _BV(0)))
									{
										++minuty;
									}
								}
							
						}
					}
				}
				
				
				if(swpin & (1<<sw2))
				{
					czas2=20;
					predkosc2=100;
				}
				
				
				
			
							
							
				if(!(swpin & (1<<sw1)))
				{
					--czas1;
					if(czas1==0)
					{				
						if(!(swpin & (1<<sw1)))
						{
							powrot=czas3;
							czas1=predkosc1;
							predkosc1=predkosc1-8;
							if(predkosc1<8)
							{
								predkosc1=8;
							}
	
								if(trybustawiania_budzika & (1<<sw1)) //jeźeli oba wciśnięte klawiszy zegar jest 
								{										//w trybie ustawiania budzika
									++godziny_budzika;
									
								}
								else
								{
									if(!(blokada & _BV(0)))
									{
										++godziny;
									}
								}
							
						}
					}
				}
				
				if(swpin & (1<<sw1))
				{
					czas1=20;
					predkosc1=100;
				}
				
				
				if(minuty_budzika==60)
				{
					minuty_budzika=0;
					++godziny_budzika;
							
				}
				
				if(godziny_budzika==24)
				{
					godziny_budzika=0;
				}
				
				
				if(sekundy==60)
				{
					sekundy=0;
					++minuty;
				}
					
				if(minuty==60)
				{
					minuty=0;
					++godziny;
				}
					
				if(godziny==24)
				{
					godziny=0;
				}
				
		
					if(blokada & _BV(0))
					{
						if((!(swpin*(1<<sw1))) || (!(swpin*(1<<sw2)))) //dezaktywacja alarmu
						{
							wlacz_alarm=0b00;
						}
					}
				
						
							if(trybustawiania_budzika & (1<<sw1))
							{
								++numer_wyswietlacza;
								if(numer_wyswietlacza==7)
								{
									numer_wyswietlacza=0;
								}
								jednostki_minut=minuty_budzika%10; 
								dziesiatki_minut=minuty_budzika/10;
								jednostki_godzin=godziny_budzika%10;
								dziesiatki_godzin=godziny_budzika/10;
							}
							
							else
							{
								++numer_wyswietlacza;
								if(numer_wyswietlacza==4)
								{
								numer_wyswietlacza=0;
								}
								jednostki_minut=minuty%10;
								dziesiatki_minut=minuty/10;
								jednostki_godzin=godziny%10;
								dziesiatki_godzin=godziny/10;
							}
							
				
                            
							
				comport= 1<<T3 | 1<<T4 | 1<<T5 | 1<<T6; //wygaś wyswietlacze
				
				switch (numer_wyswietlacza)
				{
				
					case 0: ledport=pgm_read_byte(&tablicacyfr[jednostki_minut]);
							comport= ~(1<<T3); //włącz tr T3
							break;
							
					case 1: ledport=pgm_read_byte(&tablicacyfr[dziesiatki_minut]);
							comport= ~(1<<T4); //włącz tr T4
							break;
							
					case 2: ledport=pgm_read_byte(&tablicacyfr[jednostki_godzin]);
							ledport=migaj;
 							 comport= ~(1<<T5); //włącz tr T5
							 break;
					
					case 3: ledport=pgm_read_byte(&tablicacyfr[dziesiatki_godzin]);
							ledport= ~(alarm);
							comport= ~(1<<T6); //włącz tr T6
							break;
							
				}
				
	
		
}

SIGNAL (SIG_OVERFLOW1)

{

TCNT1=3036; //62500*16us=1s

	++sekundy;
	--powrot;
	migaj^=_BV(7);
	
	if(powrot==0)
	{
		trybustawiania_budzika=0b00; //jeżeli żaden klawisz nie wciśnięty po 3sek wyjscie z trybu ustawiania budzika
	}

	if(alarm & (1<<7))
	{
		if((minuty==minuty_budzika) && (godziny=godziny_budzika))
		{
			wlacz_alarm=0b01;
		}
	}
		

	if(wlacz_alarm & (1<<sw1))
	{
		blokada=0b01;
		comport=~1<<T2;
		
	}
	else
	{
		blokada=0b00;
		comport=1<<T2;//wylacz alarm
	}
	
	
	
			TIMSK = ~1<<TOIE1; //zablokuj przerwanie od timer0
			TIMSK |= _BV(TOIE0);//odblokuj od timera17h		
	

}
Edit: Proszę używać znacznika CODE. Ddevil
Ostatnio zmieniony 30 maja 2009, 12:05 przez zeroberto1980, łącznie zmieniany 1 raz.

ODPOWIEDZ