Hallo zusammen, ich habe folgendes Problem:
Ich möchte mit dem Timer0 eine Sieben-Segment-Anzeige zum blinken bringen. Das Problem: Es funktioniert nicht .
Hier erstmal mein Code:
Code:
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <../../avr/include/util/delay.h>
// gobale Variablen
uint8_t summerOn = 0;
uint8_t timeRunning = 0;
uint8_t counter = 0;
uint8_t _NUM_ARRAY[10] = {(1<<PD1) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD7),
(1<<PD2) | (1<<PD5),
(1<<PD0) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD7),
(1<<PD0) | (1<<PD2) | (1<<PD3) | (1<<PD5) | (1<<PD7),
(1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD5),
(1<<PD0) | (1<<PD1) | (1<<PD3) | (1<<PD5) | (1<<PD7),
(1<<PD0) | (1<<PD1) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD7),
(1<<PD2) | (1<<PD5) | (1<<PD7),
(1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD7),
(1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD5) | (1<<PD7)};
uint8_t _NUM_A_ALL_ON = (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7);
uint8_t _NUM_A_ALL_OFF = ~((1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7));
void checkSummer();
void drawDisplay();
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
if ( ! (*port & (1 << pin)) )
{
// Pin wurde auf Masse gezogen, 100ms warten
_delay_ms(50); // max. 262.1 ms / F_CPU in MHz
//_delay_ms(50);
if ( *port & (1 << pin) )
{
// Anwender Zeit zum Loslassen des Tasters geben
//_delay_ms(50);
//_delay_ms(50);
return 1;
}
}
return 0;
}
void checkSummer()
{
/*if (summerOn == 1)
{
PORTB |= (1<<PB1);
PORTB ^= (1<<PB1);
_delay_ms(500);
}*/
}
void drawDisplay()
{
//if (timeRunning == 0)
//{
// PORTD = _NUM_A_ALL_OFF;
//_delay_ms(500);
//PORTD = _NUM_ARRAY[counter];
//}
}
//SIGNAL(SIG_OVERFLOW1)
ISR(TIMER0_OVF_vect)
{
//PORTD = _NUM_A_ALL_OFF;
//_delay_ms(500);
PORTD = _NUM_ARRAY[counter];
PORTB |= (1<<PB1);
}
int main(void)
{
// Ausgänge definieren
DDRD = 0xff; //Ziffern-Anzeige
DDRB |= (1<<PB1); // Summer
// Eingänge definieren
DDRB |= (1<<PB0);
// Display überprüfen
PORTD = _NUM_A_ALL_ON;
// _delay_ms(1000);
// PORTD = _NUM_A_ALL_OFF;
//Timer aktivieren
TCCR0 = (1<<CS01)|(1<<CS00);
TCNT0 = 0;
TIMSK | (1<<TOIE0);
sei();
counter = 6;
while(1)
{
if (debounce(&PINB, PB0))
{
counter += 1;
if (counter > 9)
counter = 0;
if (counter == 9)
summerOn = 1;
}
checkSummer();
drawDisplay();
}
return 0;
}
Sorry für die vielen auskommentierten Textzeilen aber ich habe halt etwas rumprobiert um das Ding zum laufen zu bringen. Ich möchte es nun einfach erstmal schaffen, dass das Programm in die ISR-Routine springt und dort den Summer zum ertönen bringt. Sieht jemand hier irgendeinen Fehler?
Ich verwende übrigens einen externen 4 Mhz Quarz.
Mfg,
Rahvin
Lesezeichen