找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机18b20温度上下限 蜂鸣器报警程序与实物制作

[复制链接]
跳转到指定楼层
楼主
这个新手可以看一下,做一个温度检测。下面是实物图:

下面是程序
  1. #include <reg52.h>
  2. #include "eepom52.h"
  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. //数码管段选定义      0     1    2    3    4    5        6         7          8           9        
  6. uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
  7.                                            0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};         //断码
  8. //数码管位选定义
  9. uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
  10. uchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};        
  11. uchar smg_i = 3;    //显示数码管的个位数
  12. sbit dq = P2^4;                //18b20IO 口的定义

  13. uint temperature ;  //
  14. bit flag_300ms ;
  15. uchar key_can;                 //按键值的变量
  16. uchar menu_1;        //菜单设计的变量
  17. uint t_high = 300,t_low = 100;
  18. bit flag_lj_en;                 //按键连加使能
  19. bit flag_lj_3_en;         //按键连3次连加后使能 加的数就越大了
  20. uchar key_time,flag_value;      //用做连加的中间变量
  21. bit key_500ms  ;



  22. /***********************1ms延时函数*****************************/
  23. void delay_1ms(uint q)
  24. {
  25.         uint i,j;
  26.         for(i=0;i<q;i++)
  27.                 for(j=0;j<110;j++);
  28. }

  29. /***********************小延时函数*****************************/
  30. void delay_uint(uint q)
  31. {
  32.         while(q--);
  33. }


  34. /***********************数码显示函数*****************************/
  35. void display()
  36. {
  37.         uchar i;
  38.         for(i=0;i<smg_i;i++)
  39.         {        
  40.                                                   
  41.                 P3 = smg_we[i];                          //位选
  42.                 P1 = dis_smg[i];                 //段选            
  43.                 delay_1ms(1);                        
  44.                 P3 = 0xff;                          //位选
  45.                 P1 = 0xff;                         //消隐
  46.                
  47.         }        
  48. }


  49. /***********************18b20初始化函数*****************************/
  50. void init_18b20()
  51. {
  52.         bit q;
  53.         dq = 1;                                //把总线拿高
  54.         delay_uint(1);            //15us
  55.         dq = 0;                                //给复位脉冲
  56.         delay_uint(80);                //750us
  57.         dq = 1;                                //把总线拿高 等待
  58.         delay_uint(10);                //110us
  59.         q = dq;                                //读取18b20初始化信号
  60.         delay_uint(20);                //200us
  61.         dq = 1;                                //把总线拿高 释放总线
  62. }

  63. /*************写18b20内的数据***************/
  64. void write_18b20(uchar dat)
  65. {
  66.         uchar i;
  67.         for(i=0;i<8;i++)
  68.         {                                         //写数据是低位开始
  69.                 dq = 0;                         //把总线拿低写时间隙开始
  70.                 dq = dat & 0x01; //向18b20总线写数据了
  71.                 delay_uint(5);         // 60us
  72.                 dq = 1;                         //释放总线
  73.                 dat >>= 1;
  74.         }        
  75. }

  76. /*************读取18b20内的数据***************/
  77. uchar read_18b20()
  78. {
  79.         uchar i,value;
  80.         for(i=0;i<8;i++)
  81.         {
  82.                 dq = 0;                         //把总线拿低读时间隙开始
  83.                 value >>= 1;         //读数据是低位开始
  84.                 dq = 1;                         //释放总线
  85.                 if(dq == 1)                 //开始读写数据
  86.                         value |= 0x80;
  87.                 delay_uint(5);         //60us        读一个时间隙最少要保持60us的时间
  88.         }
  89.         return value;                 //返回数据
  90. }

  91. /*************读取温度的值 读出来的是小数***************/
  92. uint read_temp()
  93. {
  94.         uint value;
  95.         uchar low;                           //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
  96.         init_18b20();                   //初始化18b20
  97.         write_18b20(0xcc);           //跳过64位ROM
  98.         write_18b20(0x44);           //启动一次温度转换命令
  99.         delay_uint(50);                   //500us

  100.         init_18b20();                   //初始化18b20
  101.         write_18b20(0xcc);           //跳过64位ROM
  102.         write_18b20(0xbe);           //发出读取暂存器命令

  103.         low = read_18b20();           //读温度低字节
  104.         value = read_18b20();  //读温度高字节

  105.         value <<= 8;                   //把温度的高位左移8位
  106.         value |= low;                   //把读出的温度低位放到value的低八位中
  107.         value *= 0.625;               //转换到温度值 小数
  108.         return value;                   //返回读出的温度 带小数
  109. }

  110. /*************定时器0初始化程序***************/
  111. void time_init()         
  112. {
  113.         EA   = 1;                   //开总中断
  114.         TMOD = 0X01;          //定时器0、定时器1工作方式1
  115.         ET0  = 1;                  //开定时器0中断
  116.         TR0  = 1;                  //允许定时器0定时
  117. }

  118. /****************独立按键处理函数************************/
  119. void key()
  120. {
  121.         static uchar key_new = 0,key_old = 0,key_value = 0;
  122.         if(key_new == 0)                        
  123.         {                                                   //按键松开的时候做松手检测
  124.                 if((P2 & 0x0f) == 0x0f)
  125.                         key_value ++;
  126.                 else
  127.                         key_value = 0;
  128.                 if(key_value >= 10)
  129.                 {
  130.                         key_value = 0;
  131.                         key_new = 1;
  132.                         flag_lj_en = 0;
  133.                         flag_lj_3_en = 0;
  134.                         flag_value = 0;
  135.                 }
  136.         }
  137.         else
  138.         {
  139.                 if((P2 & 0x0f) != 0x0f)
  140.                         key_value ++;  //按键按下的时候
  141.                 else
  142.                         key_value = 0;
  143.                 if(key_value >= 7)
  144.                 {
  145.                         key_value = 0;
  146.                         key_new = 0;
  147.                         flag_lj_en = 1;         //连加使能
  148.                 }
  149.         }
  150.         key_can = 20;
  151.         if(key_500ms == 1)
  152.         {
  153.                 key_500ms = 0;
  154.                 key_new = 0;
  155.                 key_old = 1;
  156.         }
  157.         if((key_new == 0) && (key_old == 1))
  158.         {
  159.                 switch(P2 & 0x0f)
  160.                 {
  161.                         case 0x0e: key_can = 4; break;           //得到k1键值
  162.                         case 0x0d: key_can = 3; break;           //得到k2键值
  163.                         case 0x0b: key_can = 2; break;           //得到k3键值
  164.                         case 0x07: key_can = 1; break;           //得到k4键值
  165.                 }
  166. //                dis_smg[3] = smg_du[key_can];
  167.         }                        
  168.         key_old = key_new;         
  169. }

  170. /****************按键处理数码管显示函数***************/
  171. void key_with()
  172. {
  173.         if(key_can == 4)
  174.         {
  175.                 menu_1 ++;
  176.                 if(menu_1 >= 3)
  177.                 {
  178.                         menu_1 = 0;
  179.                 }
  180.                 if(menu_1 == 0)
  181.                 {
  182.                         dis_smg[0] = smg_du[temperature % 10];         //取温度的小数显示
  183.                         dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取温度的个位显示
  184.                         dis_smg[2] = smg_du[temperature / 100 % 10] ;           //取温度的十位显示
  185.                         smg_i = 3;
  186.                 }
  187.                 if(menu_1 == 1)
  188.                 {
  189.                         dis_smg[0] = smg_du[t_high % 10];                   //取温度的小数显示
  190.                         dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f;  //取温度的个位显示
  191.                         dis_smg[2] = smg_du[t_high / 100 % 10] ;           //取温度的十位显示
  192.                         dis_smg[3] = 0x89;        
  193.                         smg_i = 4;
  194.                 }
  195.                 if(menu_1 == 2)
  196.                 {
  197.                         dis_smg[0] = smg_du[t_low % 10];                   //取温度的小数显示
  198.                         dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f;  //取温度的个位显示
  199.                         dis_smg[2] = smg_du[t_low / 100 % 10] ;           //取温度的十位显示
  200.                         dis_smg[3] = 0xc7;        
  201.                         smg_i = 4;
  202.                 }
  203.         }
  204.         if(menu_1 == 1)                        //设置高温报警
  205.         {
  206.                 if(key_can == 3)
  207.                 {
  208.                         if(flag_lj_3_en == 0)
  209.                                 t_high ++ ;                        
  210.                         else
  211.                                 t_high += 10;
  212.                         if(t_high > 990)
  213.                                 t_high = 990;
  214.                         dis_smg[0] = smg_du[t_high % 10];                   //取温度的小数显示
  215.                         dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f;  //取温度的个位显示
  216.                         dis_smg[2] = smg_du[t_high / 100 % 10] ;           //取温度的十位显示
  217.                         dis_smg[3] = 0x89;
  218.                 }
  219.                 if(key_can == 1)
  220.                 {
  221.                         if(flag_lj_3_en == 0)
  222.                                 t_high -- ;                        
  223.                         else
  224.                                 t_high -= 10;
  225.                         if(t_high < t_low)
  226.                                 t_high = t_low;
  227.                         dis_smg[0] = smg_du[t_high % 10];                   //取温度的小数显示
  228.                         dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f;  //取温度的个位显示
  229.                         dis_smg[2] = smg_du[t_high / 100 % 10] ;           //取温度的十位显示
  230.                         dis_smg[3] = 0x89;
  231.                 }
  232.         }        
  233.         if(menu_1 == 2)                        //设置高温报警
  234.         {
  235.                 if(key_can == 3)
  236.                 {
  237.                         if(flag_lj_3_en == 0)
  238.                                 t_low ++ ;                        
  239.                         else
  240.                                 t_low += 10;
  241.                         if(t_low >= t_high)
  242.                                 t_low = t_high - 1;
  243.                         dis_smg[0] = smg_du[t_low % 10];                   //取温度的小数显示
  244.                         dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f;  //取温度的个位显示
  245.                         dis_smg[2] = smg_du[t_low / 100 % 10] ;           //取温度的十位显示
  246.                         dis_smg[3] = 0xc7;
  247.                 }
  248.                 if(key_can == 1)
  249.                 {
  250.                         if(flag_lj_3_en == 0)
  251.                                 t_low -- ;                        
  252.                         else
  253.                                 t_low -= 10;
  254.                         if(t_low <= 10)
  255.                                 t_low = 11;
  256.                         dis_smg[0] = smg_du[t_low % 10];                   //取温度的小数显示
  257.                         dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f;  //取温度的个位显示
  258.                         dis_smg[2] = smg_du[t_low / 100 % 10] ;           //取温度的十位显示
  259.                         dis_smg[3] = 0xc7;
  260.                 }
  261.         }        
  262. }

  263. void main()
  264. {        
  265.         time_init();     //初始化定时器
  266.         while(1)
  267.         {
  268.                 display();
  269.                 key();        
  270.                 if(key_can < 10)
  271.                 {
  272.                         key_with();                                
  273.                 }
  274.                 temperature= read_temp();                //先读出温度的值
  275.                 if(flag_300ms == 1)                //300ms 处理一次温度程序
  276.                 {
  277.                         flag_300ms = 0;        
  278.                         if(menu_1 == 0)
  279.                         {        
  280.                                 dis_smg[0] = smg_du[temperature % 10];         //取温度的小数显示
  281.                                 dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取温度的个位显示
  282.                                 dis_smg[2] = smg_du[temperature / 100 % 10] ;           //取温度的十位显示
  283.                         }
  284.                 }
  285.         }
  286. }

  287. /*************定时器0中断服务程序***************/
  288. void time0_int() interrupt 1
  289. {        
  290.         static uchar value;
  291.         TH0 = 0x3c;
  292.         TL0 = 0xb0;     // 50ms
  293.         value ++;         
  294.         if(value % 6 == 0)
  295.         {
  296.                 flag_300ms = 1;           //300ms
  297.                 value = 0;
  298.         }
  299.         if(flag_lj_en == 1)
  300.         {
  301.                 key_time ++;
  302.                 if(key_time >= 10)
  303.                 {
  304.                         key_time = 0;
  305.                         key_500ms = 1;
  306.                         flag_value ++;
  307.                         if(flag_value > 3)
  308.                         {
  309.                                 flag_value = 10;
  310.                                 flag_lj_3_en = 1;
  311.                         }
  312.                                                 
  313.                 }
  314.         }
  315. }
复制代码


下面有原理图,最好按着原理图焊接。
PDF格式 温度上下限 蜂鸣器报警.pdf (91.83 KB, 下载次数: 50)

评分

参与人数 2黑币 +108 收起 理由
wuli韬韬 + 8
admin + 100 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:397465 发表于 2018-9-13 15:18 来自手机 | 只看该作者
标志语法错误咋改你的uint temperature  和dq是错误的标志你说咋改啊
回复

使用道具 举报

板凳
ID:397465 发表于 2018-9-13 15:21 来自手机 | 只看该作者
你有几个标志错误的!你能改下不
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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