Zmodyfikowałem listing ze strony
http://mikrokontrolery.net/avr_c_07.htm.
Przerobiłem go, żeby odliczał do 2 min do tyłu.Przy 1 minucie zaczyna pokazywać od 59 sek w dół.W debugerze AVR studio wszystko działa, a na Atmega8 nie.Pomóżcie co robię nie tak.Do tego LED mruga
Dodam jeszcze ,że chodzi mi to na 1Mhz wewnętrznym atmegi.
http://mikrokontrolery.net/avr_c_07.htm.
Przerobiłem go, żeby odliczał do 2 min do tyłu.Przy 1 minucie zaczyna pokazywać od 59 sek w dół.W debugerze AVR studio wszystko działa, a na Atmega8 nie.Pomóżcie co robię nie tak.Do tego LED mruga

Dodam jeszcze ,że chodzi mi to na 1Mhz wewnętrznym atmegi.
Quote:
//#define F_CPU 1000000L //* czestotliwosc kwarcu */
#include 'avr/io.h'
#include 'avr/interrupt.h'
//#define CYCLES_PER_US ((F_CPU + 500000)/1000000)
#define D1_ON PORTD ^= _BV(6);
#define D2_ON PORTD ^= _BV(7);
// tablica z kodami znaków dla wyświetlacza
char znaki[17] = {192,249,164,176,153,146,130,248,128,144,136,131,198,161,134,142,0};
// zmienna pomocnicza określająca którą cyfrę wyświetlacza w danym momencie należy wyświetlić
unsigned char wysw;
// zmianne licznikowe do odmierzania czasu
volatile int jednostki_sekund = 9, dziesiatki_sekund = 5,
jednostki_minut=2, dziesiatki_minut = 0;
void aktualizuj_czas(void);
char i;
SIGNAL (SIG_OVERFLOW0)
{
TCNT0 = 250; // załadowanie do licznika wartości początkowej
PORTD &= ~0xC0; // wygaszenie wszystkich cyfr wyświetlacza
wysw++; // zwiększenie o 1 zmiennej wysw
// w zależności od wartości wysw włącz odpowiednią cyfrę na wyświetlaczu
switch(wysw)
{
case 1:
{
if(jednostki_minut<=1 && dziesiatki_sekund != 0)
{
PORTB = *(znaki + dziesiatki_sekund); // na wyświetlaczu wyświetl odpowiedni
// znak pobrany z tablicy znaków
D1_ON; // włącz pierwszą cyfrę wyświetlcza
}
break; // opuść instrukcję switch
}
case 2:
{
if(jednostki_minut<=1)
{
PORTB = *(znaki + jednostki_sekund); // na wyświetlaczu wyświetl odpowiedni
// znak pobrany z tablicy znaków
D2_ON; // włącz drugą cyfrę wyświetlcza
}else{
PORTB = *(znaki + jednostki_minut); // na wyświetlaczu wyświetl odpowiedni
// znak pobrany z tablicy znaków
D2_ON; // włącz drugą cyfrę wyświetlcza
}
break; // opuść instrukcję switch
}
case 3:
{
wysw = 0; // zeruj zmienną wysw
break; // opuść instrukcję switch
}
}
}
SIGNAL (SIG_OVERFLOW1)
{
TCNT1 = 0xC2F7; // załadowanie do licznika TIMER1 wartości początkowych
// określających częstotliwość występowania przerwania
aktualizuj_czas(); // wywołanie procedury aktualizującej czas
}
// procedura aktualizująca czas
void aktualizuj_czas(void)
{
jednostki_sekund--; // zmniejsz licznik jednostek sekund o 1
if(jednostki_sekund < 0) // jeśli licznik jednostek sekund osiągnął wartość 0 to
{
jednostki_sekund = 9; //ustaw jednoskti sekund na 9
dziesiatki_sekund--; //zmniejsz licznik dziesiątek sekund o 1
if(dziesiatki_sekund < 0) // jeśli licznik dziesiatek sekund osiągnął wartość 0 to
{
dziesiatki_sekund = 5; //ustaw dzisiatki sekund na 5
jednostki_minut--; //zmniejsz licznik jednostek minut o 1
if(jednostki_minut == 0)
{
jednostki_minut = 0;
TIMSK = 0;
cli(); //wylaczenie przerwan
}
}
}else{
if(jednostki_minut == 0)
{
jednostki_minut = 0;
TIMSK = 0;
cli();
}
}
}
// Program główny
int main(void)
{
// konfiguracja portów I/O
DDRB = 0xFF;
DDRD = 0xC1;
PORTB = 0xFF;
PORTD = 0x01;;
// wpisanie wartości początkowej
// odblokowanie przerwania od licznika
// zezwolenie na przerwania od timer 0
TCCR0 = 0x03; //Timer1 prescaler ft/256
TCNT0 = 128;
TCCR1B = 0x03; //Timer2
TCNT1 = 0xC2F7; //przy 1MHz przerwanie co 1 s
TIMSK = _BV(TOIE1)|_BV(TOIE0); //wlaczenie przerwan dla T1 i T2
// globalne odblokowanie przerwań
sei();
// pusta pętla nieskoczona
while(1);
return 0;
}
pozdr
georgio