Zurück zur SPiC Übersicht
kaffeemaschine.c
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
typedef enum {
STATE_STANDBY,
STATE_ACTIVE,
STATE_NO_WATER
} state_t;
typedef enum {
EVENT_BUTTON,
EVENT_NO_WATER,
EVENT_ALARM
} event_t;
static uint8_t overflow_counter = 0;
static volatile uint8_t button_event = 0; static volatile uint8_t no_water_event = 0; static volatile uint8_t alarm_event = 0;
static void init(void) {
DDRD |= (1 << PD5);
PORTD |= (1 << PD5);
DDRD |= (1 << PD7) | (1 << PD4) | (1 << PD6);
PORTD |= (1 << PD7) | (1 << PD4) | (1 << PD6);
DDRD &= ~(1 << PD2);
PORTD |= (1 << PD2);
EICRA |= (1 << ISC01);
EICRA &= ~(1 << ISC00);
EIMSK |= (1 << INT0);
DDRD &= ~(1 << PD3);
PORTD |= (1 << PD3);
EICRA |= (1 << ISC11);
EICRA &= ~(1 << ISC10);
EIMSK |= (1 << INT1);
TCCR0B &= ~(1 << CS01);
TCCR0B |= (1 << CS02) | (1 << CS00);
}
static void startAlarm(void) {
overflow_counter = 0;
TIMSK0 |= (1 << TOIE0);
}
static void stopAlarm(void) {
TIMSK0 &= ~(1 << TOIE0);
}
static void startBrewing(void) {
PORTD &= ~(1 << PD5);
}
static void stopBrewing(void) {
PORTD |= (1 << PD5);
}
static uint8_t hasWater(void) {
return (PIND & (1 << PD3));
}
static void setLEDState(state_t state) {
PORTD |= (1 << PD7) | (1 << PD4) | (1 << PD6);
switch (state) {
case STATE_STANDBY:
PORTD &= ~(1 << PD7);
break;
case STATE_ACTIVE:
PORTD &= ~(1 << PD4);
break;
case STATE_NO_WATER:
PORTD &= ~(1 << PD6);
break;
}
}
ISR(INT0_vect) {
button_event = 1;
}
ISR(INT1_vect) {
no_water_event = 1;
}
ISR(TIMER0_OVF_vect) {
++overflow_counter;
if (overflow_counter == 122) {
overflow_counter = 0;
alarm_event = 1;
}
}
void main(void) {
init();
sei();
sleep_enable();
state_t state = STATE_STANDBY;
setLEDState(state);
while (1) {
cli();
while (button_event == 0 && no_water_event == 0 && alarm_event == 0) {
sei();
sleep_cpu();
cli();
}
event_t event;
if (button_event != 0) {
button_event = 0;
event = EVENT_BUTTON;
} else if (no_water_event != 0) {
no_water_event = 0;
event = EVENT_NO_WATER;
} else {
alarm_event = 0;
event = EVENT_ALARM;
}
sei();
state_t state_old = state;
switch (state) {
case STATE_STANDBY:
if (event == EVENT_BUTTON) {
if (hasWater()) {
state = STATE_ACTIVE;
} else {
state = STATE_NO_WATER;
}
}
break;
case STATE_ACTIVE:
if (event == EVENT_BUTTON || event == EVENT_NO_WATER) {
state = STATE_STANDBY;
}
break;
case STATE_NO_WATER:
if (event == EVENT_ALARM) {
state = STATE_STANDBY;
}
break;
}
if (state == state_old) {
continue;
}
setLEDState(state);
switch (state) {
case STATE_STANDBY:
stopBrewing();
stopAlarm();
break;
case STATE_ACTIVE:
startBrewing();
stopAlarm();
break;
case STATE_NO_WATER:
stopBrewing();
startAlarm();
break;
}
}
}