Zadanie chyba najprostsze jakie może być a jednak spędza mi sen z powiek bowiem:
Po napisaniu programu na płytce AVT-3505, postanowiłem przenieść go do docelowego układu, który sam sobie zbudowałem. Na płytce AVT-3505 wszystko działało super. Po zamianie definicji wyprowadzeń (#define), okazało się, że program nie działa. Przeprowadziłem symulację w AVR Studio i okazało się, że za żadne skarby nie chce zareagować na przerwanie od Timera0. Wszystkie bity w rejestrze TIMSK i SREG są ustawione prawidłowo, ale po wymuszeniu stanu "1" w rejestrze TIFR (bit TOV0) program nie skacze tam, gdzie powinien (obsługa wyświetlacza). W pliku makefile też wszystko ustawiłem zgodnie z wymaganiami (wybrałem attiny2313, częstotliwość rezonatora, nazwa pliku też jest poprawna). Dodam jeszcze tylko, że program jest zbudowany tak, aby zliczał w trybie przyspieszonym specjalnie po to, aby sprawdzić jego poprawność (godziny zliczane są jako minuty a minuty jako sekundy)
Spędziłem wczoraj całą noc na próbachi niestety nic nie pomogło, dlatego proszę Was o pomoc. Co zrobiłem nie tak? O czym zapomniałem? Poniżej przedstawiam listing programu:
Kod: Zaznacz cały
#include <avr\io.h>
#include <avr\signal.h>
#include <avr\interrupt.h>
#include <inttypes.h>
#define LEDPORT PORTB
#define LEDDDR DDRB
#define COMPORT PORTD
#define COMDDR DDRD
#define COM1 0
#define COM2 1
#define COM3 4
#define COM4 5
#define A PB1
#define B PB2
#define C PB3
#define D PB4
#define E PB5
#define F PB6
#define G PB6
#define STERDDR DDRD
#define PORTSTER PORTD
#define PINSTER PIND
#define SET 3
#define MODE 2
uint8_t g_AktWyswietlacz ;
uint16_t g_WzoryCyfr[10] ;
uint8_t g_DaneCom[4] ;
uint8_t g_Czas[4] ;
uint8_t g_Ustawienie ;
volatile uint8_t g_Delay ;
// Funkcja zliczania ziesiątek minut:
void Min_dzies(void)
{
static uint8_t Czas ;
++Czas ;
if (Czas > 2)
{
Czas = 0 ;
}
g_Czas[3] = Czas ;
return ;
}
// Funkcja zliczania jednostek minut:
void Min_jedn(void)
{
static uint8_t Czas ;
++Czas ;
if (Czas > 3)
{
if(g_Czas[3] == 2)
{
Czas = 0 ;
g_Czas[3] = 0 ;
}
}
if (Czas > 9)
{
Czas = 0 ;
Min_dzies();
}
g_Czas[2] = Czas ;
return ;
}
// Funkcja zliczająca dziesiątki sekund:
void Sek_dzies(void)
{
static uint8_t Czas ;
++Czas ;
if (Czas > 5)
{
Czas = 0 ;
if (g_Ustawienie == 0)
{
Min_jedn();
}
}
g_Czas[1] = Czas ;
return ;
}
// Funkcja zliczająca jednostki sekund:
void Sek_jedn(void)
{
static uint8_t Czas ;
++Czas ;
if (Czas > 9)
{
Czas = 0 ;
Sek_dzies() ;
}
g_Czas[0] = Czas ;
return ;
}
// Funkcja sprawdzająca przycisk:
void Sprawdz_przycisk(uint8_t przycisk, void(*funkcja)(void))
{
if (!(PINSTER & przycisk))
{
g_Delay = 7 ;
while (g_Delay != 0){}
if (!(PINSTER & przycisk))
{
g_Ustawienie = 1 ;
funkcja();
g_Delay = 160 ;
while(!(PINSTER & przycisk))
{
if (g_Delay == 0)
{
g_Delay = 14 ;
funkcja();
}
}
}
TCNT1 = 31250 ;
}
g_Ustawienie = 0 ;
}
// Start
int main(void)
{
// Inicjalizacja wyjść:
LEDDDR = 0xff ;
COMDDR = 1<<COM1 | 1<<COM2 | 1<<COM3 | 1<<COM4 | 1<<6 ;
PORTD = 1<<SET | 1<<MODE ;
// Inicjalizacja Timera1:
TCCR1B = 1<<CS12 ; // Stopień prescalera Timera1 na 256
// Inicjalizacja Timera0:
TCCR0B = 1<<CS02 ; // Stopień prescalera Timera0 na 256
// Inicjalizacja Przerwań od timerów:
TIMSK = 1<<TOIE0 | 1<<TOIE1 ; // Odblokowanie przerwań od przepełnienia Timera0 i Timera1
// Globalne odblokowanie przerwań:
sei() ;
// Tablica wypełniona wzorami cyfr:
g_WzoryCyfr[0] = ~(1<<A | 1<<B | 1<<C | 1<<D | 1<<E | 1<<F); //0
g_WzoryCyfr[1] = ~(1<<B | 1<<C) ; //1
g_WzoryCyfr[2] = ~(1<<A | 1<<B | 1<<D | 1<<E | 1<<G) ; //2
g_WzoryCyfr[3] = ~(1<<A | 1<<B | 1<<C | 1<<D | 1<<G) ; //3
g_WzoryCyfr[4] = ~(1<<B | 1<<C | 1<<F | 1<<G) ; //4
g_WzoryCyfr[5] = ~(1<<A | 1<<C | 1<<D | 1<<F | 1<<G) ; //5
g_WzoryCyfr[6] = ~(1<<A | 1<<C | 1<<D | 1<<E | 1<<F | 1<<G) ; //6
g_WzoryCyfr[7] = ~(1<<A | 1<<B | 1<<C) ; //7
g_WzoryCyfr[8] = ~(1<<A | 1<<B | 1<<C | 1<<D | 1<<E | 1<<F | 1<<G) ; //8
g_WzoryCyfr[9] = ~(1<<A | 1<<B | 1<<C | 1<<D | 1<<F | 1<<G) ; //9
// Wypełniona tablica odpowiedzialna za obsługę wyświetlaczy:
g_DaneCom[0] = ~(1<<COM1) ;
g_DaneCom[1] = ~(1<<COM2) ;
g_DaneCom[2] = ~(1<<COM3) ;
g_DaneCom[3] = ~(1<<COM4) ;
for(;;)
{
Sprawdz_przycisk(1<<SET, Sek_jedn);
Sprawdz_przycisk(1<<MODE, Min_jedn);
}
return 0 ;
}
// Koniec main
//Przerwanie odpowiedzialne za multipleksowanie i wyświetlanie cyfr:
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 138 ;
COMPORT |= 1<<COM1 | 1<<COM2 | 1<<COM3 | 1<<COM4 ;
LEDPORT = g_WzoryCyfr[g_Czas[g_AktWyswietlacz]] ;
COMPORT &= g_DaneCom[g_AktWyswietlacz] ;
if (g_Delay > 0)
{
--g_Delay ;
}
++g_AktWyswietlacz ;
if(g_AktWyswietlacz > 3)
g_AktWyswietlacz = 0 ;
}
// Przerwanie wywoływane co 1s.:
SIGNAL(SIG_OVERFLOW1)
{
// Ta część odpowiedzialna jest za miganie diodami pomiędzy cyframi minut i sekund
if ((PORTD & 1<<6))
{
PORTD |= 1<<6 ;
}
else
{
PORTD &= 1<<6 ;
}
TCNT1 = 31250 ;
Sek_jedn();
} p.s.: Czy to możliwe, że mikrokontroler jest uszkodzony?