找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2571|回复: 1
打印 上一主题 下一主题
收起左侧

单片机温度传感器的显示、存储与传输程序

[复制链接]
跳转到指定楼层
楼主
使用DS18B20温度传感器采集温度,并将温度的值显示在LCD1602上,可以通过按键调整温度的阈值,当温度传感器的值在阈值之外,报警电路发出警报,在按键的时候可以将温度传感器的值数据保存在AT24C02中。可以通过串口将温度传感器的值上传到电脑的串口调试助手。
原理图如下:


单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include"lcd1602.h"
  4. #include"key.h"
  5. #include"timer0.h"
  6. #include"at24c02.h"
  7. #include"uart.h"
  8. #include"nixie.h"

  9. typedef unsigned char uchar;
  10. typedef unsigned int uint;

  11. sbit Bus=P3^7;//数据单总线
  12. sbit LED=P3^6;//LED报警灯

  13. void Delay10us(void);//10us延时函数
  14. void Delay600us(void);//600us延时子函数  
  15. void Delay(uint n);//LCD1602中延时子函数
  16. void Delay1ms(uint t);//t毫秒延时子函数

  17. void Init_Ds(void);//DS18B20初始化
  18. void Write_Ds(uchar com);//向DS18B20写入一字节
  19. uchar Read_Ds(void);//从DS18B20读出一字节
  20. uint Get_Tem(void);//获取温度值

  21. void Change(uint x);//把整型数值x转换为字符串
  22. void Write_com(uchar com);//写命令子函数
  23. void Write_dat(uchar dat);//写数据子函数
  24. void Init_1602(void);//LCD1602初始化子函数
  25. void Show(uchar x,uchar y,uchar *str);//LCD1602显示子函数


  26. uchar str[4];//储存转换值对应的字符串
  27. unsigned char KeyNum;
  28. char TLow,THigh;
  29. unsigned char t;            
  30. unsigned char second=1;      
  31. unsigned char minute;
  32. unsigned char hour;  


  33. void main()
  34. {        
  35.   unsigned int temp;
  36.         UART_Init();  //串口初始化
  37.         LED=0;
  38.   LCD_Init();
  39. //        THigh=AT24C02_ReadByte(0);        //读取温度阈值数据
  40. //        TLow=AT24C02_ReadByte(1);
  41.         if(THigh>125 || TLow<-55 || THigh<=TLow)
  42.         {
  43.                 THigh=25;                        //如果阈值非法,则设为默认值
  44.                 TLow=20;
  45.         }
  46.         LCD_ShowString(2,1,"TH:");
  47.         LCD_ShowString(2,9,"TL:");
  48.         LCD_ShowSignedNum(2,4,THigh,3);
  49.         LCD_ShowSignedNum(2,12,TLow,3);
  50.         while(1)
  51.         {
  52.                 KeyNum=Key();
  53.                 temp=Get_Tem();
  54.                 UART_SendByte(temp);        //串口发送温度值
  55.                 if(temp>THigh)                        //越界判断
  56.                         {
  57.                                 LED=1;
  58.                         }
  59.                         else if(temp<TLow)
  60.                         {
  61.                                 LED=1;
  62.                         }
  63.                         else
  64.                         {
  65.                                 LED=0;
  66.                         }
  67.           Change(temp);
  68.                 LCD_ShowString(1,1,"Temperature:");
  69.                 LCD_ShowString(1,13,str);
  70.                
  71.                 /*阈值判断及显示*/
  72.                 if(KeyNum)
  73.                 {
  74.                         if(KeyNum==1)        //K1按键,THigh自增
  75.                         {
  76.                                 THigh++;
  77.                                 if(THigh>125){THigh=125;}
  78.                         }
  79.                         if(KeyNum==2)        //K2按键,THigh自减
  80.                         {
  81.                                 THigh--;
  82.                                 if(THigh<=TLow){THigh++;}
  83.                         }
  84.                         if(KeyNum==3)        //K3按键,TLow自增
  85.                         {
  86.                                 TLow++;
  87.                                 if(TLow>=THigh){TLow--;}
  88.                         }
  89.                         if(KeyNum==4)        //K4按键,TLow自减
  90.                         {
  91.                                 TLow--;
  92.                                 if(TLow<-55){TLow=-55;}
  93.                         }
  94.                         LCD_ShowSignedNum(2,4,THigh,3);        //显示阈值数据
  95.                         LCD_ShowSignedNum(2,12,TLow,3);
  96.                         AT24C02_WriteByte(0,temp);                //写入到At24C02中保存
  97.                         Delay(20);
  98.                         AT24C02_WriteByte(1,THigh);
  99.                         Delay(20);
  100.                         AT24C02_WriteByte(1,TLow);
  101.                         Delay(20);
  102.         }

  103. }
  104. }

  105. /***************************************延时函数体**************************/
  106. void Delay10us(void)//10us延时函数
  107. {
  108.     unsigned char a,b;
  109.     for(b=1;b>0;b--)
  110.         for(a=1;a>0;a--);
  111. }
  112. void Delay600us(void)//600us延时函数
  113. {
  114.     unsigned char a,b;
  115.     for(b=119;b>0;b--)
  116.         for(a=1;a>0;a--);
  117. }
  118. void Delay1ms(uint t)//t毫秒延时函数
  119. {
  120.     unsigned char a,b;
  121.         uint i;
  122.         for(i=0;i<t;i++)
  123.             for(b=199;b>0;b--)
  124.                 for(a=1;a>0;a--);
  125. }

  126. /********************************DS18B20初始化函数*************************/
  127. void Init_Ds(void)//DS18B20初始化
  128. {
  129.         Bus=0;//主动拉低480-960us(此处选择600us)
  130.         Delay600us();
  131.         Bus=1;//释放总线,传感器15-60us后拉低总线
  132.         while(Bus);//等待传感器拉低;
  133.         while(!Bus);//度过传感器被拉低的时间(60-240us)后主动拉高
  134.         Bus=1;//主动拉高
  135. }
  136. /********************************向DS18B20写入一字节***********************/
  137. void Write_Ds(uchar com)//从低位开始写入
  138. {
  139.         uchar mask;
  140.         for(mask=0x01;mask!=0;mask<<=1)
  141.         {
  142.                 //该位为0,先拉低,15us后在拉高,并通过延时使整个周期为60us
  143.             //该位为1,先拉低并在15us内(此处选择5us)拉高,并通过延时使整个周期为60us        
  144.                 Bus=0;
  145.                 _nop_();_nop_();_nop_();_nop_();_nop_();//先拉低5us
  146.                 if((com&mask)==0)//该位是0
  147.                 {
  148.                         Bus=0;        
  149.                 }
  150.                 else//该位是1
  151.                 {
  152.                         Bus=1;               
  153.                 }
  154.                 Delay10us();Delay10us();Delay10us();Delay10us();Delay10us();;//延时60us
  155.                 _nop_();_nop_();_nop_();_nop_();_nop_();
  156.                 Bus=1;//拉高
  157.                 _nop_();_nop_();//写两个位之间至少有1us的间隔(此处选择2us)
  158.         }
  159. }
  160. /********************************从DS18B20读出一字节***********************/
  161. uchar Read_Ds(void)//先读的是低位,整个读周期至少为60us,但控制器采样要在15us内完成,相邻“位”之间至少间隔1us
  162. {
  163.         uchar value=0,mask;
  164.         for(mask=0x01;mask!=0;mask<<=1)
  165.         {
  166.                 Bus=0;//先把总线拉低超过1us(此处选择2us)后释放
  167.                 _nop_();_nop_();
  168.                 Bus=1;
  169.                 _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//再延时6us后读总线数据
  170.                 if(Bus==0)//如果该位是0
  171.                 {
  172.                         value&=(~mask);
  173.                 }
  174.                 else
  175.                 {
  176.                         value|=mask;
  177.                 }
  178.                 Delay10us();Delay10us();Delay10us();Delay10us();Delay10us();//再延时52us,凑够至少60us的采样周期
  179.                 _nop_();_nop_();
  180.                 Bus=1;
  181.                 _nop_();_nop_();//写两个位之间至少有1us的间隔(此处选择2us)
  182.         }
  183.         return value;        
  184. }
  185. /**********************************获取温度值函数***************************/
  186. uint Get_Tem(void)
  187. {
  188.         uint temp=0;
  189.         float tp;
  190.         uchar LSB=0,MSB=0;
  191.         Delay1ms(10);//延时10ms度过不稳定期

  192.         Init_Ds();//Ds18b20初始化
  193.         Delay1ms(1);
  194.         Write_Ds(0xcc);//跳过ROM寻址
  195.         Write_Ds(0x44);//启动一次温度转换
  196.         Delay1ms(1000);//延时1s等待转化

  197.         Init_Ds();//Ds18b20初始化
  198.         Delay1ms(1);
  199.         Write_Ds(0xcc);//跳过ROM寻址
  200.         Write_Ds(0xbe);//发送读值命令·
  201.         LSB=Read_Ds();
  202.         MSB=Read_Ds();
  203.         temp=MSB;
  204.         temp<<=8;
  205.         temp|=LSB;
  206.         tp=temp*0.0625;
  207.         temp=tp;
  208.         if(tp-temp>=0.5)
  209.         {
  210.                 temp+=1;
  211.         }
  212.         return temp;
  213. }
  214. /******************************把整型数据转换为字符串**********************/
  215. void Change(uint x)
  216. {
  217.         str[0]=x/100+48;
  218.         str[1]=(x/10)%10+48;
  219.         str[2]=x%10+48;
  220.         str[3]='\0';
  221. }
复制代码

仅供参考,如存在错误和不足之处,请大家回帖多多指教,切勿照搬,Keil代码下载:
代码.7z (32.55 KB, 下载次数: 27)

评分

参与人数 2黑币 +15 收起 理由
Zcc… + 5
admin + 10 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:987978 发表于 2023-5-23 12:52 | 只看该作者
楼主 仿真可以分享一下么
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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