找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机数字温度计仿真程序 带负温度显示

[复制链接]
跳转到指定楼层
楼主
功能说明

1.数码管显示 DS18B20设置的问题
2.报警设置初始值为30 上电默认30  K1按键按下进入报警温度设置 K2+温度 K3-温度 K4恢复显示

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


单片机源程序如下:
  1. #include "reg52.h"                       

  2. typedef unsigned int uint;          
  3. //对数据类型进行声明定义
  4. typedef unsigned char uchar;

  5. sbit beep = P1^5;

  6. sbit DSPORT        =P3^7;
  7. sbit LSA=P2^2;
  8. sbit LSB=P2^3;
  9. sbit LSC=P2^4;
  10. sbit K1=P3^0;
  11. sbit K2=P3^1;
  12. sbit K3=P3^2;
  13. sbit K4=P3^3;



  14. uint DisplayData[8];
  15. uint code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  16. uint warn = 30;
  17. uint tt = 30;//记录温度
  18. uint warns[8];

  19. void delay(uint i){        //延迟ius
  20.         while(i--);
  21. }

  22. //延迟函数
  23. void Delay1ms(uint y)
  24. {
  25.         uint x;
  26.         for( ; y>0; y--)
  27.         {
  28.                 for(x=110; x>0; x--);
  29.         }
  30. }

  31. //初始化函数
  32. uchar Ds18K20Init()
  33. {
  34.         uchar i;
  35.         DSPORT = 0;
  36.         //将总线拉低480us~960us
  37.         i = 73;       
  38.         while(i--);//延时642us
  39.         DSPORT = 1;
  40.         //然后拉高总线,如果DS18K20做出
  41.         //反应会将在15us~60us后总线拉低
  42.         i = 0;
  43.         while(DSPORT)       
  44.         {//等待DS18K20拉低总线
  45.                 Delay1ms(1);
  46.                 i++;
  47.                 if(i>5)//等待>5ms
  48.                 {
  49.                         return 0;//初始化失败
  50.                 }
  51.        
  52.         }
  53.         return 1;//初始化成功
  54. }

  55. //向传感器写字节
  56. void Ds18K20WriteByte(uchar dat)
  57. {
  58.         uint i, j;

  59.         for(j=0; j<8; j++)
  60.         {
  61.                 DSPORT = 0;                       
  62.                 //每写入一位数据之前先把总线拉低1us
  63.                 i++;
  64.                 DSPORT = dat & 0x01;  
  65.                 //然后写入一个数据,从最低位开始 0000 0001
  66.                 i=6;
  67.                 while(i--);
  68.                 //延时68us,持续时间最少60us
  69.                 DSPORT = 1;       
  70.                 //然后释放总线,至少1us给总线恢复时
  71.                 //间才能接着写入第二个数值
  72.                 dat >>= 1;       
  73.                 //传输完最低位,数据右移,传输次低
  74.                 //位,依次循环           1000 1001 -> 0100 0100
  75.         }
  76. }

  77. //从传感器读字节
  78. uchar Ds18K20ReadByte()
  79. {
  80.         uchar byte, bi;//bi保存单位数据
  81.         uint  i,j;       
  82.         for(j=8; j>0; j--)
  83.         {
  84.                 DSPORT = 0;//先将总线拉低1us
  85.                 i++;
  86.                 DSPORT = 1;//总线拉高,然后释放总线
  87.                 i++;
  88.                 i++;//延时6us等待数据稳定
  89.                 bi = DSPORT;         //读取数据,从最低位开始读取
  90.                 byte = (byte >> 1) | (bi << 7);
  91.                 /*如,byte=0000 0000,bi读取到一个最低位有效数字0000 0001,
  92.                 左移七位1000 0000,byte右移一位0000 0000,和byte或,
  93.                         byte=1000 0000,bi读取到一个最低位有效数字0000 0001,
  94.                         左移七位1000 0000,byte右移一位0100 0000,和byte或,
  95.                         byte=1100 0000,以此类推       
  96.                 */                                                  
  97.                 while(i--);//延时45us
  98.         }                               
  99.         return byte;
  100. }

  101. //温度转换函数指令
  102. void  Ds18K20ChangTemp()
  103. {
  104.         Ds18K20Init();
  105.         Delay1ms(1);
  106.         Ds18K20WriteByte(0xcc);               
  107.         //跳过ROM操作命令                 
  108.         Ds18K20WriteByte(0x44);          
  109.         //温度转换命令
  110.         //Delay1ms(100);       
  111.         //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
  112.    
  113. }

  114. //读取温度数据指令
  115. void  Ds18K20ReadTempCom()
  116. {       

  117.         Ds18K20Init();
  118.         Delay1ms(1);
  119.         Ds18K20WriteByte(0xcc);         
  120.         //跳过ROM操作命令
  121.         Ds18K20WriteByte(0xbe);         
  122.         //发送读取温度命令
  123. }

  124. //报警函数
  125. void Alarm(uint t){
  126.         uint i = 10;
  127.        
  128.         if(t>=warn){
  129.                 while(i--){
  130.                         beep=~beep;
  131.                 }
  132.         }
  133. }

  134. //温度读取函数
  135. int Ds18K20ReadTemp()
  136. {
  137.         int temp = 0;
  138.         //注意这里int是2字节16位
  139.         uchar tmh, tml;
  140.         //分别用于存放温度的低字节和高字节数据
  141.         Ds18K20ChangTemp();                         
  142.         //先写入转换命令
  143.         Ds18K20ReadTempCom();               
  144.         //然后等待转换完后发送读取温度命令
  145.         tml = Ds18K20ReadByte();       
  146.         //读取温度值共16位,先读低字节
  147.         tmh = Ds18K20ReadByte();       
  148.         //再读高字节
  149.         temp = tmh;
  150.         //先读取高八位         0000 0000
  151.         temp <<= 8;
  152.         //将读取到的数据从temp低八位移位至高八位
  153.         temp |= tml;
  154.         //以或的形式读取低八位
  155.         return temp;
  156. }

  157. //数据处理函数
  158. void datapros(int temp)          
  159. {        uint ge,shi,bai;
  160.            float tp;  
  161.         //保存温度
  162.         if(temp< 0)//当温度值为负数
  163.           {
  164.                 DisplayData[0] = 0x40;           //   -
  165.                 //因为读取的温度是实际温度的补码
  166.                 //,所以减1,再取反求出原码
  167.                 temp=temp-1;
  168.                 temp=~temp;
  169.                 tp=temp;
  170.                 temp=tp*0.0625*100+0.5;       
  171.                 //留两个小数点就*100,+0.5是四舍五入,因为
  172.                 //C语言浮点数转换为整型的时候把小数点
  173.                 //后面的数自动去掉,不管是否大于0.5,而+0.5
  174.                 //之后大于0.5的就是进1了,小于0.5的就
  175.                 //算加上0.5,还是在小数点后面。

  176.           }
  177.         else
  178.           {                       
  179.                 DisplayData[0] = 0x00;
  180.                 tp=temp;
  181.                 //因为数据处理有小数点所以将温度赋给一个浮点型变量
  182.                 //如果温度是正的那么,那么正数的原码就是补码它本身
  183.                 temp=tp*0.0625*100+0.5;       
  184.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮
  185.                 //点数转换为整型的时候把小数点后面的数自动去掉,
  186.                 //不管是否大于0.5,而+0.5之后大于0.5的就是进1了,
  187.                 //小于0.5的就算加上0.5,还是在小数点后面。
  188.         }


  189.         bai=temp / 10000;
  190.         shi=temp % 10000 / 1000;
  191.         ge=        temp % 10000 % 1000/100;
  192.         DisplayData[1] = smgduan[bai];                                        //百位
  193.         DisplayData[2] = smgduan[shi];                        //十位
  194.         DisplayData[3] = smgduan[ge]|0x80;        //个位
  195.         DisplayData[4] = smgduan[temp %  100 / 10];
  196.         DisplayData[5] = smgduan[temp %  100 % 10];
  197.         tt=bai*100+10*shi+ge;
  198. }                                          


  199. void dealWaring(){//警戒处理函数
  200.         if(warn>0){
  201.                 warns[0] = 0x00;
  202.                 warns[1] = smgduan[warn/100];
  203.                 warns[2] = smgduan[warn%100/10];
  204.                 warns[3] = smgduan[warn%10];
  205.         }else{
  206.                  warns[0]= 0x40;           //   -
  207.                 warns[1] = smgduan[warn/100];
  208.                 warns[2] = smgduan[warn%100/10];
  209.                 warns[3] = smgduan[warn%10];
  210.         }

  211. }

  212. void keyScan()//键盘控制
  213. {
  214.         uint flag;
  215.         if(K1==0)//按下按键1进入警戒值调整
  216.         {
  217.                 Delay1ms(10);
  218.                 if(K1==0)
  219.                 {
  220.                         dealWaring();
  221.                         while(flag){
  222.                                 uchar i;
  223.                                 for(i=0;i<6;i++)
  224.                                 {
  225.                                         switch(i)         //位选,选择点亮的数码管,
  226.                                         {
  227.                                            case(0):
  228.                                                         LSA=1;LSB=1;LSC=1; break;//显示第0位
  229.                                                 case(1):
  230.                                                         LSA=0;LSB=1;LSC=1; break;//显示第1位
  231.                                                 case(2):
  232.                                                         LSA=1;LSB=0;LSC=1; break;//显示第2位
  233.                                                 case(3):       
  234.                                                         LSA=0;LSB=0;LSC=1; break;//显示第3位
  235.                                                 case(4):
  236.                                                         LSA=1;LSB=1;LSC=0; break;//显示第4位
  237.                                                 case(5):
  238.                                                         LSA=0;LSB=1;LSC=0; break;//显示第5位
  239.                                                 case(6):
  240.                                                         LSA=1;LSB=0;LSC=0; break;//显示第6位
  241.                                                 case(7):
  242.                                                         LSA=0;LSB=0;LSC=0; break;//显示第7位       
  243.                                         }
  244.                                         P0=warns[i];//发送段码
  245.                                         delay(50); //间隔一段时间扫描       
  246.                                         P0=0x00;//消影
  247.                                 }
  248.                                 if(K2==0)
  249.                                 {
  250.                                         Delay1ms(10);
  251.                                         if(K2==0)
  252.                                         {               
  253.                                                 warn++;
  254.                                                 dealWaring();
  255.                                                 while(!K2);
  256.                                         }
  257.                                 }
  258.                        
  259.                                 if(K3==0)
  260.                                 {
  261.                                         Delay1ms(10);
  262.                                         if(K3==0)
  263.                                         {               
  264.                                                 warn--;
  265.                                                 dealWaring();
  266.                                                 while(!K3);
  267.                                         }
  268.                                 }
  269.                        
  270.                                 if(K4==0)
  271.                                 {
  272.                                         Delay1ms(10);
  273.                                         if(K4==0)
  274.                                         {               
  275.                                                 flag=0;
  276.                                                 while(!K4);
  277.                                         }
  278.                                 }                                         
  279.                         }
  280.                
  281.                 }
  282.         }
  283. }

  284. //显示数字
  285. void DigDisplay()
  286. {
  287. ……………………

  288. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
基于DS18B20的温度传感器设计.zip (109.91 KB, 下载次数: 41)


评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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