找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机温度控制程序+仿真(按键设置上中下限)

  [复制链接]
跳转到指定楼层
楼主
1.可按键设置上中下限
2.有声光报警
3.有风扇

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


单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. #include <math.h>
  4. #include "main.h"


  5.   char code LED_display[14] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0XFF,0x89,0XC7};  //共阳数码管段码
  6.                              // 0     1    2   3     4    5    6     7   8    9    -                    H    L
  7.   char code bit_sel[4] = {0x01,0x02,0x04,0x08};
  8.   char dis[4];
  9.                                                                  


  10. unsigned char TL0_temp;         /*暂存TL0的初值*/
  11. unsigned char TH0_temp;         /*暂存TH0的初值*/
  12. #define INT_CLOCK 5 /*INT_CLOCK为定时值,单位为ms ,此处定义为5ms*/
  13. #define CRY_FREQUENCY 12000000 /*CRY_FREQUENCY为晶振频率,单位为Hz*/

  14. bit flag = 0; //0-正温度  1-负温度
  15. sbit key1 = P3^2;  //设置按键
  16. sbit key2 = P3^3;  //增量按键
  17. sbit key3 = P3^4;  //减量按键

  18. bit bKey1,bKey2,bKey3;
  19. uchar countSet = 0;


  20. sbit ledRed = P1^0;             //红灯
  21. sbit ledYellow = P1^1;         //黄灯
  22. sbit ledGreen = P1^2;         //绿灯

  23. sbit fan = P1^6;  //风扇
  24. sbit beep = P1^5; //蜂鸣器



  25. char shutDowmH = 85; //关机温度
  26. char SetH = 65;          //高温上限
  27. char SetL = 30;          //低温下限

  28. char alarm = 0;
  29. sbit DQ=P3^6;           /* 18B20数据引脚*/


  30. #define temp_h P3|=0x40//单片机向DS18B20输出高电平
  31. #define temp_l P3&=0xbf//单片机向DS18B20输出低电平





  32. void delay(uint z)
  33. {
  34.         uint x,y;
  35.         for(x=z;x>0;x--)
  36.                 for(y=110;y>0;y--);
  37. }



  38. void Timer0_init()
  39. {
  40.         unsigned long T0_temp;                                     /*暂存T0的初始值        */
  41.         T0_temp = 65536-((INT_CLOCK *CRY_FREQUENCY /1000)/12);    /*T0初始值计算公式,参考教科书*/
  42.         TL0_temp = T0_temp & 0xff;
  43.         TH0_temp = T0_temp >> 8;
  44.         TL0 = TL0_temp;
  45.         TH0 = TH0_temp;
  46.         TMOD |= 0x01;
  47.         TR0 = 1;  
  48.         ET0 = 1;   
  49.         EA = 1;                                               /*开定时器0中断*/

  50. }

  51. void INT0_Init()
  52. {
  53.         EX0 = 1;
  54.         IT0 = 1;
  55. }

  56. void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
  57. {
  58.         unsigned int i,j;
  59.    for(i=0;i<ms;i++)
  60.     for(j=0;j<100;j++);
  61. }


  62. void keyScan()
  63. {
  64.   
  65.    if(!key2)
  66.    {
  67.      delay1ms(300);
  68.          if(!key2)
  69.            bKey2 = 1;
  70.    }
  71.    if(!key3)
  72.    {
  73.      delay1ms(300);
  74.          if(!key3)
  75.            bKey3 = 1;
  76.    }
  77. }






  78. //数码管显示温度值

  79. void displayTemp(uint temp)
  80. {
  81.         uchar i;

  82.            if(countSet == 0) //显示实际的测试温度
  83.         {
  84.         if(flag == 1)  //负温度
  85.         {
  86.             
  87.                 dis[0] = 11;
  88.                 dis[1] = 10;
  89.                 dis[2] = temp/100;
  90.                 dis[3] = temp%100/10;
  91.         }
  92.         else //正温度
  93.         {
  94.          
  95.            dis[0] = 11;
  96.            dis[1] = temp/1000;
  97.            dis[2] = temp%1000/100;
  98.            dis[3] = temp%1000%100/10;

  99.         }
  100.         }
  101.         else if(countSet == 1) //显示设置的温度下限
  102.         {
  103.             dis[0] = 1;  //显示'1'
  104.                
  105.                 dis[1] = 10;
  106.                 dis[2] = SetL/10;
  107.                 dis[3] = SetL%10;
  108.          
  109.            
  110.         }
  111.         else if(countSet == 2) //显示设置的温度上限
  112.         {
  113.            dis[0] = 2;  //显示'2'
  114.                
  115.                 dis[1] = 10;
  116.                 dis[2] = SetH/10;
  117.                 dis[3] = SetH%10;
  118.         }
  119.         else if(countSet == 3) //显示设置的关机温度
  120.         {
  121.             dis[0] = 3;  //显示'3'
  122.                
  123.                 dis[1] = 10;
  124.                 dis[2] = shutDowmH/10;
  125.                 dis[3] = shutDowmH%10;
  126.         }

  127. }







  128. /***********ds18b20延迟子函数(晶振12MHz )*******/

  129. void delayms(uint x)//延时1ms
  130. {
  131.         uint y,z;
  132.         for(y=x;y>0;y--)
  133.                 for(z=110;z>0;z--);
  134. }

  135. /**********ds18b20初始化函数**********************/

  136. void Ds18b20_reset()//DS18B20初始化
  137. {
  138.         uchar count;
  139.         uint i=2200;
  140.         temp_l;
  141.         for(count=240;count>0;count--);//延时480us
  142.         temp_h;
  143.         while(DQ&&(i>0)) i--;
  144.         for(count=240;count>0;count--);//延时480us
  145. }

  146. /***********ds18b20读一个字节**************/  

  147. uchar Ds18b20_read()//从DS18B20读一个字节
  148. {
  149.         uchar i,count,dat;
  150.         for(i=8;i>0;i--)
  151.         {
  152.                 dat>>=1;
  153.                 temp_l;
  154.                 for(count=1;count>0;count--);
  155.                 temp_h;//此语句必须有,参考datasheet的P15
  156.                 for(count=1;count>0;count--);
  157.                 if(DQ)
  158.                         dat|=0x80;
  159.                 for(count=30;count>0;count--);        
  160.         }
  161.         return dat;
  162. }

  163. /*************ds18b20写一个字节****************/  

  164. void Ds18b20_write(uchar dat)//向DS18B20写一个字节
  165. {
  166.         uchar count;
  167.         uchar i;
  168.         for(i=8;i>0;i--)
  169.         {
  170.                 temp_l;
  171.                 for(count=1;count>0;count--);
  172.                
  173.                 if(dat&0x01==0x01)
  174.                         temp_h;
  175.                 else
  176.                         temp_l;
  177.                 for(count=30;count>0;count--);
  178.                 temp_h;
  179.                 dat>>=1;        
  180.         }        
  181. }
  182. /**************读取ds18b20当前温度************/
  183. uint ReadTemperature(void)
  184. {
  185.         uint dat;
  186.             uchar dat1,dat2;//保存读出的温度
  187.                 Ds18b20_reset();
  188.                 Ds18b20_write(0xcc);
  189.                 Ds18b20_write(0x44);//发送温度转换命令
  190.                 delayms(1000);//延时1s,等待温度转换完成
  191.                 Ds18b20_reset();
  192.                 Ds18b20_write(0xcc);
  193.                 Ds18b20_write(0xbe);//发送读温度寄存器命令
  194.                 dat1=Ds18b20_read();
  195.                 dat2=Ds18b20_read();
  196.             if(dat2 >= 240)         //负温度
  197.                 {
  198.                                 dat=(~(dat2*256+dat1)+1)*(0.0625*10);
  199.                                 flag = 1;
  200.             }
  201.                 else  //正温度
  202.                 {
  203.                       flag = 0;
  204.                           dat=(dat2*256+dat1)*(0.0625*10);
  205.                 }
  206.                 return dat;
  207. }

  208. void main()
  209. {

  210.         
  211.          uint temp;
  212.           Timer0_init();  //定时器0初始化
  213.           INT0_Init();

  214.           EA = 1;           //开总中断
  215.           fan = 0;
  216.           countSet = 0;        
  217.         while(1)
  218.         {
  219.             if(countSet == 0)
  220.                 temp =         ReadTemperature();  //采集DS18B20的温度值
  221.                 if(flag == 1)  //负温度
  222.                 {
  223.                       ledYellow = 0;   //黄灯亮
  224.                           ledRed = 1;
  225.                           ledGreen = 1;
  226.                           displayTemp(temp); //显示温度
  227.                           fan = 0;//风扇关闭
  228.                           alarm = 0;
  229.                 }
  230.                 else
  231.                 {
  232.                      if(temp/10 > shutDowmH)
  233.                          {
  234.                               dis[0] = 11;
  235.                       dis[1] = 11;
  236.                       dis[2] = 11;
  237.                       dis[3] = 11; //数码管熄灭
  238.                                   ledYellow = 1;   //灯全熄灭
  239.                               ledRed = 1;
  240.                               ledGreen = 1;
  241.                                   fan = 0; //风扇停转
  242.                                   alarm = 0;
  243.                          }
  244.                          else if(temp/10 > SetH)
  245.                          {
  246.                             displayTemp(temp); //显示温度
  247.                                 ledYellow = 1;   //指示灯变红
  248.                               ledRed = 0;
  249.                               ledGreen = 1;
  250.                                    fan = 1; //风扇开启
  251.                                         alarm = 1;
  252.                          }
  253.                          else if(temp/10 > SetL)
  254.                          {
  255.                             displayTemp(temp); //显示温度 或者设置
  256.                                 ledYellow = 1;   //指示灯变绿
  257.                               ledRed = 1;
  258.                               ledGreen = 0;
  259.                                    fan = 1; //风扇开启
  260.                                  alarm = 0;
  261.                          }
  262.                          else
  263.                          {
  264.                             displayTemp(temp); //显示温度
  265.                                 ledYellow = 0;   //指示灯变黄
  266.                               ledRed = 1;
  267.                               ledGreen = 1;
  268.                                    fan = 0; //风扇关闭
  269.                                    alarm = 0;
  270.                          }               
  271.                 }


  272.                 keyScan();
  273.                 if(bKey2)  //温度加
  274.                 {
  275.                   bKey2 = 0;
  276.                   if(countSet == 1)         //设置低温
  277.                   {
  278.                       if(SetL < SetH)
  279.                             SetL++;
  280.                   }
  281.                   if(countSet == 2)          //设置高温
  282.                   {
  283.                       if(SetH < shutDowmH)
  284.                             SetH++;
  285.                   }
  286.                   if(countSet == 3)          //设置关机温度
  287.                   {
  288.                       if(shutDowmH < 99)
  289.                             shutDowmH++;
  290.                   }
  291.                 }
  292.                 if(bKey3)        //温度减
  293.                 {
  294.                   bKey3 = 0;
  295.                   if(countSet == 1)          //设置低温
  296.                   {
  297.                       if(SetL > 0)
  298.                             SetL--;
  299.                   }
  300.                   if(countSet == 2)          //设置高温
  301.                   {
  302.                       if(SetH > SetL)
  303.                             SetH--;
  304.                   }
  305.                   if(countSet == 3)         //设置关机温度
  306.                   {
  307.                       if(shutDowmH > SetH)
  308.                             shutDowmH--;
  309.                   }
  310.                 }

  311.         }           
  312. }




  313. unsigned char count_5ms = 0;
  314. unsigned int count_5s = 0;

  315. void T0_interrupt(void) interrupt 1         
  316. {
  317.         TH0 += TH0_temp;
  318.         TL0 += TL0_temp;
  319.         
  320.         count_5ms++;
  321.         if(count_5ms >= 4)
  322.            count_5ms = 0;

  323.     P2 = 0X00;
  324.         P0 = LED_display[dis[count_5ms]];
  325.         P2 = bit_sel[count_5ms];

  326.         if(alarm == 1)
  327.         {
  328.            
  329.            if(count_5s < 1000)
  330.            {
  331.               count_5s++;
  332.                   beep = !beep;
  333.            }   
  334.         }
  335.         else
  336.           count_5s = 0;
  337. }

  338. /*
  339.   外部中断0服务处理函数,记录“设置”按键按下的次数
  340. */

  341. void int_int0() interrupt 0
  342. {
  343.         countSet++;
  344.         if(countSet > 3)
  345.           countSet = 0;
  346. }
