本帖最后由 mfkyygt 于 2014-7-18 22:38 编辑
近来无聊,决定把普力马的手动温控改为自动温控,并把FM、蓝牙免提和MP3集成在一起控制,发几个主要的子程序模块吧,包括18B20的读写、按键扫描、EEPROM的读写,供有兴趣玩玩的参考下吧:主控芯片 M8
//---- DS18B20复位 ----
void DS18B20_reset()
{
OUTPUT(DDRB,DQ); //DQ设为输出
CLR(PORTB,DQ); //DQ拉低电平
delay_us(680); //延迟500us
SET(PORTB,DQ); //DQ置高电平
delay_us(50); //延迟40us
INPUT(DDRB,DQ); //DQ设为输入
while(PINB&BIT(DQ));
while(!(PINB&BIT(DQ)));
}
//---- DS18B20写字节 ----
void DS18B20_write(unsigned char dt)
{
unsigned char i;
OUTPUT(DDRB,DQ); //DQ设为输出
for (i=0;i<8;i++)
{
CLR(PORTB,DQ); //DQ拉低电平
delay_us(10); //延迟10us
if (dt&0x01) SET(PORTB,DQ);
else CLR(PORTB,DQ);
delay_us(50); //延迟40us
SET(PORTB,DQ);
delay_us(2); //稍微延时
dt>>=1;
}
}
//---- DS18B20读字节 ----
unsigned char DS18B20_read()
{
unsigned char i,T;
for (i=0;i<8;i++)
{
T>>=1;
OUTPUT(DDRB,DQ); //DQ设为输出
CLR(PORTB,DQ); //DQ拉低电平
SET(PORTB,DQ); //DQ置高电平
delay_us(1);
INPUT(DDRB,DQ); //DQ设为输入
if (GET(PINB,DQ)) //读入DQ值
{T|=0x80;}
delay_us(100); //延迟70us
}
return T;
}
//---- DS18B20测温 ----
unsigned int Get_Temp()
{
unsigned char TL,TH;
DS18B20_reset(); //DS18B20复位
DS18B20_write(0xCC); //跳过ROM
DS18B20_write(0x44); //启动温度转换
DS18B20_reset(); //DS18B20复位
DS18B20_write(0xCC); //跳过ROM
DS18B20_write(0xBE); //读取RAM
TL =DS18B20_read(); //读温度值低八位
TH =DS18B20_read(); //读温度值低八位
DS18B20_reset(); //DS18B20复位
return(((TH<<8)|TL)*0.0625); //0.0625=xx;0.625=xx.x;6.25=xx.xx
//return((TH*256 +TL)*0.0625);
}
//========================= 分割一下吧 =========================
//---- 按键扫描 ----
void scan_key()
{
//--- 扫描KEY1
if (GET(PINC,KEY1)==0) //KEY1按下否
{
if (L_set==0)
{show_led(NowTemp);}
else
{show_led(SetTemp);} //LED显示10ms作为消抖
if (GET(PINC,KEY1)==0) //再查KEY1按下否
{
N_dl =0;
while (GET(PINC,KEY1)==0) //KEY1释放否
{
N_dl++;
if (L_set==0)
{show_led(NowTemp);}
else
{show_led(SetTemp);}
if (N_dl>30) //按下超过300ms,标记为长按
{
L_long =1;
break;
}
}
keyproc(1); //去键值处理
}
}
....
//---- 扫描KEY2
//======================== 再来割一下 ===========================
//---- 写EEPROM ----
void EEPROM_write(uint epadd,uchar epdata)
{
while (EECR &(1<<EEWE)) //等待上一次写操作结束
{;}
EEAR = epadd; //设置地址
EEDR = epdata; //设置数据寄存器
EECR |=(1<<EEMWE);
EECR |=(1<<EEWE); //启动写操作
}
//---- 读EEPROM ----
uchar EEPROM_read(uint epadd)
{
while (EECR & (1<<EEWE)) //等待上一次写操作结束
{;}
EEAR =epadd; //设置地址寄存器
EECR |=(1<<EERE); //启动读操作
return EEDR;
}
//----读取eeprom储存初值
SetTemp =EEPROM_read(0x01);
N_step =EEPROM_read(0x02);
if ((SetTemp<20)&&(SetTemp>40))
{SetTemp =24;}
if ((N_step<0)&&(N_step>5))
{N_step =2;}
//==============
else //设定状态下,短按KEY3切换温度/回差设置
{
if (L_set==1)
{L_set =2;}
else
{
EEPROM_write(0x01,SetTemp); //写入设置温度
EEPROM_write(0x02,N_step); //写入设置回差
L_set =0;
}
}
说明一下:
K1:减; K2:加; K3:模式切换/长按设定目标温度与回差温度
测试步骤:
1、长按K3,进入设定温度状态,加减设定目标温度;
2、再短按K3,设定回差温度;设定好后再短按一下K3保存设置;
3、非设定温度状态下,短按K3用来切换FM、BLUETOOTH和MP3功能(用双刀双掷信号继电器实现)
|