找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3620|回复: 1
收起左侧

单片机水温控制keil程序

[复制链接]
ID:213071 发表于 2017-6-20 20:24 | 显示全部楼层 |阅读模式
51单片机做的水温控制keilc51程序,包括键盘,数码管显示,报警器等。

单片机源程序如下:
  1. #include <reg51.h>                         //包含头文件
  2. #define uint unsigned int
  3. #define uchar unsigned char //宏定义
  4. sbit SET=P3^1;                            //定义调整键
  5. sbit DEC=P3^2;                            //定义减少键
  6. sbit ADD=P3^3;                            //定义增加键
  7. sbit BEEP=P3^6;                            //定义蜂鸣器
  8. sbit ALAM=P1^4;                               
  9. sbit ALAM1=P1^2;                        //定义加热制冷继电器
  10. sbit DQ=P3^7;                             //定义DS18B20总线I/O       
  11. bit shanshuo_st;                            //闪烁间隔标志
  12. bit beep_st;                                     //蜂鸣器间隔标志
  13. sbit DIAN = P0^5;                        //小数点
  14. uchar x=0;                                      //计数器
  15. signed char m;                                     //温度值全局变量
  16. uchar n;                                              //温度值全局变量
  17. uchar set_st=0;                             //设置状态标志
  18. signed char shangxian=38;                  //上限报警温度,默认值为38
  19. signed char xiaxian=5;                   //下限报警温度,默认值为5
  20. //uchar code  LEDData[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};
  21. uchar code  LEDData[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7,0xCF,0xDA,0x9B,0xDC,0x9B,0x8B}; //数码管显示码表

  22. //============================================================================================
  23. //====================================DS18B20=================================================
  24. //============================================================================================
  25. /*****18b20延时子程序*****/
  26. void Delay_DS18B20(int num)
  27. {
  28.   while(num--) ;
  29. }
  30. /*****初始化DS18B20*****/
  31. void Init_DS18B20(void)
  32. {
  33.   unsigned char x=0;
  34.   DQ = 1;         //DQ复位
  35.   Delay_DS18B20(8);    //稍做延时
  36.   DQ = 0;         //单片机将DQ拉低
  37.   Delay_DS18B20(80);   //精确延时,大于480us
  38.   DQ = 1;         //拉高总线
  39.   Delay_DS18B20(14);
  40.   x = DQ;           //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
  41.   Delay_DS18B20(20);
  42. }
  43. /*****读一个字节*****/
  44. unsigned char ReadOneChar(void)
  45. {
  46.   unsigned char i=0;
  47.   unsigned char dat = 0;
  48.   for (i=8;i>0;i--)        //循环8次,读出一个字节
  49.   {
  50.     DQ = 0;     // 给脉冲信号
  51.     dat>>=1;        //数据右移一位
  52.     DQ = 1;     // 给脉冲信号
  53.     if(DQ)                //如果该位为1
  54.     dat|=0x80;        //将数据 | 0x80后,存入dat
  55.     Delay_DS18B20(4);  //延时
  56.   }
  57.   return(dat);        //返回一字节数据
  58. }
  59. /*****写一个字节*****/
  60. void WriteOneChar(unsigned char dat)
  61. {
  62.   unsigned char i=0;
  63.   for (i=8; i>0; i--)         //循环8次,写入一个字节
  64.   {
  65.     DQ = 0;                                 //拉低
  66.     DQ = dat&0x01;                 //将dat数据&0x01后,送入IO口
  67.     Delay_DS18B20(5);         //保持一会
  68.     DQ = 1;                                 //io口拉高
  69.     dat>>=1;                         //dat右移一位
  70.   }
  71. }
  72. /*****读取温度*****/
  73. unsigned int ReadTemperature(void)
  74. {
  75.   unsigned char a=0;
  76.   unsigned char b=0;
  77.   unsigned int t=0;
  78.   float tt=0;
  79.   Init_DS18B20();
  80.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  81.   WriteOneChar(0x44);  //启动温度转换
  82.   Init_DS18B20();
  83.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  84.   WriteOneChar(0xBE);  //读取温度寄存器
  85.   a=ReadOneChar();     //读低8位
  86.   b=ReadOneChar();    //读高8位
  87.   t=b;                                  //将高8位数据存入t
  88.   t<<=8;                          //t左移8位
  89.   t=t|a;                          //将t|a得到一个16位的温度数据
  90.   tt=t*0.0625;                  //一个最低位代表0.0625°C,所以要*0.0625得到实际温度,因为有小数运算,所以定义的tt是float浮点型变量
  91.   t= tt*10+0.5;     //放大10倍输出并四舍五入(将温度放大10倍可以得到小数部分)
  92. //  t= tt*10;
  93.   return(t);                //返回得到的温度值
  94. }
  95. //=====================================================================================
  96. //=====================================================================================
  97. //=====================================================================================


  98. /*****延时子程序*****/
  99. void Delay(uint num)
  100. {
  101. while( --num );
  102. }
  103. /*****初始化定时器0*****/
  104. void InitTimer(void)
  105. {
  106.         TMOD=0x1;          //工作方式1
  107.         TH0=0x3c;
  108.         TL0=0xb0;     //50ms(晶振12M)
  109. }

  110. /*****读取温度*****/
  111. void check_wendu(void)
  112. {
  113.         uint a,b,c;
  114.         c=ReadTemperature()-5;                          //获取温度值并减去DS18B20的温漂误差
  115. //        c=ReadTemperature();
  116.         a=c/100;                                                     //计算得到十位数字
  117.         b=c/10-a*10;                                            //计算得到个位数字
  118.         m=c/10;                                                      //计算得到整数位
  119.         n=c-a*100-b*10;                                    //计算得到小数位
  120.         if(m<0){m=0;n=0;}                                   //设置温度显示上限
  121.         if(m>99){m=99;n=9;}                                   //设置温度显示上限   
  122. }
  123. /*****显示开机初始化等待画面*****/
  124. void Disp_init(void)   
  125. {
  126.         P0 = ~0x80;      //显示----
  127.         P2 = 0x7F;                 //依次打开各位
  128.         Delay(200);                 //延时
  129.         P2 = 0xDF;
  130.         Delay(200);   
  131.         P2 = 0xF7;
  132.         Delay(200);
  133.         P2 = 0xFD;
  134.         Delay(200);
  135.         P2 = 0xFF;         //关闭显示
  136. }
  137. /*****显示温度子程序*****/
  138. void Disp_Temperature(void)     //显示温度
  139. {
  140.         P0 = ~0x98;      //显示C
  141.         P2 = 0x7F;                 //打开位
  142.         Delay(400);                 //延时
  143.         P2 = 0xff;         //关闭显示
  144.         P0=~LEDData[n];    //显示个位
  145.         P2 = 0xDF;
  146.         Delay(400);
  147.         P2 = 0xff;         //关闭显示
  148.         P0 =~LEDData[m%10];    //显示十位
  149.         DIAN = 0;         //显示小数点
  150.         P2 = 0xF7;
  151.         Delay(400);
  152.         P2 = 0xff;         //关闭显示
  153.         P0 =~LEDData[m/10];    //显示百位
  154.         P2 = 0xFD;
  155.         Delay(400);
  156.         P2 = 0xff;         //关闭显示
  157. }
  158. /*****显示报警温度子程序*****/
  159. void Disp_alarm(uchar baojing)
  160. {
  161.         P0 =~0x98;      //显示C
  162.         P2 = 0x7F;                //选中位
  163.         Delay(200);
  164.         P2 = 0xff;         //关闭显示
  165.         P0 =~LEDData[baojing%10]; //显示十位
  166.         P2 = 0xDF;
  167.         Delay(200);
  168.         P2 = 0xff;         //关闭显示
  169.         P0 =~LEDData[baojing/10]; //显示百位
  170.         P2 = 0xF7;
  171.         Delay(200);
  172.         P2 = 0xff;         //关闭显示
  173.         if(set_st==1)P0 =~0xCE;                 //设置上限时显示H
  174.         else if(set_st==2)P0 =~0x1A; //设置下限时显示L
  175.         P2 = 0xFD;
  176.         Delay(200);
  177.         P2 = 0xff;         //关闭显示
  178. }
  179. /*****报警子程序*****/
  180. void Alarm()
  181. {
  182.         if(x>=10){beep_st=~beep_st;x=0;} //控制闪烁(x随定时器每50ms加1,10次时500ms,这里闪烁就是500ms亮500ms灭)
  183.         if(m>=shangxian)  //温度大于上限时
  184.         {
  185.                 ALAM=0;                  //制冷继电器吸合
  186.                 ALAM1=1;
  187.                 if(beep_st==1)//控制蜂鸣器闪烁变量为1时
  188.                 BEEP=0;                  //蜂鸣器响
  189.                 else                  //控制蜂鸣器闪烁变量为0时
  190.                 BEEP=1;                  //蜂鸣器停止
  191.         }
  192.         else if(m<xiaxian)//温度小于下限时
  193.         {
  194.                 ALAM1=0;          //升温继电器吸合
  195.                 ALAM=1;
  196.                 if(beep_st==1)//控制蜂鸣器闪烁
  197.                 BEEP=0;
  198.                 else
  199.                 BEEP=1;
  200.         }
  201.         else                          //水温在上下限范围内时
  202.         {
  203.                 BEEP=1;                  //关闭蜂鸣器
  204.                 ALAM=1;                  //关闭加热和制冷继电器
  205.                 ALAM1=1;
  206.         }
  207. }

  208. /*****主函数*****/
  209. void main(void)
  210. {
  211.         uint z;
  212.         InitTimer();    //初始化定时器
  213.         EA=1;      //全局中断开关
  214.         TR0=1;                 //打开定时器定时开关
  215.         ET0=1;      //开启定时器0
  216.         IT0=1;      //外部中断下降沿有效  
  217.         IT1=1;
  218.         check_wendu();
  219.         check_wendu();          //读取两次温度,防止开机读取到85°C,使继电器误操作
  220.         for(z=0;z<300;z++)        //开机画面
  221.         {
  222.                 Disp_init();        
  223.         }
  224.         while(1)                   //while循环
  225.         {
  226.                 if(SET==0)           //判断设置键是否按下
  227.                 {
  228.                         Delay(2000);         //延时去抖
  229.                         do{}while(SET==0);         //执行空语句,判断按键是否松开,松开向下执行,否则重新执行空语句
  230.                         set_st++;x=0;shanshuo_st=1;        //设置键松开后将设置变量加1,闪烁标志位置1
  231.                         if(set_st>2)set_st=0;        //当设置完成时,退出设置
  232.                 }
  233.                 if(set_st==0) //正常工作时
  234.                 {
  235.                         EX0=0;    //关闭外部中断0
  236.                         EX1=0;    //关闭外部中断1
  237.                         check_wendu();
  238.                         Disp_Temperature();        //检测温度
  239.                         Alarm();   //报警检测
  240.                 }
  241.                 else if(set_st==1)        //设置上限时
  242.                 {
  243.                         BEEP=1;    //关闭蜂鸣器
  244.                         ALAM=1;
  245.                         ALAM1=1;  //继电器关闭
  246.                         EX0=1;    //开启外部中断0
  247.                         EX1=1;    //开启外部中断1
  248.                         if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
  249.                         if(shanshuo_st) {Disp_alarm(shangxian);}  //闪烁
  250.                 }
  251.                 else if(set_st==2)        //设置下限时
  252.                 {
  253.                         BEEP=1;    //关闭蜂鸣器
  254.                         ALAM=1;
  255.                         ALAM1=1;   //关闭继电器
  256.                         EX0=1;    //开启外部中断0
  257.                         EX1=1;    //开启外部中断1
  258.                         if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
  259.                         if(shanshuo_st) {Disp_alarm(xiaxian);}         //闪烁
  260.                 }
  261.         }
  262. }

  263. /*****定时器0中断服务程序*****/
  264. void timer0(void) interrupt 1
  265. {
  266. TH0=0x3c;
  267. TL0=0xb0;                 //12MHz晶振时定时50ms
  268. x++;
  269. }
  270. /*****外部中断0服务程序*****/
  271. void int0(void) interrupt 0
  272. {
  273.         EX0=0;      //关外部中断0
  274.         if(DEC==0&&set_st==1)           //设置上限时按下减按键
  275.         {
  276.                 do
  277.                 {
  278.                         Disp_alarm(shangxian);        //显示设置
  279.                 }
  280.                 while(DEC==0);
  281.                 shangxian--;                                //将上限值减1
  282.                 if(shangxian<=xiaxian)shangxian=xiaxian+1;          //上限值最小比下限值大1
  283.         }
  284.         else if(DEC==0&&set_st==2)         //设置下限时按下减按键
  285. ……………………

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

所有资料51hei提供下载:
程序.zip (56.89 KB, 下载次数: 46)
回复

使用道具 举报

ID:484263 发表于 2019-3-28 18:31 | 显示全部楼层
有电路原理图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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