经典温度检测程序,亲测可用
电路原理图如下:
元件清单
1) 万用板
2) 单片机
3) 40脚IC座
4) LCD1602液晶
5) 16P排母座
6) 16P排针
7) TLC2543
8) 20脚ic座
9) 热敏电阻
10) 2p排座
11) 1K电阻*2
12) 2K电阻
13) 10k电阻*2
14) 104电容
15) 10uf电容
16) 30pf电容*2
17) 12M晶振
18) 轻触按键*4
19) 8550三极管
20) 蜂鸣器
21) 5mm LED灯(红色)
22) 5mm LED灯(绿色)
23) 103电位器
24) 自锁开关
25) DC电源插口
26) 焊锡若干
27) 导线若干
28) USB电源线或电池盒
单片机源程序如下:
- #include<reg52.h> //头文件
- #include<intrins.h>
- #include"eeprom.h" //调用STC89C52单片机的EEPROM控制程序
- #include "math.h"
- #define uchar unsigned char //宏定义
- #define uint unsigned int //宏定义
- #define ulong unsigned long //宏定义
- #define LCD1602_dat P0 //LCD1602的数据传输IO口
- sbit LCD1602_rs = P2^5; //LCD1602命令数据控制IO
- sbit LCD1602_rw = P2^6; //LCD1602读写IO控制
- sbit LCD1602_e = P2^7; //数据脉冲输入
- sbit beep=P2^4; //蜂鸣器IO
- sbit led_1=P2^1; //超上限指示灯
- sbit led_2=P2^0; //超下限指示灯
- sbit key_1=P3^2;//设置按键
- sbit key_2=P3^3;//加按键
- sbit key_3=P3^4;//减按键
- sbit TCL2543_EOC = P1^0; //转换结束标志IO口
- sbit TCL2543_CLK = P1^1; //I/O时钟输入
- sbit TCL2543_ADIN = P1^2; //串行数据输入端
- sbit TCL2543_DOUT = P1^3; //串行数据输出端
- sbit TCL2543_CS = P1^4; //片选脚IO
- float zhi; //暂存读取的输入变量
- int temp; //读取DS18B20的温度数据
- char temp_h,temp_l; //温度上下限制存储变量
- uchar state,ms; //系统设置项变量、50ms定时变量
- bit s1,beep1; //设置闪烁标志位、报警标志位
- ulong AD,AD_Data=0;
- uint num;
- void delay(uint T) //系统延时程序
- {
- while(T--);
- }
- /******************把数据保存到单片机内部eeprom中******************/
- void write_eeprom()
- {
- SectorErase(0x2000); //清空
- byte_write(0x2000,temp_h);
- byte_write(0x2001,temp_l);
- byte_write(0x2060,a_a);
- }
- /******************把数据从单片机内部eeprom中读出来*****************/
- void read_eeprom()
- {
- temp_h=byte_read(0x2000);
- temp_l=byte_read(0x2001);
- a_a = byte_read(0x2060);
- }
- /**************开机自检eeprom初始化*****************/
- void init_eeprom()
- {
- read_eeprom();
- if(a_a != 1||key_2==0) //新的单片机初始单片机内问eeprom
- {
- temp_h=35;
- temp_l=15;
-
- a_a = 1;
- write_eeprom(); //保存数据
- }
- }
- // 其中 port 为通道: 通道0:port = 0x01 通道1:port = 0x02 通道2:port = 0x04 ...
- // 片子操作文本地址 http://wenku.baidu.com/link?url=WTp8rj93fYDbqM6kYbynkqTrI5MGQFQGtgk6aDrMMdfcB0K2Q9HIrVOs-SSSCLUMOKLOS31ENJAadBSdrVMHg_YxXPYcXWC7T0rb-rINptW
- uint read2543(unsigned char port) //读取TCL2543对应模拟输入口的AD数据,并返回数据
- {
- unsigned int i; //上电时,EOC=“1”,CS=“1”
- uint ad_value=0;
- TCL2543_CLK=0;
- TCL2543_CS=0; //使能TCL2543片选
- TCL2543_EOC=1;
- port<<=4;
- for(i=0;i<12;i++) //读取12位的模拟量的数字数据
- {
- if(TCL2543_DOUT) ad_value|=0x01; //前次转换结果的MSB即A11位数据输出到Dout供读数
- TCL2543_ADIN=(bit)(port&0x80);
- TCL2543_CLK=1; //
- _nop_();
- _nop_();
- _nop_();
- TCL2543_CLK=0;
- _nop_();
- _nop_();
- _nop_();
- port=port<<1;
- ad_value=ad_value<<1;
- }
- TCL2543_CS=1; //锁定片子
- ad_value=ad_value>>1;
- return ad_value; //返回读取的AD值
- }
- /********************************************************************
- * 名称 : LCD1602_write(uchar order,dat)
- * 功能 : 1602写如数据函数
- * 输入 : 输入的命令值
- * 输出 : 无
- ***********************************************************************/
- void LCD1602_write(uchar order,dat) //1602 一个字节 处理
- {
- LCD1602_e=0;
- LCD1602_rs=order;
- LCD1602_dat=dat;
- LCD1602_rw=0;
- LCD1602_e=1;
- delay(1);
- LCD1602_e=0;
- }
- /********************************************************************
- * 名称 : LCD1602_writebye(uchar *prointer)
- * 功能 : 1602写入数据函数 指针式
- * 输入 : 输入的命令值
- * 输出 : 无
- ***********************************************************************/
- void LCD1602_writebyte(uchar *prointer) //1602 字符串 处理
- {
- while(*prointer!='\0')
- {
- LCD1602_write(1,*prointer);
- prointer++;
- }
- }
- /********************************************************************
- * 名称 : LCD1602_cls()
- * 功能 : 初始化1602液晶
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void LCD1602_cls() //1602 初始化
- {
- LCD1602_write(0,0x01); //1602 清屏 指令
- delay(1500);
- LCD1602_write(0,0x38); // 功能设置 8位、5*7点阵
- delay(1500);
- LCD1602_write(0,0x0c); //设置 光标 不显示开关、不显示光标、字符不闪烁
- LCD1602_write(0,0x06);
- LCD1602_write(0,0xd0);
- delay(1500);
- }
- /********************************************************************
- * 名称 : show()
- * 功能 : LCD1602液晶显示程序
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void show() //显示数据
- {
- LCD1602_write(0,0x80); //显示位置设定
- LCD1602_writebyte("Temp:"); //显示当前温度值
- if(temp>=0) //显示温度整数部分
- {
- if(temp>999)LCD1602_write(1,0x30+temp/1000%10);
- else LCD1602_writebyte(" ");
- if(temp>99)LCD1602_write(1,0x30+temp/100%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+temp/10%10);
- LCD1602_writebyte(".");
- LCD1602_write(1,0x30+temp%10);
- }else
- {
- LCD1602_writebyte("-"); //显示温度负数部分
- if(temp*-1>99)LCD1602_write(1,0x30+(temp*-1)/10%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+(temp*-1)%10);
- LCD1602_writebyte(".");
- LCD1602_write(1,0x30+temp%10);
- }
- LCD1602_write(1,0xdf);
- LCD1602_writebyte("C ");
- LCD1602_write(0,0xC0); //第二行显示温度上下限值
- LCD1602_writebyte("H:");
- if(state==1&&s1==1) //对应设置项设置时闪烁控制 //上限
- {
- LCD1602_writebyte(" ");
- }else //显示上限值
- {
- if(temp_h>=0)
- {
- if(temp_h>99)LCD1602_write(1,0x30+temp_h/100%10);
- else LCD1602_writebyte(" ");
- if(temp_h>9)LCD1602_write(1,0x30+temp_h/10%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+temp_h%10);
- }else
- {
- LCD1602_writebyte("-");
- if(temp_h*-1>9)LCD1602_write(1,0x30+(temp_h*-1)/10%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+(temp_h*-1)%10);
- }
- }
- LCD1602_write(1,0xdf);
- LCD1602_writebyte("C L:");
- if(state==2&&s1==1) //对应设置项设置时闪烁控制 //下限
- {
- LCD1602_writebyte(" ");
- }else
- {
- if(temp_l>=0) //显示下限值
- {
- if(temp_l>99)LCD1602_write(1,0x30+temp_l/100%10);
- else LCD1602_writebyte(" ");
- if(temp_l>9)LCD1602_write(1,0x30+temp_l/10%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+temp_l%10);
- }else
- {
- LCD1602_writebyte("-");
- if(temp_l*-1>9)LCD1602_write(1,0x30+(temp_l*-1)/10%10);
- else LCD1602_writebyte(" ");
- LCD1602_write(1,0x30+(temp_l*-1)%10);
- }
- }
- LCD1602_write(1,0xdf);
- LCD1602_writebyte("C");
-
- }
- /********************************************************************
- * 名称 : proc()
- * 功能 : 系统指示灯与报警处理
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void proc()
- {
- if(temp>temp_h*10) //如果当前温度高于上限温度
- {
- led_1=0; //对应指示灯点亮
- }else //否则 熄灭
- {
- led_1=1;
- }
- if(temp<temp_l*10) //如果当前温度低于下限温度
- {
- led_2=0; //对应指示灯点亮
- }else //否则 熄灭
- {
- led_2=1;
- }
- if(temp>temp_h*10||temp<temp_l*10) //如果当前温度 值不处于 上下限温度之间 这报警标志位值1 反之 置0
- {
- beep1=1; //开始报警
- }else
- {
- beep1=0; //停止报警
- }
- }
- /********************************************************************
- * 名称 : key()
- * 功能 : 系统控制按键控制检测程序
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void key()
- {
- if(!key_1) //判断按键是否按下
- {
- delay(888); //延时去抖
- if(!key_1) //再次判断按键是否按下
- {
- state=(state+1)%3; //切换设置项
- while(!key_1); //按键判断释放
- }
- }
- if(state!=0) //如果系统非设置状态 则
- {
- if(!key_2) //判断按键是否按下//如果加按键按下
- {
- delay(888); //延时去抖
- if(!key_2) //再次判断按键是否按下
- {
- while(!key_2) show(); //按键判断释放
- switch(state) //判断当前设置项
- {
- case 1: //如果是上限设置
- if(temp_h<99)temp_h++;
- break;
- case 2: //如果是下限设置
- if(temp_h>temp_l+1)temp_l++;
- break;
- }
- write_eeprom();
- }
- }
- if(!key_3) //判断按键是否按下 如果减按键按下
- {
- delay(888); //延时去抖
- if(!key_3) //再次判断按键是否按下
- {
- while(!key_3) show(); //按键判断释放
- switch(state) //判断当前设置项
- {
- case 1: //如果是上限设置
- if(temp_h>temp_l+1)temp_h--;
- break;
- case 2: //如果是下限设置
- if(temp_l>-40)temp_l--;
- break;
- }
- write_eeprom();
- }
- }
- }
- }
- /********************************************************************
- * 名称 : float TempCalculate(float Rx,float B,float Revise,float BasicRx)
- * 功能 : 根据当前热敏电阻的阻值、以及参数、通过Sin曲线求出当前系统的温度值 并返回浮点型的温度值
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- float TempCalculate(float Rx,float B,float Revise,float BasicRx){
- /*
- Rx: 热敏电阻当前阻值
- B: 热敏电阻参数B值
- Revise: 校正温度
- BasicRx: 热敏电阻25度时电阻(标称电阻数值)
- 返回: 摄氏度
- */
- Rx = Rx / BasicRx;
-
- Rx = log(Rx);
-
- Rx = (Rx) / B;
-
- Rx = Rx + 0.003356;
- Rx = 1 / Rx;
- Rx = Rx - 273.13;
- Rx = Rx + Revise;
-
-
- return Rx;
-
- }
- /********************************************************************
- * 名称 : void main()
- * 功能 : 系统主程序
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void main()
- {
- float Rad; //生成运算暂存变量
- LCD1602_cls();//LCD1602初始化程序调用
- TMOD=0x01; //定时器0初始化配置
- TH0=0x4c;
- TL0=0x00; //定时初值赋值
- ET0=1; //定时器0中断打开
- TR0=1; //打开定时器0
- EA=1; //打开总中断
- init_eeprom();
- while(1)
- {
- num++;
- AD=read2543(0);
- AD_Data=AD_Data+AD;
- if(num>=30)
- {
- num=0;
- AD_Data=AD_Data/30;
- zhi=(float)AD_Data/819.0; //计算电压值
- // zhi=(float)read2543(0)/819.0; //计算电压值
- Rad=zhi/((5.0-zhi)/10000.0); //计算热敏电阻当前阻值
- //temp=(int)((temp * 0.2) +(TempCalculate(Rad,600.0,0,630) * 0.5)*10);//求出当前系统的当前温度
- temp=(int)((0.19*Rad-86)*10);//求出当前系统的当前温度
- // temp=Rad;
- AD_Data=0;
- }
- show(); //显示函数
- key(); //按键处理程序
- proc(); //超限处理程序
- }
- }
- /********************************************************************
- * 名称 : void UART_1() interrupt 1
- * 功能 : 定时器0中断服务程序
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void UART_1() interrupt 1
- {
- TH0=0x4c; //重新赋值
- TL0=0x00;
- ms++; //50ms定时变量计时
- if(ms%5==0) //区分250ms定时
- {
- s1=!s1; //闪烁标志位切换
- if(beep1==1) beep=!beep; //判断报警标志位是否报警
- else beep=1;
- }
- if(ms>19) //1s定时
- {
- ms=0;
- }
- }
复制代码
所有资料51hei提供下载:
温度检测资料.7z
(46.05 KB, 下载次数: 104)
|