电脑可调温度控制器源程序
温度控制器 V1.5 显示为三个共阳极 LED 温度传感器用单总线 DS18B20CPU 为 2051,四个按键,分别为 UP,DOWN,SET 温度调节上限为 125 度,下限为-55 度只能用于单只 18B20 本软件仅供学习与参考,引用时请注明版权 http://www.cdle.net 明浩 2004/1/2pnzwzw@cdle.net-------------------------------*/#include#include#define Key_UP P3_0 //上调温度#define Key_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,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF}; //0-9 的 LED 笔划,0xFF 为空,0xF7 为负号 static unsigned char bdata StateREG; //可位寻址的状态寄存器 sbit DS1820ON = StateREG^0; //DS1820 是否存在 sbit SetTF = StateREG^1; //是否是在温度设置状态 sbit KeySETDown = StateREG^2; //是否已按过 SET 键标识 sbit PowTF = StateREG^3; //电源电源标识 sbit KeyTF = StateREG^4; //键盘是否允许//sbit KeySETDowning = StateREG^5; //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 unsigned 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 TMVDS1820(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;TLV = 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 里的上限值到 TMSetVEA = 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 2{TH0=0xB1;TL0=0xDF; //设定时值为 20000us(20ms)LEDPort = 0xFF;if (!
Key_UP)KeyV = 1;if (!Key_DOWN)KeyV = 2;if (!Key_SET)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)if (SetTF){SetTF = 0; //标识位标识退出设定 InitDS1820(); //初始化 ROMDS1820(); //跳过 ROMTMWDS1820(); //写温度上限指令 WriteDS1820(); //写温度上限到 DS18B20ROMWriteDS1820(); //写温度上限到 DS18B20ROMWriteDS1820(); //写温度上限到 DS18B20ROMInitDS1820(); //初始化 ROMDS1820(); //跳过 ROMTMREDS1820(); //温度上限值 COPY 回 E2PRAM}elseSetTF = 1;if (!
KeySETDown) //没有第一次按下 SET 时,KeySETDown 标识置 1KeySETDown = 1;elseKSDNum = 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 (KeySETDown) //在 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;LEDTwoC = 1; //关显示 LEDThreeC = 1;Delay_4s();IntNum = 0;IntNum2 = 0;IntNum3 = 0;}KSDNum = 0;}}KeyV = 0;TempKeyV = 0; //清空变量准备下次键扫描 if (!
PowTF){InitDS1820(); //初始化 ROMDS1820(); //跳过 ROMTMVDS1820(); //温度转换指令 Delay_510();Delay_510(); //延时等待转换完成 InitDS1820(); //初始化 ROMDS1820(); //跳过 ROMTMRDS1820(); //读出温度指令 ReadDS1820(); //读出温度值 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; //取符号 elseSign = 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) / 100; //转换百位值 LED_Two = ((~TMV) - LED_One * 100)/10;LED_Three = (~TMV) - LED_One * 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;}}//转 LED 字段 if (LED_One) //超过百时十位的处理 LED_Two = LEDDis[LED_Two];else{if (LED_Two ==
0)LED_Two = LEDDis[10];elseLED_Two = LEDDis[LED_Two];}if (Sign)LED_One = LEDDis[11];else{if (LED_One ==
0)LED_One = LEDDis[10];elseLED_One = LEDDis[LED_One];}LED_Three = LEDDis[LED_Three];}void InitDS1820(void) //初始化 DS1820{TMPort = 1; //拉高 TMPort_nop_(); //保持一个周期 TMPort = 0; //拉低 TMPortDelay_510(); //延时 DS1820 复位时间要 500us 的低电平 TMPort = 1; //拉高 TMPort_nop_(); //保持_nop_();_nop_();Delay_110(); //延时 110us 等待 DS1820 回应 if (!
TMPort) //回应信号为低电平 DS1820ON = 1;elseDS1820ON = 0;Delay_110(); //延时 Delay_110();TMPort = 1; //拉高 TMPort}void ROMDS1820(void) //跳过 ROM 匹配{#pragma asmMOV A,#0CCHMOV R2,#8CLR CWR1:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR1SETB P3_7#pragma endasm}void TMVDS1820(void) //温度转换指令{#pragma asmMOV A,#44HMOV R2,#8CLR CWR2:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR2SETB P3_7#pragma endasm}void TMRDS1820(void) //读出温度指令{#pragma asmMOV A,#0BEHMOV R2,#8CLR CWR3:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR3SETB P3_7#pragma endasm}void TMWDS1820(void) //写入温度限制指令{#pragma asmMOV A,#04EHMOV R2,#8CLR CWR13:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR13SETB P3_7#pragma endasm}void TMREDS1820(void) //COPY RAM to E2PRAM{#pragma asmMOV A,#48HMOV R2,#8CLR CWR33:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR33SETB P3_7#pragma endasm}void TMERDS1820(void) //COPY E2PRAM to RAM{#pragma asmMOV A,#0B8HMOV R2,#8CLR CWR43:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR43SETB P3_7#pragma endasm}void WriteDS1820(void) //写入温度限制值{#pragma asmMOV A,26H //发出 4EH 写 ROM 指令后连发两个字节分别为上下限 MOV R2,#8CLR CWR23:CLR P3_7MOV R3,#6DJNZ R3,$RRC AMOV P3_7,CMOV R3,#23DJNZ R3,$SETB P3_7NOPDJNZ R2,WR23SETB P3_7#pragma endasm}void ReadDS1820(void) //读出温度值{#pragma asmMOV R4,#3 ; 将温度高位和低位,高温限制位从 DS18B20 中读出 MOV R1,#29H ; 低位存入 29H(TEMPER_L),高位存入 28H(TEMPER_H),高温限制位存入 27H(TMRomV)RE00:MOV R2,#8RE01:CLR CSETB P3_7NOPNOPCLR P3_7NOPNOPNOPSETB P3_7MOV R3,#09RE10:DJNZ R3,RE10MOV C,P3_7MOV R3,#23RE20:DJNZ R3,RE20RRC ADJNZ R2,RE01MOV @R1,ADEC R1DJNZ R4,RE00#pragma endasm}void Delay_510(void) //延时 510 微秒{#pragma asmMOV R0,#7DHMOV R1,#02HTSR1:DJNZ R0,TSR1MOV R0,#7DHDJNZ R1,TSR1#pragma endasm}void Delay_110(void) //延时 110 微秒{#pragma asmMOV R0,#19HMOV R1,#02HTSR2:DJNZ R0,TSR2MOV R0,#19HDJNZ R1,TSR2#pragma endasm}void Delay_10ms(void) //延时 10ms{#pragma asmMOV R0,#19HMOV R1,#0C8HTSR3:DJNZ R0,TSR3MOV R0,#19HDJNZ R1,TSR3#pragma endasm}void Delay_4s(void) //延时 4s{#pragma asmMOV R2,#28HTSR5:MOV R0,#0FAHMOV R1,#0C8HTSR4:DJNZ R0,TSR4MOV R0,#0FAHDJNZ R1,TSR4DJNZ R2,TSR5#pragma endasm}