找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机DS18B20温度控制系统代码与Proteus仿真原理图 按键控制报警值

[复制链接]
跳转到指定楼层
楼主
单片机+DS18b20完成温度监测系统设计,1602液晶显示器显示温度数据和温度报警数据,按键控制报警值.

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include<reg51.h>   
  2. #include<intrins.h>  //定义_nop_()函数的头文件
  3. #include"lcd1602.h"
  4. #define uchar unsigned char   
  5. #define uint unsigned int

  6. int f;           //定义正 负温度标志
  7. unsigned char code str1[]={"T :"};
  8. unsigned char code str2[]={"T Alarm:"};
  9. unsigned char code digit[10]={"0123456789"};     //定义字符数组显示的数字
  10. unsigned char code Cent[]={0xdf,"C"};           //显示温度单位为摄氏度

  11. sbit DQ=P3^3;                //DS18B20的DQ端与P3.3脚相连


  12. sbit key_up=P1^0;         //报警值增加按键
  13. sbit key_down=P1^1;         //报警值减小按键

  14. sbit led=P1^6;


  15. /*******************DS18B20延时函数****************************/
  16. void Delay_DS(int num)
  17. {
  18.     while(num--) ;
  19. }


  20. //DS18B20驱动程序
  21. /************************************************************/
  22. void Init_DS18B20(void)//初始化ds18b20
  23. {
  24.         DQ = 0;    //单片机将DQ拉低
  25.         Delay_DS(80);   //精确延时 大于 480us
  26.         DQ = 1;    //拉高总线
  27.         Delay_DS(14);
  28.         Delay_DS(20);
  29. }

  30. /******************************************************************************/
  31. unsigned char ReadOneChar(void)//读一个字节
  32. {
  33.         unsigned char i=0;
  34.         unsigned char dat = 0;
  35.         for (i=8;i>0;i--)
  36.         {
  37.                 DQ = 0; // 给脉冲信号
  38.                 DQ=dat>>=1;        
  39.                 DQ = 1; // 给脉冲信号
  40.                 if(DQ)
  41.                 dat|=0x80;
  42.                 Delay_DS(4);
  43.         }
  44.         return(dat);
  45. }

  46. /******************************************************************************/
  47. void WriteOneChar(unsigned char dat)//写一个字节
  48. {
  49.         unsigned char i=0;
  50.         for (i=8; i>0; i--)
  51.         {
  52.                 DQ = 0;
  53.                 DQ = dat&0x01;
  54.                 Delay_DS(5);
  55.                 DQ = 1;
  56.                 dat>>=1;
  57.         }
  58. }
  59. /******************************************************************************/
  60. unsigned int ReadTemperature(void)//读取温度
  61. {
  62.     unsigned char a=0;
  63.     unsigned char b=0;
  64.     unsigned int t=0;
  65.     float tt=0;
  66.     Init_DS18B20();
  67.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  68.         WriteOneChar(0x44); // 启动温度转换      
  69.         Init_DS18B20();
  70.         WriteOneChar(0xCC); //跳过读序号列号的操作
  71.         WriteOneChar(0xBE); //读取温度寄存器     
  72.         a=ReadOneChar();    //读低8位            
  73.         b=ReadOneChar();    //读高8位            
  74.    
  75. //        t = ((a&0xf0)>>4) | ((b&0x07)<<4);
  76. /*        t=b;
  77.     t<<=8;
  78.     t=t|a;
  79.     tt=t*0.0625;
  80.     t= tt*10+0.5; //放大10倍输出并四舍五入*/

  81.         t=b;
  82.         t <<= 8;
  83.         t = t | a;         //将LSB和MSB整合成为一个16位的整数
  84.         //首先通过温度数据的高5位判断采用结果是正温度还是负温度
  85.         if((t & 0xf800) == 0x0000)    //正温度的处理办法
  86.         {
  87.                 t >>= 4;         //取出温度结果的整数部分
  88.                 t = t*10;    //放大10倍,然后加上小数部分
  89.                 t = t + (a&0x0f)*0.625;        //保留1位小数
  90.                 f=0;
  91.         }
  92.         else if((t & 0xf800)== 0xf800)        //负温度的处理办法
  93.         {
  94.                 t=~t+1;           //负数补码运算,取反之后+1
  95.                 t >>= 4;         //取出温度结果的整数部分
  96.                 t = t*10;    //放大10倍,然后加上小数部分
  97.                 t = t + (a&0x0f)*0.625;
  98.                 f=1;

  99.         }
  100.     return t;
  101.         return f;
  102. }

  103. void main()
  104. {
  105.         uchar n,m=0;
  106.         int i;
  107.         int alarm=0;
  108.         lcd_init();
  109.         lcd_wcom(0x80);   //显示地址设为80H(即00H,)上排第一位         
  110.         for(m=0;m<3;m++)     //将table[]中的数据依次写入1602显示     
  111.         {               
  112.                 lcd_wdat(str1[m]);   
  113.                 delay(200);     
  114.         }
  115.         lcd_wcom(0x80+0x40); //重新设定显示地址为0xc4,即下排第5位     

  116.         for(n=0;n<8;n++)   //将table1[]中的数据依次写入1602显示     
  117.         {                  
  118.                 lcd_wdat(str2[n]);            
  119.                 delay(200);     
  120.         }

  121.         
  122. while(1)
  123. {

  124.         i=ReadTemperature(); /*读取当前温度*/
  125.         if(f==0)
  126.         {
  127.         lcd_wcom(0x80+0x05); //第一行显示当前温度
  128.         lcd_wdat(digit[i/1000]);
  129.         lcd_wdat(digit[i/100%10]);
  130.         lcd_wdat(digit[i%100/10]);
  131.         lcd_wdat('.');
  132.         lcd_wdat(digit[i%10]);
  133.         lcd_wdat(Cent[0]);        
  134.         lcd_wdat(Cent[1]);

  135.         lcd_wcom(0x80+0x49);  //第二行显示报警值
  136.         lcd_wdat(digit[alarm/10]);
  137.         lcd_wdat(digit[alarm%10]);
  138.         lcd_wdat(Cent[0]);        
  139.         lcd_wdat(Cent[1]);
  140.         }
  141.         else if(f==1)
  142.         {
  143.         lcd_wcom(0x80+0x05); //第一行显示当前温度
  144.         lcd_wdat('-');
  145.         lcd_wdat(digit[i/1000]);
  146.         lcd_wdat(digit[i/100%10]);
  147.         lcd_wdat(digit[i%100/10]);
  148.         lcd_wdat('.');
  149.         lcd_wdat(digit[i%10]);
  150.         lcd_wdat(Cent[0]);        
  151.         lcd_wdat(Cent[1]);

  152.         lcd_wcom(0x80+0x49);  //第二行显示报警值
  153.         lcd_wdat(digit[alarm/10]);
  154.         lcd_wdat(digit[alarm%10]);
  155.         lcd_wdat(Cent[0]);        
  156.         lcd_wdat(Cent[1]);        
  157.         }

  158.         if(key_up==0)   //报警值增加
  159.         {
  160.                 delay(10);
  161.                 if(key_up==0)
  162.                 {
  163.                         while(key_up==0);
  164.                         alarm++;
  165.                 }
  166.         }
  167.                 if(key_down==0)         //报警值减少
  168.         {
  169.                 delay(10);
  170.                 if(key_down==0)
  171.                 {
  172.                         while(key_down==0);
  173.                         if(alarm>0)
  174.                         {
  175.                         alarm--;
  176.                         }
  177.                         else
  178.                         alarm=0;
  179.                 }
  180.         }
  181.         
  182.         if(f==0&&i/10>alarm)        //超过报警值,报警灯亮
  183.         {
  184.                 led=0;
  185.         }
  186.         else if(f==1||i/10<alarm)
  187.         {
  188.         led=1;
  189.         }        
  190.         
  191. }   
  192. }
复制代码

Keil代码与Proteus仿真下载:
DS18B20例程.7z (1.11 MB, 下载次数: 94)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:262 发表于 2022-4-27 22:46 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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