找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3645|回复: 6
收起左侧

基于51单片机、ds18b20温度计设计源代码

[复制链接]
ID:191697 发表于 2017-4-22 10:16 | 显示全部楼层 |阅读模式
功能:1.显示温度;
2.显示温度上下限;
3.上下限可调;
4.显示温度传感器序列码;
5.温度异常,分阶段报警。            
0.png

源程序:
  1. //////////////////////////////////////////////////////////////////// /////////////////////////////////////////
  2. /*

  3. 按键控制LCD显示内容,(id号与当前温度/上下限以及)
  4. 按键可调温度的上下限。


  5. */
  6. #include<reg52.h>
  7. #include<intrins.h>                         //nop

  8. #define uchar unsigned char
  9. #define uint unsigned int

  10. sbit ds = P2^2;                           //DS18b20-->DS
  11. sbit beep = P2^3;                   //buzz

  12. sbit wela = P2^7;                        //
  13. sbit dula = P2^6;                        //

  14. sbit LCDEN = P3^4;                        // EN
  15. sbit rs = P3^5;                                //数据 命令选择端
  16. sbit rw = P3^6;                                //读写选择端

  17. uchar datstr[] = "Temperature:";
  18. uchar str[4];                            //uchartostr函数转换的字符串   同时可以把16进制转成10进制        存高低温上下限
  19. uchar str1[5];                                         //uchartostr1函数转换的字符串   同时可以把16进制转成10进制        存温度  
  20. //sbit IDcheck=P2^5;
  21. //sbit IDready=P3^1;

  22.    
  23. int flip=0;                   // 用来读flip1  用于反转
  24. int flip1=1;                  //=1 开单键&用于双键反转
  25. bit flag;//ds初始化成功标志
  26. uchar ds_rom[16];         //存序列码         存入的是字节
  27.           
  28. uchar H=40,L=10,Key_value;              //初始上下限温度,


  29. uchar code table[]={'0','1','2','3','4',
  30.                                         '5','6','7','8','9',
  31.                                         'A','B','C','D','E','F'                //序列码字节转ASCII专用数组               
  32. };


  33. void delay(uint z);                                 //延时函数        1602专用
  34. void write_com(uchar com);                       //写命令
  35. void write_data(uchar date);                  //写数据
  36. void init_1602();                                //初始化1602
  37. uchar *uchartostr(uchar num);        //将一个字节的数据转换为字符串 或10进制         返回数组 上下限显示用
  38. uchar *uchartostr1(uint num);        //将一个字节的数据转换为字符串 或10进制         返回数组 温度显示用
  39. void lcd_dis(uchar X,uchar Y,uchar *dis);        //显示数据数组
  40. void lcd_distostr(uchar X,uchar Y);//显示字符串temperature 数组
  41.                  

  42. void TempDelay(uchar us)                        //delay
  43. {
  44.         while(us--); //6.51us
  45. }
  46. void ds_reset()                                                //ds18b20 init
  47. {
  48.         ds=1;
  49.         _nop_();         //1us
  50.         ds=0;
  51.         TempDelay(80);         //延时略长些
  52.         ds=1;
  53.         TempDelay(6);
  54.         if(ds==0)
  55.                 flag=0;                        //记录应答电平
  56.         else
  57.                 flag=1;                         //失败
  58.         TempDelay(20);                 //延时
  59.         ds=1;                                   //置1结束
  60. }

  61. bit ds_read_bit()          //(||)read a bit
  62. {
  63.         bit dat;
  64.         ds=0;                        //DQ已经是1了
  65.         _nop_();           //1us delay
  66.         _nop_();
  67.         ds=1;
  68.         _nop_();
  69.         dat=ds;                        //读一位
  70.         TempDelay(12);                //延时稍长
  71.         return dat;
  72. }
  73. uchar ds_read_byte()                //read a byte
  74. {
  75.         uchar i,j,value;
  76.         for(i=0;i<8;i++)
  77.         {
  78.                 j=ds_read_bit();          //1 bit上一个函数    @先读到的位为最低位
  79.                 value=(j<<7)|(value>>1);   //新bit左移7位,旧状态右移一位空出最高位,组合
  80.         }
  81.         return value;
  82. }
  83. void ds_write_byte(uchar dat)                          //写一字节
  84. {
  85.         uchar i,onebit;
  86.         for(i=0;i<8;i++)                                          //8bit
  87.         {
  88.                 onebit=dat&0x01;         //取最低位
  89.                 if(onebit)           //最低位为1  写1
  90.                 {
  91.                         ds=0;
  92.                         TempDelay(1);
  93.                         ds=1;
  94.                         _nop_();
  95.                 }
  96.                 else  //写0
  97.                 {
  98.                         ds=0;
  99.                         TempDelay(11);   //delay 长一些 因为省去ds=0
  100.                         ds=1;
  101.                         _nop_();
  102.                 }
  103.                 dat>>=1;          //右移一位
  104.         }
  105. }

  106. void ds_change()                        //jump rom  &start temp convert
  107. {       
  108.         ds_reset() ;
  109.         while(flag!=0);                        //        //检测到设备  成功返回0
  110.         ds_write_byte(0xcc);        //jump ROM
  111.         ds_write_byte(0x44);        //TEMP convert
  112. }


  113. void Read_ROM()                           //序列码读入数组        ds_rom[i]
  114. {
  115.         int i;
  116.         uchar a;       //序列码缓冲
  117.         ds_reset();
  118.         while(flag!=0);
  119.         ds_write_byte(0x33);        //read rom序列码
  120.         for(i=15;i>0;i--)
  121.         {       
  122.                 a=ds_read_byte();
  123.                 ds_rom[i--]=(0x0f&a);                  //取低四位        15
  124.                 ds_rom[i]=((0xf0&a)>>4);                //取高四位          14
  125.         }
  126.         // ds_rom[16]='\0';
  127. }

  128. uint get_temperature()                 //                  温度采集
  129. {
  130.         uint temp;
  131.         float ftemp;
  132.         uchar a,b;
  133.         ds_reset();
  134.         while(flag!=0);
  135.         ds_write_byte(0xcc);                         //jump ROM
  136.         ds_write_byte(0xbe);                        //read 标签存储器
  137.         a=ds_read_byte();                                //read low8
  138.         b=ds_read_byte();                                //read high8
  139.        
  140.         temp=b;
  141.         temp<<=8;
  142.         temp|=a;                                           //高低8位结合

  143.         ftemp=temp*0.0625;                           //12bit-->0.0625*10 (除以16,2^4,右移4位)
  144.         ftemp=ftemp*10+0.5;                           //取1位小数后四舍五入
  145.         temp=ftemp;                                           //现在为10倍temp的整数  便于显示

  146.         return temp;
  147. }

  148. void IDshow();                                                //显示序列码
  149. void WarningShow();                                         //温度上下限显示
  150. void key()                                           // 有问题  按键扫描
  151. {
  152.         Key_value = P3;
  153.         Key_value = Key_value & 0x0f;
  154.         if ( Key_value != 0x0f )
  155.         {
  156.                 delay(5);
  157.                 if ( Key_value != 0x0f )        //qu dou
  158.                 {
  159.                         if( Key_value == 0x0c )                  //s2s3同时按下
  160.                                 {  
  161.                                         delay(5);
  162.                                         if( Key_value == 0x0c )        //
  163.                                     {
  164.                                                  flip=flip1;                  //状态反转 读上一次状态 每同时按一次  反转一次
  165.                                                 if(flip==1)                  
  166.                                                 {
  167.                                                    IDshow();
  168.                                                    flip1=0;                  //flip1==1  关闭单键调节功能
  169.                                                 }
  170.                                                 else if(flip==0)
  171.                                                 {
  172.                                                         WarningShow();         //显示上下限
  173.                                                         flip1=1;                //flip1==1  时才能监测其他按键来调上下限                               
  174.                                                 }
  175.                                         }
  176.                                 }
  177.                        
  178.                         if( (Key_value == 0x0e)&(flip1==1) )
  179.                         {        //*
  180.                        
  181.                                 H++;
  182.                                 if (H==100)
  183.                                         H=40;
  184.                                
  185.                         }

  186.                         if( (Key_value == 0x0d)&(flip1==1) )
  187.                         {
  188.                                 H--;
  189.                                 if (H==0)
  190.                                         H=99;
  191.                                 if (H==L)
  192.                                         H=H+1;
  193.                         }

  194.                         if( (Key_value == 0x0b)&(flip1==1) )
  195.                         {
  196.                                 L++;
  197.                                 if (L==H)
  198.                                         L=0;
  199.                         }

  200.                          if( (Key_value == 0x07)&(flip1==1) )
  201.                         {
  202.                                 L--;
  203.                                 if (L==0)
  204.                                         if(H>10)
  205.                                                  L=10;
  206.                                         else
  207.                                              L=H-1;
  208.                         }                  

  209.                 }
  210.         }
  211.        


  212. }

  213. void IDshow()
  214. {

  215.         uint i;
  216.         Read_ROM();
  217.         write_com( 0x80 + 0 + 0 );
  218.         for(i=0;i<16;i++)
  219.         {
  220.             write_data(table[ds_rom[i]]);           //
  221.         }
  222.                
  223. }

  224. void WarningShow()
  225. {
  226.         write_com( 0x80 + 0 + 0);
  227.         write_data( ' ' );
  228.         write_data( ' ' );
  229.         write_data( ' ' );
  230.         write_com( 0x80 + 0 + 3);
  231.         write_data( 'H' );
  232.         write_data( ':' );
  233.         write_com( 0x80 + 0 + 7);
  234.         write_data( ' ' );
  235.         write_com( 0x80 + 0 + 8);
  236.         write_data( 'L' );
  237.         write_data( ':' );
  238.         write_com( 0x80 + 0 + 12);
  239.         write_data( ' ' );
  240.         write_data( ' ' );
  241.         write_data( ' ' );
  242.         write_data( ' ' );
  243.         lcd_dis( 0,5,uchartostr( H ) );
  244.         lcd_dis( 0,10,uchartostr( L ) );
  245. }




  246. /****************************************************MAIN*************************************************************/
  247. /****************************************************MAIN*************************************************************/
  248. /****************************************************MAIN*************************************************************/
  249. void main()                                               
  250. {

  251.         uint i;
  252. //        rd = 0;
  253.         init_1602();                           //
  254.                                           
  255.         WarningShow();        
  256. //        H = 40;
  257. //        L = 10;
  258.         lcd_dis( 0,5,uchartostr( H ) );
  259.     lcd_dis( 0,10,uchartostr( L ) );
  260.         lcd_distostr(1,0);           //TEMPERATURE

  261.                                                 //init warn
  262.        
  263.         ds_change();
  264.         delay(800);               ////85C
  265.         while(1)
  266.         {
  267.                 ds_change();  
  268.                 i = get_temperature();        //采温度
  269.        
  270.                 lcd_dis( 1,12,uchartostr1( i ) );                //str1 显示温度
  271.                 if(flip1==0);
  272.                 else if(flip1==1)        //启动单键时
  273.                 {
  274.                         lcd_dis( 0,5,uchartostr( H ) );                  //上下限-->str
  275.                     lcd_dis( 0,10,uchartostr( L ) );
  276.                 }
  277.                
  278.                 //报警
  279.                 if ( i >=(10*H) )
  280.                 {
  281.                          P1 = 0x33;
  282.                 }
  283.                 else if (i<=(10*L))
  284.                 {
  285.                          P1 = 0xcc;
  286.                 }
  287.                 else
  288.                 {
  289.                          P1 = 0xff;
  290.                 }
  291.                 key();
  292.         }  
  293. }






  294. //1602辅助小函数
  295. void delay(uint z)                                 //延时函数
  296. {
  297.         uint x,y;
  298.         for(x=z;x>0;x--)
  299.                 for(y=120;y>0;y--);
  300. }
  301. void write_com(uchar com)                  //写命令
  302. {
  303.         P0=com;                                                 
  304.         rs=0;                                                 //写命令
  305.         LCDEN=0;
  306.         delay(10);
  307.         LCDEN=1;
  308.         delay(10);
  309.         LCDEN=0;
  310.                
  311. }
  312. void write_data(uchar date)                  //写数据
  313. {
  314.         P0=date;
  315.         rs=1;                                                 //写数据
  316.         LCDEN=0;
  317.         delay(10);
  318.         LCDEN=1;
  319.         delay(10);
  320.         LCDEN=0;
  321.                
  322. }
  323. void init_1602()                                //初始化1602
  324. {
  325.     rw=0;
  326.         dula=0;
  327.         wela=0;                                  //防止数码管乱闪

  328.         write_com(0x38);           //显示模式设置:16×2显示,5×7点阵,8位数据接口
  329.         delay(20);
  330.         write_com(0x0c);           //显示模式设置:开显示 不显示光标  也不闪烁
  331.         delay(20);                        
  332.         write_com(0x06);           //显示模式设置:光标右移,字符不移,不移动屏幕
  333.         delay(20);
  334.         write_com(0x01);           //清屏幕指令,将以前的显示内容清除
  335.         delay(20);       
  336. }

  337. /////////////////////////////////////////////////////////////////////////////////
  338. ////////////////////////////x数组  准备显示//////////////////////////////////////
  339. /////////////////////////////////////////////////////////////////////////////////

  340. uchar *uchartostr(uchar num)        //将一个字节的数据转换为字符串 或10进制         返回数组首地址        (上下限)
  341. {
  342.         uchar x1,x0,i;


  343.         x1=num%100/10;
  344.         x0=num%100%10;
  345.         i=0;                                                          //数组第一元素

  346.         str[i]=x1+48;                                        //变ASCII码
  347.         i++;
  348.         str[i]=x0+48;
  349.         i++;
  350.         str[i]='\0';                                        //结束符
  351.         return str;
  352. }


  353. uchar *uchartostr1(uint num)        //将一个字节的数据转换为字符串 或10进制         返回数组(温度专用)
  354. {
  355.         uchar x2,x1,x0,i;

  356.         x2=num/100;
  357.         x1=num%100/10;
  358.         x0=num%10;
  359.         i=0;                                                          //数组第一元素
  360.         if(x2!=0)
  361.         {
  362.                 str1[i]=x2+48;                                 //变ASCII码 十位
  363.                 i++;
  364.         }
  365.         if(1)
  366.         {
  367.                 str1[i]=x1+48;                                //个位
  368.                 i++;
  369.                 str1[i]=46;                                           // "." 小数点
  370.                 i++;
  371.         }
  372.         str1[i]=x0+48;                                    //十分位
  373.         i++;
  374.         str1[i]='\0';                                        //结束符
  375.         return str1;                                       
  376. }


  377. /////////////////////////////////////////////////////////////////////////////////
  378. ////////////////////////////x显示////////////////////////////////////////////////
  379. /////////////////////////////////////////////////////////////////////////////////

  380. void lcd_dis(uchar X,uchar Y,uchar *dis)        //显示数据数组
  381. {                          
  382.    uchar  pos;                                                                //位置
  383.    switch(X)
  384.    {
  385.                 case 0:X=0x00;                                                // line1
  386.                 break;
  387.                 case 1:X=0x40;                                                //line2
  388.                 break;
  389.                 break;
  390.                 default:break;
  391.    }

  392.    pos =0x80+X+Y;                                                          //
  393.    write_com(pos);                          //写入显示地址设置
  394.    while(*dis!='\0')                                                //
  395.    {
  396.         write_data(*dis++);               
  397.    }
  398. }

  399. void lcd_distostr(uchar X,uchar Y)//显示字符串temperature 数组
  400. {                          
  401.    uchar  pos,i;
  402.    i=0;                                                                         //设定从数组中的第几个字符串开始显示
  403.         switch(X)


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

下载:
ds18b20_oo.zip (60.74 KB, 下载次数: 36)

评分

参与人数 3黑币 +11 收起 理由
XINB + 5 很给力!
luo1429181965 + 5
c51ds18b20 + 1 很给力!

查看全部评分

回复

使用道具 举报

ID:233546 发表于 2017-12-25 00:56 | 显示全部楼层
请问按键是矩阵是按键吗?
回复

使用道具 举报

ID:260785 发表于 2017-12-25 08:11 | 显示全部楼层
感谢无私奉献。一起学习一起前进。
回复

使用道具 举报

ID:264406 发表于 2017-12-25 12:05 | 显示全部楼层
按键改温度怎么按键?
回复

使用道具 举报

ID:267631 发表于 2017-12-27 12:39 | 显示全部楼层
太好了这设计
回复

使用道具 举报

ID:268529 发表于 2017-12-28 19:28 | 显示全部楼层
我做的数码管不显示十位后的温度,很烦,自己也不知道哪里错了。
回复

使用道具 举报

ID:271393 发表于 2018-1-4 14:57 | 显示全部楼层
谢谢楼主了,我正在学习,看一下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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