每次在家煤气烧水总会因听不到水烧开的声音而浪费煤气。索性做个温度检测,当水温差不多合适就报警提示,由于温度精度要求不高,索性使用了热敏电阻进行模糊控制。实用就行。
//ICC-AVR application builder : 2012/6/19 下午 10:43:42
// Target : T13
// Crystal: 4.8000Mhz
#include <iot13v.h>
#include <macros.h>
#define CPL PORTB &= ~(1<<PB1)
#define CPH PORTB |=(1<<PB1)
#define DAL PORTB &= ~(1<<PB0)
#define DAH PORTB |=(1<<PB0)
#define FSL PORTB &= ~(1<<PB3)
#define FSH PORTB |=(1<<PB3)
char dsp,tdsp;
char adcdata=0;
flash char LED[]={
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
//0xed,0x21,0x8f,0xab,0x63,0xea,0xee,0xa1,0xef,0xeb
};
void delay1ms(void) //误差 0us
{
unsigned char a,b;
for(b=4;b>0;b--)
for(a=248;a>0;a--);
}
void delay(unsigned char i)
{
unsigned char a,b;
for(b=2;b>0;b--)
for(a=i;a>0;a--);
}
void delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=30;c>0;c--)
for(b=154;b>0;b--)
for(a=2;a>0;a--);
}
void beep(void) //蜂鸣器响一声函数
{
unsigned char i;
for(i=0;i<100;i++)
{
FSH;
delay1ms();
FSL; //BEEP取反
delay1ms();
}
for(i=0;i<100;i++)
{
FSH;
//delay1ms();
//FSL; //BEEP取反
delay1ms();
}
}
void send(char a)
{
char i;
for(i=8;i>0;i--)
{
CPL;delay(1);
if(a&0x80)
{
DAH;
}
else
{
DAL;
}
CPH;delay(1);
a=a<<1;
}
}
void disp(void)
{
//FSH;
send(LED[dsp%100%10]+tdsp);
send(LED[dsp%100/10]+tdsp);
send(LED[dsp/100]+tdsp);
//send(LED[dsp%100%10]+tdsp);
//send(LED[dsp%100/10]+tdsp);
//delay(255);
//delay(255);FSL;
}
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x0B;
}
void adcstar(char a,char b,char c)
{
DIDR0=a; // ADC2(PB4)禁用数字输入缓冲;
ADMUX=(1<<REFS0)|(0<<ADLAR)|(b<<MUX1)|(c<<MUX0);
/*
ADMUX (ADC Multiplexer Select Register) PDF86页
bit7 Res 保留
bit6 REFS0 0=VCC作为模拟参考电压;1=片内基准电压
bit5 ADLAR 0=右对齐;1=左对齐(8bit只读ADCH即可)
bit4:2 Res 保留
bit1:0 MUX1,MUX0 通道选择,00=ADC0(PB5);01=ADC1(PB2);10=ADC2(PB4);11=ADC3 (PB3)
*/
ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
/*
ADCSRA (ADC Control and Status Register A) PDF 87页
bit7 ADEN ADC使能=1
bit6 ADSC 启动ADC开始转换=1
bit5 ADATE 自触发使能
bit4 ADIF ADC中断标志
bit3 ADIE ADC中断使能
bit2:0 ADC 预分频选择位
*/
}
#pragma interrupt_handler eeprom_ready_isr:iv_EE_RDY
void eeprom_ready_isr(void)//内部EEPROM读写初始化
{
//eeprom ready event
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x00;
TIMSK0 = 0x00; //timer interrupt sources
GIMSK = 0x00; //interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
char key(void)
{
if (ADCSRA&(1<<ADIF))
{
adcdata=ADC/4;
ADCSRA|=(1<<ADSC)|(1<<ADIF); // ???ADC ???? ADIF?1???????1??0
}//delay(100);
return(adcdata);
}
void main(void)
{
char stmp,mode=0,tmp;
init_devices();
stmp=EEPROMread(0);//读取EEPROM预设温度数据
adcstar(0x10,1,0);//温度检测
dsp=key();
disp();
FSH;
while(1)
{
adcstar(0x10,1,0);//温度检测
delay10ms();
if(mode==0)
{
tmp=((key()-37)/2)+10;
tdsp=0x00;
if((tmp>stmp)&&(key()>38))
{
beep();
}
else
{
FSH;
}
if(dsp!=tmp)
{
dsp=tmp;
disp();
}
}
delay10ms();
adcstar(0x04,0,1);//按键检测
delay10ms();
//if(dsp!=key())
//{
//dsp=key();
//disp();
//}
if(key()==0)
{
mode++;
if(mode>1)
{
mode=0;
}
while(key()==0);
}
if(mode==1)
{
tdsp=0x80;
if(dsp!=stmp)
{
dsp=stmp;
disp();
}
if((key()>=104)&&(key()<=107))
{
stmp++;
if(stmp>250)
{
stmp=250;
}
EEPROMwrite(0,stmp);//向EEPROM写入预设温度数据
//while((key()==105)|(key()==106));
}
if((key()>=180)&&(key()<=183))
{
stmp--;
if(stmp<1)
{
stmp=1;
}
EEPROMwrite(0,stmp);//向EEPROM写入预设温度数据
//while((key()==180)|(key()==181));
}
}
delay10ms();
}
}
|