1、自制可调温度控制器自制可调温度控制器作者:温正伟原载:无线电杂志 近期我发现很多DIY或是电子爱好的朋友们比较关注电子温度控制器制作的文章,前面我也发过一篇AT89C2051控制的简单温度计制作的文章,但是由于电路比较简易,而且没有调温功能.应部分朋友的要求我在此转载一篇温正伟在无线电杂志上发表过的一款可以方便调节、设定温度的控制器。1 功能介绍笔者设计的这一款温度控制器是使用仍是比较常用的DS18B20集成温度传感器,还是用七段数码管做显示,完成温度采集与处理控制的CPU仍是AT89C2051单片机,但该电路具有电路简单,制作起来也无需调试,安装好后就可以使用等方便DIY的优点。 该电路最大
2、的特点是用可以直观方便的调节所要限定的温度值,温度值是用3个7段共阳极数码管显示的,上电后会显示当前的温度值,按设定键时会闪烁显示设定温度值,这时可以按上/下调节键调整设定温度值,再次按下设定键时返回当前温度显示同时会对设定温度值进行保存,这个设定值会保存在DS18B20中,掉电后也不会丢失,下次上电时,单片机会自动读入上次的温度设定值。长按设定键为关闭显示和温控,再次按下时功能再次打开。电路中还设计了一路继电器控制,程序中设定超出设定温度时继电器被驱动吸合。2 元器件背景及选用表一是元器件列表。在这个电路中关键的两个元器件分别是单片机AT89C2051和温度传感传感芯片DS18B20。AT8
3、9C2051具有2K的可多次擦写的FLASH存储器,有15个I/O口,用于做一些小型的控制显示和数据采集系统是很好的选择,本制作中2051单片机除要完成数据采集、处理、控制和显示的任务外,还要完按键值的采集、处理。如果要用常规的数字加模拟电路实现起来就相对困难多了。DS18B20是DALLAS半导体公司(现属MAXIM公司)设计生产的单总线数字温度传感器,单总线也就是说只用一根I/O引线完成数据的输入输出功能,所以它的体积很小,而且电压适用范围在35.5V,封装形式除有SO/uSO的8PIN贴片式,还有更方便的三极管形式的TO92封装(封装形式和引脚说明请看图一)。DS18B20测量温度范围为
4、 -55C+125C,其A/D转换的分辩率可用程序控制分别为9位、10位、11位和12位,最高分别率可以高达0.0625C,但在-10+85C范围内其精度为0.5C,这个精度已可以满足普通型的环境温度控制或测温类消费电子产品的要求。DS18B20中有三个8位E2RAM单元(非易失性可电擦写储存器),可以读写上下限警报温度值和一个自定义值,在本制作的中就只使用了上限温度值单元。每个DS18B20出厂时都有一个唯一的序列编号,就是说在同一个单总线系统中可以控制多个DS18B20。对DS18B20的单总线的操作方法这里因篇幅问题不可能一一说明,有兴趣的读者可以自己多查看些的DS18B20资料。表1
5、元件清单元件名数量说明AT89C20511AT89C4051也可DS18B201温度传感器七段数码管3共阳极LM78051稳压三极管小按钮3100uF,10uF电解电容各10.1uF瓷片电容130pF212M晶振1也可以用11.0592M90121也可用同类小功率三极管S85503同上8.2K,4.7K电阻各1470欧电阻7可以根据数码管的亮度选用或不用1K电阻4继电器1驱动电压为5V图1:温度传感器封装形式及引脚说明3 电路原理制作中DS18B20使用外接电源的供电方式,数据端用4.7K电阻上拉,并联接到2051的11脚上。晶振选用12M的,使用简单的上电复位电路。选用共阳极的数码管,用S8
6、550作位驱动,段引脚通过470欧的电限流电阻接入2051的P1口上,如选用的数码管亮度不足可以调小限流电阻值。笔者也使用过共阴极的数码管,在P1口用1K电阻上拉提供电流,亮度不高,但可以节省三个位驱动IO脚,电路更是简单。电路中有三个按键,分别是显示开关/温度设定,温度上调,温度下调,在电路上电运行时程序初始是处于关闭状态的,要按一下S2电路开始显示和监测,如再按一下S2进入温度设定状态,设定值每秒闪烁一次,这时可以按S1或S3进行调节,再按下S2时退回显示当前温度状态并保存温度值到DS18B20。使用2051的第9脚做控制输出端,低电平有效,笔者用它通过9012去驱动一个5V的继电器。笔者
7、把这个电路安装到电脑前面板上,继电器触头端接机箱的散热风扇,设定一个温度值如28度,当机箱内的温度超出28度时,控制端为低电平,继电器闭合,风扇启动进行散热。图三就是装在电脑面板上的实物照片。图2:电原理图4 软件实现图三 实物图用实验板搭建的实物图源程序如下:/*-温度控制器V1.51显示为三个共阳极LED温度传感器用单总线DS18B20CPU为2051,三个按键,分别为UP,DOWN,SET温度调节上限为125度,下限为-55度只能用于单只18B20本软件仅供学习与参考,引用时请注明版权#include #include #define Key_UP P3_0 /上调温度#define K
8、ey_DOWN P3_1 /下调温度#define Key_SET P1_7 /设定键(温度设定,长按开电源)#define RelayOutPort P3_5 /继电器输出#define LEDPort P1 /LED控制口#define LEDOneC P3_2 /LED DS1控制(百位)#define LEDTwoC P3_3 /LED DS2控制(十位)#define LEDThreeC P3_4 /LED DS3控制(个位)#define TMPort P3_7 /DS1820 DataPortunsigned char code LEDDis=0xC0,0xF9,0xA4,0xB
9、0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF; /0-9的LED笔划,0xFF为空,0xF7为负号static unsigned char bdata StateREG; /可位寻址的状态寄存器sbit DS1820ON = StateREG0; /DS1820是否存在sbit SetTF = StateREG1; /是否是在温度设置状态sbit KeySETDown = StateREG2; /是否已按过SET键标识sbit PowTF = StateREG3; /电源电源标识sbit KeyTF = StateREG4; /键盘是否允许/sbit Ke
10、ySETDowning = StateREG5; /SET是否正在按下static unsigned char bdata TLV _at_ 0x0029; /温度变量高低位static unsigned char bdata THV _at_ 0x0028;static signed char TMV; /转换后的温度值static unsigned char KeyV,TempKeyV; /键值static signed char TMRomV _at_ 0x0027; /高温限制static signed char TMSetV _at_ 0x0026; /温度设定值static uns
11、igned char KSDNum; /SET键连按时的采集次数static unsigned char IntNum,IntNum2,IntNum3; /中断发生次数,IntNum用于SET长按检测,IntNum2用于设定状态时LED闪烁static signed char LED_One,LED_Two,LED_Three; /LED的显示位 LED_One为十位,LED_Two为个位static unsigned char Sign; /负号标识void main(void)void InitDS1820(void); /定义函数void ROMDS1820(void);void TMV
12、DS1820(void);void TMRDS1820(void);void TMWDS1820(void);void TMREDS1820(void);void TMERDS1820(void);void ReadDS1820(void);void WriteDS1820(void);void Delay_510(void);void Delay_110(void);void Delay_10ms(void);void Delay_4s(void);void V2ToV(void);StateREG = 0; /初始化变量SetTF = 1; PowTF = 1; /关电源THV = 0;T
13、LV = 0;TMV = 0;KeyV = 0;TempKeyV = 0;KSDNum = 0;IntNum = 0;IntNum2 = 0;IntNum3 = 0;LED_One = 0;LED_Two = 0;InitDS1820(); /初始化ROMDS1820(); /跳过ROMTMERDS1820(); /E2PRAM中温度上限值调入RAMInitDS1820(); /初始化ROMDS1820(); /跳过ROMTMRDS1820(); /读出温度指令ReadDS1820(); /读出温度值和上限值TMSetV = TMRomV; /拷贝保存在DS18B20ROM里的上限值到TMSe
14、tVEA = 1; /允许CPU中断ET0 = 1; /定时器0中断打开TMOD = 0x1; /设定时器0为模式1,16位模式TH0=0xB1;TL0=0xDF; /设定时值为20000us(20ms)TR0 = 1; /开始定时while(1);/定时器0中断外理中键扫描和显示void KeyAndDis_Time0(void) interrupt 1 using 2TH0=0xB1;TL0=0xDF; /设定时值为20000us(20ms)LEDPort = 0xFF;if (!Key_UP) KeyV = 1;if (!Key_DOWN) KeyV = 2;if (!Key_SET)
15、KeyV = 3;/KeySETDowning = 0; /清除if (KeyV != 0) /有键按下 Delay_10ms(); /延时防抖 按下10ms再测 if (!Key_UP) TempKeyV = 1; if (!Key_DOWN) TempKeyV = 2; if (!Key_SET) TempKeyV = 3; if (KeyV = TempKeyV) /两次值相等为确定接下了键 if (KeyV = 3) /按下SET键,如在SET状态就退出,否则进入 /KeySETDowning = 1; /表明SET正在按下 PowTF = 0; /电源标识开 if (!KeyTF)
16、if (SetTF) SetTF = 0; /标识位标识退出设定 InitDS1820(); /初始化 ROMDS1820(); /跳过ROM TMWDS1820(); /写温度上限指令 WriteDS1820(); /写温度上限到DS18B20ROM WriteDS1820(); /写温度上限到DS18B20ROM WriteDS1820(); /写温度上限到DS18B20ROM InitDS1820(); /初始化 ROMDS1820(); /跳过ROM TMREDS1820(); /温度上限值COPY回E2PRAM else SetTF = 1; if (!KeySETDown) /没有
17、第一次按下SET时,KeySETDown标识置1 KeySETDown = 1; else KSDNum = KSDNum + 1; /前一秒内有按过SET则开始计数 if (SetTF) /在SET状态下 if (KeyV = 1) & (!KeyTF) TMSetV = TMSetV + 1; /上调温度 if (KeyV = 2) & (!KeyTF) TMSetV = TMSetV - 1; /下调温度 if (TMSetV = 125) TMSetV = 125; if (!KeyTF) & (IntNum3 = 0) KeyTF = 1; /当键盘处于可用时,锁定 if (KeyS
18、ETDown) /在2秒内按下了SET则计中断发生次数用于长按SET时计时用 IntNum = IntNum + 1; if (IntNum 55) /中断发生了55次时(大约1.2秒)75为1.5秒左右 IntNum = 0; KeySETDown = 0; if (KSDNum = 55) /如一直长按了SET1.2秒左右 RelayOutPort = 1; /关闭继电器输出 PowTF = 1; /电源标识关 LEDOneC = 0; LEDTwoC = 0; LEDThreeC = 0; LEDPort = 0xBF; /显示- Delay_4s(); /延时 LEDOneC = 1;
19、 LEDTwoC = 1; /关显示 LEDThreeC = 1; Delay_4s(); IntNum = 0; IntNum2 = 0; IntNum3 = 0; KSDNum = 0; KeyV = 0;TempKeyV = 0; /清空变量准备下次键扫描if (!PowTF) InitDS1820(); /初始化 ROMDS1820(); /跳过ROM TMVDS1820(); /温度转换指令 Delay_510(); Delay_510(); /延时等待转换完成 InitDS1820(); /初始化 ROMDS1820(); /跳过ROM TMRDS1820(); /读出温度指令 R
20、eadDS1820(); /读出温度值 V2ToV(); /转换显示值 if (TMV TMSetV) /根据采集到的温度值控制继电器 RelayOutPort = 0; else RelayOutPort = 1; if (SetTF) IntNum2 = IntNum2 + 1; /用于闪烁计数 if (IntNum2 50 ) IntNum2 = 0; if (KeyTF) IntNum3 = IntNum3 + 1; /用于防止按键连按 if (IntNum3 25) IntNum3 = 0; KeyTF = 0; if (SetTF) & (IntNum2 4;THV = THV 7
21、; /取符号else Sign = TMV 7;if (Sign) if (SetTF | !Key_SET) LED_One = (TMSetV-1) / 100; /SET状态下显示设定值 LED_Two = (TMSetV-1) - LED_One * 100)/10; LED_Three = (TMSetV-1) - LED_One * 100 - LED_Two * 10; else LED_One = (TMV-1) / 100; /转换百位值 LED_Two = (TMV-1) - LED_One * 100)/10; LED_Three = (TMV-1) - LED_One
22、* 100 - LED_Two * 10; else if (SetTF | !Key_SET) LED_One = (TMSetV) / 100; /SET状态下显示设定值 LED_Two = (TMSetV - LED_One * 100)/10; LED_Three = TMSetV - LED_One * 100 - LED_Two * 10; else LED_One = (TMV) / 100; /转换百位值 LED_Two = (TMV - LED_One * 100)/10; LED_Three = TMV - LED_One * 100 - LED_Two * 10; /转L
23、ED字段 if (LED_One) /超过百时十位的处理 LED_Two = LEDDisLED_Two;else if (LED_Two = 0) LED_Two = LEDDis10; else LED_Two = LEDDisLED_Two; if (Sign) LED_One = LEDDis11;else if (LED_One = 0) LED_One = LEDDis10; else LED_One = LEDDisLED_One; LED_Three = LEDDisLED_Three;void InitDS1820(void) /初始化DS1820TMPort = 1; /拉高TMPort_nop_(); /保持一个周期TMPort =
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1