| |
candle.c
// candle.c
#include "iodefs.h"
#include "crc.h"
#include "rand.h"
#include "timer.h"
#include "uart.h"
#include "show_adc.h"
#include "progmem.h"
#include "adc.h"
#define LOW_POWER
#define delay(x) _delay_ms(x)
//#define BYTE(x) x
int main(void)
{
unsigned char ix;
register unsigned short v asm("r2");
register unsigned short v1 asm("r6");
register unsigned short v2 asm("r8");
register unsigned short v3 asm("r10");
register unsigned short seed asm("r12");
unsigned short vref;
register char tic = BYTE('-');
register unsigned char loop = 0;
osccal(); // calibrate internal processor clock
adc_disable(); // disable ADC
timer1_stop(); // stop timer
_uart_reset(); // enable UART output
// delay before driving MOSI output (thermistor driver pin)
cbi(DDR(TM_PORT),TM_BIT); // tri-state thermistor driver pin
sbi(DDR(LED_PORT),LED_BIT); // make LED driver output
for (ix = 0; ix < 4; ++ix) {
if ((ix & 1) == 0)
cbi(LED_PORT, LED_BIT); // LED on
else
sbi(LED_PORT,LED_BIT); // LED off
delay_cs(25);
}
cbi(TM_PORT,TM_BIT); // thermistor driver pin low
#ifndef LOW_POWER
sbi(DDR(TM_PORT),TM_BIT); // activate thermistor driver pin
#endif
// setup DAC (PWM mode, active low, fast clock)
timer1_init(PWM_ON, COM1A_SET, T1_CK, 0, 0);
// internal ref, left-adjust, free-run, thermistor input, fastest rate
///adc_setup(ADC_REF_INT, ADC_LEFT, ADC_BIT, ADC_FREE, ADC_CK2);
adc_setup(ADC_REF_VCC, ADC_LEFT, ADC_BIT, ADC_FREE, ADC_CK2);
adc_start(); // start free-running conversion
dac_set(255); // LED on bright
// delay and then read "reference"
delay_cs(100);
sbi(DDR(TM_PORT),TM_BIT); // activate thermistor driver pin
delay_ms(10);
seed = v1 = v2 = v3 = vref = adc_inputw() >> 6;
if (seed == 0) seed = BYTE('U');
puthexb(vref >> 8); puthexb2(vref, ' '); crlf();
while (1) {
unsigned char ch, i;
char n;
#ifndef LOW_POWER
if ((loop & 127) == 0) {
tic = BYTE('+');
}
#endif
if ((loop & 127) == 63) {
tic = BYTE('-');
}
++loop;
#define PERIOD 20
// heat up thermistor
sbi(DDR(TM_PORT),TM_BIT); // activate thermistor driver pin
//delay_ms(PERIOD/2);
delay_ms(PERIOD);
// read next value
dac_set(0); // turn off LED (low noise)
delay_ms(1); // wait for ADC reading to complete
v = adc_inputw() >> 6; // read ADC
dac_set(ix); // LED back on
puthexb(v >> 8); puthexb2(v, ' ');
if (tic == '-') {
cbi(DDR(TM_PORT),TM_BIT); // deactivate thermistor driver pin
}
// calculate delta from reference
ix = (vref > v) ? vref - v : v - vref;
puthexb2(ix, tic);
ix = ix << 2;
// update LED
seed = rand(seed);
if (ix == 0) { ix = (seed & 1) ? 0 : BYTE(40); }
else if (ix == 1) { ix = BYTE(50); }
else if (ix == 2) { ix = BYTE(60); }
else if (ix == 3) { ix = BYTE(70); }
else if (ix == 4) { ix = BYTE(80); }
else if (ix == 5) { ix = BYTE(90); }
else if (ix == 6) { ix = BYTE(100); }
else if (ix == 7) { ix = BYTE(120); }
else { ix = BYTE(126); }
puthexb2(ix, tic);
ix = (BYTE(127) - ix) << 1;
dac_set(ix);
// plot readings
n = vref - v;
for (i = 0; i < 64; ++i) {
ch = ' ';
if (i == 32) ch = BYTE('.');
if (i == 32 + n) ch = BYTE('*');
putchar(ch);
}
crlf();
// update reference
vref = (v + v1 + v2 + v3 + BYTE(2)) >> 2;
v3 = v2;
v2 = v1;
v1 = v;
// wait
delay_cs(PERIOD);
}
}
Back
|
|
|