找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3857|回复: 1
收起左侧

51单片机+TLC2543+热敏电阻温度检测源程序加电路原理图

[复制链接]
ID:327562 发表于 2020-3-18 09:44 | 显示全部楼层 |阅读模式
经典温度检测程序,亲测可用
电路原理图如下:
0.jpg
元件清单
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电源线或电池盒

单片机源程序如下:
  1. #include<reg52.h>                                 //头文件
  2. #include<intrins.h>
  3. #include"eeprom.h"                  //调用STC89C52单片机的EEPROM控制程序
  4. #include "math.h"
  5. #define uchar unsigned char                 //宏定义
  6. #define uint unsigned int                 //宏定义
  7. #define ulong unsigned long                 //宏定义

  8. #define LCD1602_dat P0                         //LCD1602的数据传输IO口


  9. sbit LCD1602_rs = P2^5; //LCD1602命令数据控制IO
  10. sbit LCD1602_rw = P2^6; //LCD1602读写IO控制
  11. sbit LCD1602_e  = P2^7;  //数据脉冲输入

  12. sbit beep=P2^4;         //蜂鸣器IO
  13. sbit led_1=P2^1; //超上限指示灯
  14. sbit led_2=P2^0; //超下限指示灯

  15. sbit key_1=P3^2;//设置按键
  16. sbit key_2=P3^3;//加按键
  17. sbit key_3=P3^4;//减按键


  18. sbit TCL2543_EOC  = P1^0;         //转换结束标志IO口
  19. sbit TCL2543_CLK  = P1^1;        //I/O时钟输入
  20. sbit TCL2543_ADIN = P1^2;         //串行数据输入端
  21. sbit TCL2543_DOUT = P1^3;  //串行数据输出端
  22. sbit TCL2543_CS   = P1^4;         //片选脚IO


  23. float zhi;        //暂存读取的输入变量

  24. int temp;        //读取DS18B20的温度数据
  25. char temp_h,temp_l;        //温度上下限制存储变量
  26. uchar state,ms;           //系统设置项变量、50ms定时变量

  27. bit s1,beep1;        //设置闪烁标志位、报警标志位

  28. ulong AD,AD_Data=0;
  29. uint num;

  30. void delay(uint T)                //系统延时程序
  31. {
  32.         while(T--);
  33. }


  34. /******************把数据保存到单片机内部eeprom中******************/
  35. void write_eeprom()
  36. {
  37.         SectorErase(0x2000);                          //清空
  38.         byte_write(0x2000,temp_h);
  39.         byte_write(0x2001,temp_l);
  40.         byte_write(0x2060,a_a);        
  41. }

  42. /******************把数据从单片机内部eeprom中读出来*****************/
  43. void read_eeprom()
  44. {
  45.         temp_h=byte_read(0x2000);
  46.         temp_l=byte_read(0x2001);
  47.         a_a = byte_read(0x2060);
  48. }

  49. /**************开机自检eeprom初始化*****************/
  50. void init_eeprom()
  51. {
  52.         read_eeprom();
  53.         if(a_a != 1||key_2==0)                //新的单片机初始单片机内问eeprom
  54.         {
  55.                 temp_h=35;
  56.                 temp_l=15;
  57.                
  58.                 a_a = 1;
  59.                 write_eeprom();           //保存数据
  60.         }        
  61. }



  62. // 其中 port 为通道: 通道0:port = 0x01 通道1:port = 0x02 通道2:port = 0x04 ...
  63. //    片子操作文本地址    http://wenku.baidu.com/link?url=WTp8rj93fYDbqM6kYbynkqTrI5MGQFQGtgk6aDrMMdfcB0K2Q9HIrVOs-SSSCLUMOKLOS31ENJAadBSdrVMHg_YxXPYcXWC7T0rb-rINptW
  64. uint read2543(unsigned char port) //读取TCL2543对应模拟输入口的AD数据,并返回数据
  65. {  
  66.         unsigned int i;  //上电时,EOC=“1”,CS=“1”
  67.         uint ad_value=0;  
  68.         TCL2543_CLK=0;   
  69.         TCL2543_CS=0;   //使能TCL2543片选
  70.         TCL2543_EOC=1;   
  71.         port<<=4;   
  72.         for(i=0;i<12;i++)      //读取12位的模拟量的数字数据
  73.         {  
  74.                 if(TCL2543_DOUT) ad_value|=0x01;  //前次转换结果的MSB即A11位数据输出到Dout供读数  
  75.                 TCL2543_ADIN=(bit)(port&0x80);   
  76.                 TCL2543_CLK=1;    //
  77.                 _nop_();  
  78.                 _nop_();   
  79.                 _nop_();  
  80.                 TCL2543_CLK=0;   
  81.                 _nop_();   
  82.                 _nop_();  
  83.                 _nop_();  
  84.                 port=port<<1;  
  85.                 ad_value=ad_value<<1;   
  86.         }
  87.         TCL2543_CS=1;   //锁定片子
  88.         ad_value=ad_value>>1;   
  89.         return ad_value;          //返回读取的AD值
  90. }
  91. /********************************************************************
  92. * 名称 : LCD1602_write(uchar order,dat)
  93. * 功能 : 1602写如数据函数
  94. * 输入 : 输入的命令值
  95. * 输出 : 无
  96. ***********************************************************************/
  97. void LCD1602_write(uchar order,dat)                                  //1602 一个字节  处理
  98. {
  99.     LCD1602_e=0;
  100.     LCD1602_rs=order;
  101.     LCD1602_dat=dat;
  102.     LCD1602_rw=0;
  103.     LCD1602_e=1;
  104.     delay(1);
  105.     LCD1602_e=0;                                                                                                                                                                                                     
  106. }
  107. /********************************************************************
  108. * 名称 : LCD1602_writebye(uchar *prointer)
  109. * 功能 : 1602写入数据函数  指针式
  110. * 输入 : 输入的命令值
  111. * 输出 : 无
  112. ***********************************************************************/
  113. void LCD1602_writebyte(uchar *prointer)                                   //1602 字符串    处理
  114. {
  115.     while(*prointer!='\0')
  116.     {
  117.         LCD1602_write(1,*prointer);
  118.         prointer++;
  119.     }
  120. }
  121. /********************************************************************
  122. * 名称 : LCD1602_cls()
  123. * 功能 : 初始化1602液晶
  124. * 输入 : 无
  125. * 输出 : 无
  126. ***********************************************************************/
  127. void LCD1602_cls()                                                                         //1602 初始化
  128. {
  129.         LCD1602_write(0,0x01);     //1602 清屏 指令
  130.         delay(1500);
  131.         LCD1602_write(0,0x38);     // 功能设置 8位、5*7点阵
  132.         delay(1500);
  133.         LCD1602_write(0,0x0c);     //设置 光标   不显示开关、不显示光标、字符不闪烁
  134.         LCD1602_write(0,0x06);
  135.         LCD1602_write(0,0xd0);
  136.         delay(1500);
  137. }

  138. /********************************************************************
  139. * 名称 : show()
  140. * 功能 : LCD1602液晶显示程序
  141. * 输入 : 无
  142. * 输出 : 无
  143. ***********************************************************************/
  144. void show()                        //显示数据
  145. {

  146.                 LCD1602_write(0,0x80);                   //显示位置设定
  147.                 LCD1602_writebyte("Temp:");                //显示当前温度值
  148.                 if(temp>=0)                         //显示温度整数部分
  149.                 {
  150.                            if(temp>999)LCD1602_write(1,0x30+temp/1000%10);           
  151.                         else LCD1602_writebyte(" ");
  152.                         if(temp>99)LCD1602_write(1,0x30+temp/100%10);
  153.                         else LCD1602_writebyte(" ");
  154.                         LCD1602_write(1,0x30+temp/10%10);
  155.                         LCD1602_writebyte(".");
  156.                            LCD1602_write(1,0x30+temp%10);
  157.                 }else
  158.                 {
  159.                         LCD1602_writebyte("-");          //显示温度负数部分
  160.                         if(temp*-1>99)LCD1602_write(1,0x30+(temp*-1)/10%10);
  161.                         else LCD1602_writebyte(" ");
  162.                         LCD1602_write(1,0x30+(temp*-1)%10);        
  163.                         LCD1602_writebyte(".");
  164.                            LCD1602_write(1,0x30+temp%10);
  165.                 }
  166.                 LCD1602_write(1,0xdf);
  167.                 LCD1602_writebyte("C  ");



  168.                  LCD1602_write(0,0xC0);         //第二行显示温度上下限值
  169.                 LCD1602_writebyte("H:");
  170.                 if(state==1&&s1==1)                  //对应设置项设置时闪烁控制   //上限
  171.                 {
  172.                         LCD1602_writebyte("   ");
  173.                 }else                                           //显示上限值
  174.                 {
  175.                         if(temp_h>=0)
  176.                         {
  177.                                    if(temp_h>99)LCD1602_write(1,0x30+temp_h/100%10);
  178.                                 else LCD1602_writebyte(" ");
  179.                                 if(temp_h>9)LCD1602_write(1,0x30+temp_h/10%10);
  180.                                 else LCD1602_writebyte(" ");
  181.                                 LCD1602_write(1,0x30+temp_h%10);
  182.                         }else
  183.                         {
  184.                                 LCD1602_writebyte("-");
  185.                                 if(temp_h*-1>9)LCD1602_write(1,0x30+(temp_h*-1)/10%10);
  186.                                 else LCD1602_writebyte(" ");
  187.                                 LCD1602_write(1,0x30+(temp_h*-1)%10);        
  188.                         }
  189.                 }
  190.                 LCD1602_write(1,0xdf);
  191.                 LCD1602_writebyte("C L:");
  192.                 if(state==2&&s1==1)          //对应设置项设置时闪烁控制   //下限
  193.                 {
  194.                         LCD1602_writebyte("   ");
  195.                 }else
  196.                 {
  197.                         if(temp_l>=0)                  //显示下限值
  198.                         {
  199.                                    if(temp_l>99)LCD1602_write(1,0x30+temp_l/100%10);
  200.                                 else LCD1602_writebyte(" ");
  201.                                 if(temp_l>9)LCD1602_write(1,0x30+temp_l/10%10);
  202.                                 else LCD1602_writebyte(" ");
  203.                                 LCD1602_write(1,0x30+temp_l%10);
  204.                         }else
  205.                         {
  206.                                 LCD1602_writebyte("-");
  207.                                 if(temp_l*-1>9)LCD1602_write(1,0x30+(temp_l*-1)/10%10);
  208.                                 else LCD1602_writebyte(" ");
  209.                                 LCD1602_write(1,0x30+(temp_l*-1)%10);        
  210.                         }
  211.                 }
  212.                 LCD1602_write(1,0xdf);
  213.                 LCD1602_writebyte("C");
  214.         
  215. }

  216. /********************************************************************
  217. * 名称 : proc()
  218. * 功能 : 系统指示灯与报警处理
  219. * 输入 : 无
  220. * 输出 : 无
  221. ***********************************************************************/
  222. void proc()
  223. {
  224.         if(temp>temp_h*10)         //如果当前温度高于上限温度
  225.         {
  226.                 led_1=0;          //对应指示灯点亮
  227.         }else                        //否则  熄灭
  228.         {
  229.                 led_1=1;         
  230.         }
  231.         if(temp<temp_l*10)        //如果当前温度低于下限温度
  232.         {
  233.                 led_2=0;          //对应指示灯点亮
  234.         }else                          //否则  熄灭
  235.         {
  236.                 led_2=1;        
  237.         }

  238.         if(temp>temp_h*10||temp<temp_l*10)         //如果当前温度 值不处于  上下限温度之间  这报警标志位值1   反之  置0   
  239.         {
  240.                 beep1=1;  //开始报警
  241.         }else
  242.         {
  243.                 beep1=0;  //停止报警
  244.         }
  245. }

  246. /********************************************************************
  247. * 名称 : key()
  248. * 功能 : 系统控制按键控制检测程序
  249. * 输入 : 无
  250. * 输出 : 无
  251. ***********************************************************************/
  252. void key()
  253. {

  254.         if(!key_1)        //判断按键是否按下
  255.         {
  256.                 delay(888);         //延时去抖
  257.                 if(!key_1)        //再次判断按键是否按下
  258.                 {
  259.                         state=(state+1)%3;                //切换设置项
  260.                         while(!key_1);                   //按键判断释放
  261.                 }
  262.         }
  263.         if(state!=0)                //如果系统非设置状态   则
  264.         {
  265.                 if(!key_2)                //判断按键是否按下//如果加按键按下  
  266.                 {
  267.                         delay(888);           //延时去抖
  268.                         if(!key_2)        //再次判断按键是否按下
  269.                         {
  270.                                 while(!key_2) show();  //按键判断释放
  271.                                 switch(state) //判断当前设置项
  272.                                 {
  273.                                         case 1:                                  //如果是上限设置
  274.                                         if(temp_h<99)temp_h++;
  275.                                         break;
  276.                                         case 2:                     //如果是下限设置
  277.                                         if(temp_h>temp_l+1)temp_l++;        
  278.                                         break;
  279.                                 }
  280.                                 write_eeprom();
  281.                         }
  282.                 }
  283.                 if(!key_3)        //判断按键是否按下  如果减按键按下
  284.                 {
  285.                         delay(888);         //延时去抖
  286.                         if(!key_3)         //再次判断按键是否按下
  287.                         {
  288.                                 while(!key_3) show();  //按键判断释放
  289.                                 switch(state)         //判断当前设置项
  290.                                 {
  291.                                         case 1:                             //如果是上限设置
  292.                                         if(temp_h>temp_l+1)temp_h--;
  293.                                         break;
  294.                                         case 2:                           //如果是下限设置
  295.                                         if(temp_l>-40)temp_l--;
  296.                                         break;
  297.                                 }
  298.                                 write_eeprom();
  299.                         }
  300.                 }
  301.         }
  302. }


  303. /********************************************************************
  304. * 名称 : float TempCalculate(float Rx,float B,float Revise,float BasicRx)
  305. * 功能 : 根据当前热敏电阻的阻值、以及参数、通过Sin曲线求出当前系统的温度值  并返回浮点型的温度值
  306. * 输入 : 无
  307. * 输出 : 无
  308. ***********************************************************************/
  309. float TempCalculate(float Rx,float B,float Revise,float BasicRx){
  310. /*

  311. Rx:  热敏电阻当前阻值
  312. B:   热敏电阻参数B值
  313. Revise:  校正温度
  314. BasicRx:  热敏电阻25度时电阻(标称电阻数值)


  315. 返回: 摄氏度

  316. */  


  317.     Rx = Rx / BasicRx;
  318.    
  319.     Rx = log(Rx);
  320.    
  321.     Rx = (Rx) / B;
  322.    
  323.     Rx = Rx + 0.003356;
  324.     Rx = 1 / Rx;
  325.     Rx = Rx - 273.13;  
  326.     Rx = Rx + Revise;
  327.    
  328.    
  329.     return Rx;
  330.   
  331. }
  332. /********************************************************************
  333. * 名称 : void main()
  334. * 功能 : 系统主程序
  335. * 输入 : 无
  336. * 输出 : 无
  337. ***********************************************************************/
  338. void main()
  339. {
  340.         float Rad;         //生成运算暂存变量
  341.         LCD1602_cls();//LCD1602初始化程序调用
  342.         TMOD=0x01;         //定时器0初始化配置
  343.         TH0=0x4c;
  344.         TL0=0x00;         //定时初值赋值
  345.         ET0=1;                //定时器0中断打开
  346.         TR0=1;           //打开定时器0
  347.         EA=1;                //打开总中断
  348.         init_eeprom();
  349.         while(1)
  350.         {
  351.                 num++;
  352.                 AD=read2543(0);
  353.                 AD_Data=AD_Data+AD;
  354.                 if(num>=30)
  355.                 {
  356.                         num=0;
  357.                         AD_Data=AD_Data/30;
  358.                         zhi=(float)AD_Data/819.0;  //计算电压值
  359. //                zhi=(float)read2543(0)/819.0;  //计算电压值
  360.                 Rad=zhi/((5.0-zhi)/10000.0);   //计算热敏电阻当前阻值
  361.                 //temp=(int)((temp * 0.2) +(TempCalculate(Rad,600.0,0,630) * 0.5)*10);//求出当前系统的当前温度
  362.                         temp=(int)((0.19*Rad-86)*10);//求出当前系统的当前温度
  363.                 //        temp=Rad;
  364.                         AD_Data=0;
  365.                 }

  366.                 show();                 //显示函数
  367.                 key();                 //按键处理程序
  368.                 proc();                 //超限处理程序
  369.         }
  370. }

  371. /********************************************************************
  372. * 名称 : void UART_1() interrupt 1
  373. * 功能 : 定时器0中断服务程序
  374. * 输入 : 无
  375. * 输出 : 无
  376. ***********************************************************************/
  377. void UART_1() interrupt 1
  378. {
  379.         TH0=0x4c;        //重新赋值
  380.         TL0=0x00;
  381.         ms++;          //50ms定时变量计时
  382.         if(ms%5==0)          //区分250ms定时
  383.         {
  384.                 s1=!s1;                //闪烁标志位切换
  385.                 if(beep1==1) beep=!beep;  //判断报警标志位是否报警   
  386.                 else        beep=1;
  387.         }

  388.         if(ms>19)        //1s定时
  389.         {
  390.                 ms=0;               
  391.         }
  392. }
复制代码

所有资料51hei提供下载:
温度检测资料.7z (46.05 KB, 下载次数: 102)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:849468 发表于 2021-11-22 18:52 来自手机 | 显示全部楼层
想问问求出当前温度那个公式哪来的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表