You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.3 KiB

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define TEMP_PIN 0
#define IMPULS0_PIN 1
#define IMPULS1_PIN 2
#define TAST_PIN 3
#define FET0_PIN 0
#define FET1_PIN 1
13 years ago
#define TIMEOUT 255
uint8_t led_color = 0;
13 years ago
uint8_t setting_timeout = 0;
uint8_t adc_pos = 0;
uint16_t adc_sum = 0;
13 years ago
uint16_t temperature = 0;
13 years ago
uint16_t target = 0;
uint8_t heat_pwm = 0;
uint8_t heat_on[2] = {0, 0};
uint8_t heat_off[2] = {0, 0};
13 years ago
uint8_t input_state = 0;
uint8_t dev_state = 0;
/* gray code to change lookup table, index is old state .. new state */
int8_t state_change[16] = {0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0};
ISR(TIM1_OVF_vect)
13 years ago
{
13 years ago
/* timeout for displaying target temperature */
13 years ago
if(setting_timeout) {setting_timeout--;}
13 years ago
/* incremtening softpwm, toggling output if needed */
heat_pwm++;
if(heat_pwm == heat_on[0]) {PORTB |= (1 << FET0_PIN);}
if(heat_pwm == heat_off[0]) {PORTB &= ~(1 << FET0_PIN);}
if(heat_pwm == heat_on[1]) {PORTB |= (1 << FET1_PIN);}
if(heat_pwm == heat_off[1]) {PORTB &= ~(1 << FET1_PIN);}
}
ISR(PCINT0_vect)
{
uint8_t new_state = (PORTA & ((1 << IMPULS1_PIN) | (1 << IMPULS0_PIN) | (1 << TAST_PIN))) >> 1;
uint8_t diff = new_state ^ input_state;
if(!diff) {return;}
if(diff & (1 << TAST_PIN) && new_state & (1 << TAST_PIN))
{
dev_state = !dev_state;
}
int8_t change = state_change[((input_state & 3) << 2) | (new_state & 3)];
if(change)
{
target += change;
setting_timeout = TIMEOUT;
}
input_state = new_state;
13 years ago
}
void io_init(void)
{
PORTA = (1 << TAST_PIN) | (1 << IMPULS1_PIN) | (1 << IMPULS0_PIN);/* enable pullups on inputs */
PORTB = 0;
13 years ago
DDRA = (1 << PA7);/* led outputs ... */
DDRB = (1 << PB2) | (1 << FET0_PIN) | (1 << FET1_PIN);/* ... and FET output */
input_state = PORTA & ((1 << IMPULS1_PIN) | (1 << IMPULS0_PIN) | (1 << TAST_PIN));
}
void led_init(void)
{
13 years ago
TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << COM0B0) | (1 << WGM01) | (1 << WGM00);/* pwm enable: fast, A not inverted, B inverted */
TCCR0B = (1 << CS02) | (1 << CS00);/* prescaler / 1024 */
OCR0A = OCR0B = led_color;
}
13 years ago
void led_set(uint16_t value)
{
13 years ago
OCR0A = OCR0B = led_color = value >> 8;
}
void adc_init(void)
{
ADMUX = (1 << REFS1) | (TEMP_PIN << MUX0);/* Vref = 1.1, pin selection */
ADCSRA = (1 << ADEN) | (1 << ADATE);/* adc enable, triggered */
ADCSRB = (1 << ADTS2);/* trigger on counter 0 overflow */
DIDR0 = (1 << TEMP_PIN);/* disable digital input on adc pin */
/* result in (ADCH << 8) | ADCL, accessable as ADC? */
}
13 years ago
void heat_init(void)
{
13 years ago
TCCR1B = (1 << CS12) | (1 << CS10);/* prescaler / 1024 */
13 years ago
TIMSK1 = (1 << TOIE1);/* interupt on overflow */
/* insert loading of heat setting here */
}
void input_init(void)
{
GIMSK = (1 << PCIE0);/* interrupt on change on PORT A */
PCMSK0 = (1 << TAST_PIN) | (1 << IMPULS1_PIN) | (1 << IMPULS0_PIN);
}
int main(void)
{
13 years ago
/* if we store the last setting somewhere calculate led_color from it before calling led_init() */
io_init();
led_init();
adc_init();
13 years ago
heat_init();
input_init();
13 years ago
for(;;)
{
if(ADCSRA & (1 << ADIF))
{
/* new adc result */
ADCSRA |= (1 << ADIF);
13 years ago
adc_sum += ADC;
13 years ago
if(++adc_pos == 64)
13 years ago
{
13 years ago
temperature = adc_sum;
adc_sum = 0;
adc_pos = 0;
13 years ago
}
}
if(setting_timeout) {led_set(target);}
13 years ago
else {led_set(temperature);}
13 years ago
}
return 0;
}