Witam wszystkich. W końcu wziąłem się za naukę C, tym bardziej, że zakupiłem książkę naszego forumowicza mirka (polecam książkę, lekko napisana i ta po "chłopsku") oraz wpadł mi w ręce zestaw startowy z and-tech EvB 4.3
(bardzo podobny do tego z ATNEL-a). Pierwsze kroki z diodą i wyświetlaczem LCD za mną. Przerwanie i migoczącą diodą także.
Problem mam z konfiguracją przerwania TIMER1
Wiem że kod jest nieco zagmatwany i niepotrzebne są wskaźniki i przerwanie ale właśnie się ich uczyłem i dlatego zastosowałem.
W tym przypadku włączone jest przerwanie, ale jest puste. Wykonywać powinien się tylko główny program zliczający CAX, "przekonwertować" na odpowiednie segmenty, wysłać do portu c, zwiększyć CAX, zmienić stan dodatkowej diody na PA0, odczekać 4s i ... tyle, wraca i robi znów to samo. Międzyczasie wykonuje się puste przerwanie co 1s.
Natomiast u mnie dioda miga co 1s a na LCD mam wciąż cyfrę 1, jaka był przypisana na początku jeszcze przed pętlą.
Program działa prawidłowo jeżeli całą konfigurację przerwania oraz samo przerwanie ujmę w komentarz.
Wówczas wyświetlana cyfra się zwiększa wraz ze zmianą stanu diody co 4s.
(bardzo podobny do tego z ATNEL-a). Pierwsze kroki z diodą i wyświetlaczem LCD za mną. Przerwanie i migoczącą diodą także.
Problem mam z konfiguracją przerwania TIMER1
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//----definicja segmentow----
#define sA (1<<PC0)
#define sB (1<<PC1)
#define sC (1<<PC2)
#define sD (1<<PC3)
#define sE (1<<PC4)
#define sF (1<<PC5)
#define sG (1<<PC6)
//----definicja cyfr------
#define c0 ( sG)
#define c1 ( sA | sD | sE | sF | sG)
#define c2 ( sC | sF)
#define c3 ( sE | sF)
#define c4 ( sA | sD | sE)
#define c5 ( sB | sE)
#define c6 ( sB)
#define c7 ( sD | sE | sF | sG)
#define c8 (0)
#define c9 ( sE)
#define ce ( sB |sC)
//----zmienne globalne----
uint8_t zn,CAX;
uint8_t *wsk;
// --- *** Program Glowny *** ---
int main(void)
{
DDRC |= (sA | sB | sC | sD | sE | sF | sG); //piny do lcd
DDRA |= (1<<PA0); //pin do diody
//--- konfiguracja przerwania ---
TCCR1B |= (1<<WGM12); //ustawienie TIMER1 w tryb CTC
TCCR1B |= ((1<<CS12)|(1<<CS10)); //ustawienie prescalera
OCR1A =15625; //wartosc w rejestrze do porownania
TIMSK |= ((1<<OCIE1A) | (1<<OCIE1B)); //zezwolenie na przerwanie od timer1
sei();
CAX=1; //ot takie sobie przypisanie
//--- petla---
while(1)
{
zn=CAX;
switch (zn) //konwersja cyfry na konkretne segmenty
{
case 0:
zn=c0;
break;
case 1:
zn=c1;
break;
case 2:
zn=c2;
break;
case 3:
zn=c3;
break;
case 4:
zn=c4;
break;
case 5:
zn=c5;
break;
case 6:
zn=c6;
break;
case 7:
zn=c7;
break;
case 8:
zn=c8;
break;
case 9:
zn=c9;
break;
default:
zn=ce;
}
PORTC=zn; //wyslanie cyfry juz zamienionej
portu C
wsk=&CAX;
++*wsk;
if (*wsk>=10) *wsk=0;
PORTA ^=(1<<PA0); //zmiana stanu diody
_delay_ms(4000);
}
}
//---przerwanie---
ISR(TIMER1_COMPA_vect)
{
}
Wiem że kod jest nieco zagmatwany i niepotrzebne są wskaźniki i przerwanie ale właśnie się ich uczyłem i dlatego zastosowałem.
W tym przypadku włączone jest przerwanie, ale jest puste. Wykonywać powinien się tylko główny program zliczający CAX, "przekonwertować" na odpowiednie segmenty, wysłać do portu c, zwiększyć CAX, zmienić stan dodatkowej diody na PA0, odczekać 4s i ... tyle, wraca i robi znów to samo. Międzyczasie wykonuje się puste przerwanie co 1s.
Natomiast u mnie dioda miga co 1s a na LCD mam wciąż cyfrę 1, jaka był przypisana na początku jeszcze przed pętlą.
Program działa prawidłowo jeżeli całą konfigurację przerwania oraz samo przerwanie ujmę w komentarz.
/*
//--- konfiguracja przerwania ---
TCCR1B |= (1<<WGM12); //ustawienie TIMER1 w tryb CTC
TCCR1B |= ((1<<CS12)|(1<<CS10)); //ustawienie prescalera
OCR1A =15625; //wartosc w rejestrze do porownania
TIMSK |= ((1<<OCIE1A) | (1<<OCIE1B)); //zezwolenie na przerwanie od timer1
sei();
*/
/*
//---przerwanie---
ISR(TIMER1_COMPA_vect)
{
}
*/
Wówczas wyświetlana cyfra się zwiększa wraz ze zmianą stanu diody co 4s.