Die ISR macht komische Dinge im Simulator...
Hab die bools mal durch uint8 ersetzt und den Wechsel mit nem xor realisiert.
Zumindest im Simulator tuts jetzt in der ISR.
Code:
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#define F_CPU 9.6E6
#include <util/delay.h>
#define CLOCK_PRESCALER 256
#define TIMER_PRESCALER 1024
#define TIMER_PERIOD (256 / (F_CPU / CLOCK_PRESCALER / TIMER_PRESCALER))
#define MEDIAN ( 1 * 60) /* 10 minutes */
volatile uint16_t countdown;
volatile uint8_t timer_expired;
volatile uint8_t on;
ISR(TIM0_OVF_vect)
{
if (--countdown == 0) {
TCCR0B = 0; /* turn off timer */
timer_expired = 0x01;
clock_prescale_set(clock_div_1);
}
}
ISR(INT0_vect)
{
on ^= 0x01;
if (on) {
PORTB |= (1<<PB4); // LED 2*flashing: Off
_delay_ms(20);
PORTB &= ~(1<<PB4);
_delay_ms(20);
PORTB |= (1<<PB4);
_delay_ms(20);
PORTB &= ~(1<<PB4);
_delay_ms(20);
} else {
PORTB |= (1<<PB4); // LED 1*flashing: On
_delay_ms(20);
PORTB &= ~(1<<PB4);
_delay_ms(20);
}
}
static void starttimer(uint16_t timeout)
{
countdown = timeout;
TCNT0 = 0;
timer_expired = 0x00;
clock_prescale_set(clock_div_256);
TCCR0B = _BV(CS02) | _BV(CS00); /* start timer with prescaler 1024 */
}
static void ioinit(void)
{
TIMSK0 = _BV(TOIE0);
GIMSK |= (1<<INT0);
//MCUCR |= (1<<ISC01); // Falling edge
//MCUCR &= ~(1<<ISC00); // INT0 detection
MCUCR = 0x02;
on = 0x00;
sei();
DDRB = _BV(4); /* connection for LED or something else */
}
static void signal_event(void)
{
PORTB |= _BV(4);
_delay_ms(1000);
PORTB &= ~_BV(4);
}
int
main(void)
{
ioinit();
while(1) {
int r = rand();
uint16_t timeout = (unsigned)r % (unsigned)(2 * MEDIAN / TIMER_PERIOD) + 1;
starttimer(timeout);
do
{
sleep_mode();
}
while (!timer_expired);
if (on) {
signal_event();
}
}
}
Lesezeichen