复制代码

所有资料51hei提供下载:
CPU温度控制(1).zip (103.31 KB, 下载次数: 307)

评分

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

查看全部评分

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

使用道具 举报

来自 2#
ID:668055 发表于 2020-5-30 18:11 | 只看该作者
你好 请问void Ds18b20_reset()//DS18B20初始化
{
        uchar count;
        uint i=2200;
        temp_l;
        for(count=240;count>0;count--);//延时480us
        temp_h;
        while(DQ&&(i>0)) i--;
        for(count=240;count>0;count--);//延时480us
temp_h和temp_l是代表了拉高总线和拉低总线吗?为何延时不用上边刚定义的函数,要用count呢?
回复

使用道具 举报

板凳
ID:437339 发表于 2018-12-26 15:27 | 只看该作者
你好。我是新手,dis[1]=11,为什么数码管熄灭啊
回复

使用道具 举报

地板
ID:239620 发表于 2019-2-23 10:26 | 只看该作者
谢谢分享,学习学习!
回复

使用道具 举报

5#
ID:468833 发表于 2019-4-12 10:20 | 只看该作者
谢谢分享
回复

使用道具 举报

6#
ID:524279 发表于 2019-4-29 10:51 来自手机 | 只看该作者
楼主发全程序啊
回复

使用道具 举报

7#
ID:409381 发表于 2019-4-29 12:28 | 只看该作者
谢谢分享楼主大作
回复

使用道具 举报

8#
ID:208733 发表于 2020-2-2 18:47 | 只看该作者
谢谢分享
回复

使用道具 举报

9#
ID:404346 发表于 2020-3-29 10:38 | 只看该作者
谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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