基于单片机的烧水壶体系设计

打印 上一主题 下一主题

主题 1927|帖子 1927|积分 5781



目次
一、主要功能
二、硬件资源
三、步伐编程
四、实现征象

一、主要功能

基于STC89C52RC单片机,接纳四个按键,通过DS18B20检测温度,开机表实际时温度
第一个按键为切换功能按键,按下后,可以设置烧水温度的大小,两个按键负责增减。
再按切换功能按键,可以设置保温温度的大小,两个按键负责增减。
再按切换功能按键,可以设置烧开温度的大小,两个按键负责增减。
再按切换功能按键,可以设置定时时间,两个按键负责增减。
然后第四个返回键点击返回后,体系开始倒计时。
接纳三个LED灯分别对应烧水温度、保温温度、烧开温度的状态。
比如设置烧水温度为50-80,保温温度为80,烧开温度为100;
如果检测温度在50-80之间,则烧水温度状态灯点亮,如果监测温度在80,则保温温度状态灯点亮。
如果检测温度在100,则烧开温度状态灯点亮。
接纳滑动变阻器连接ADC0832数模转换器模拟水位监测,这个阈值在步伐里设置好,分别为50和150;
如果低于50或高于150,则为缺水或溢水,则蜂鸣器报警,此时所有LED灯熄灭。
全程都通过串口及时打印温度给电脑。

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、步伐编程

  1. #include <REGX52.H>
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #include "Delay.h"
  5. #include "LCD1602.h"
  6. #define uchar unsigned char
  7. #define uint unsigned  int
  8. sbit DS=P2^4;                 //DS18B20温度传感器
  9. sbit CS=P1^0;                 //adc0832引脚
  10. sbit CLK=P1^1;
  11. sbit DIO=P1^2;
  12. sbit key1=P3^2;
  13. sbit key2=P3^3;
  14. sbit key3=P3^4;
  15. sbit key4=P3^5;
  16. sbit beep = P3^6;
  17. sbit ssled=P1^5;
  18. sbit bwled=P1^4;
  19. sbit skled=P1^3;
  20. sbit led = P1^6;
  21. unsigned char count;
  22. typedef unsigned char u8;
  23. typedef unsigned int  u16;
  24. static uint temp;
  25. static float ftemp = 0.0f;//温度转变
  26. uint temp;
  27. static int sswd=70,bwwd=80,skwd=100,swxx=50,swsx=150; //烧水温度,保温温度,烧开温度,水位下限,水位上限
  28. static unsigned char num;
  29. static int num1;
  30. static int flag=1;
  31. static int flag2=0;
  32. static int flag3=0;
  33. static int time=00;
  34. uchar  count=0;
  35. static double u,u1;
  36. static int timeflag = 0;
  37. static int seconds=50;
  38. void tmpchange();
  39. uint tmp();
  40. void beep_warning();
  41. void ajpd();
  42. void swhq();
  43. void xianshi();
  44. void Time0_Init()          //定时器初始化
  45. {
  46.         TMOD = 0x21;
  47.         TH0  = (65535-50000)/256;
  48.         TL0  = (65535-50000)%256;
  49.         IE = 0x82;
  50.         TR0 = 1;
  51. }
  52. void Time0_Int() interrupt 1 //中断程序
  53. {
  54.    TH0  = (65535-50000)/256;             //重新赋值 50ms
  55.    TL0  = (65535-50000)%256;
  56.     num++;
  57.         if(num==5)
  58.         {
  59.             tmpchange();        //让18b20开始转换温度
  60.             temp = tmp();       //读取温度
  61.             ftemp = temp/10.0f; //转换温度
  62.                 num=0;
  63.         }
  64.         num1++;
  65.         if(num1 == 20)
  66.         {
  67.                 printf("温度=%3.0f℃\r\n",ftemp);       
  68.                 num1 = 0;
  69.         }
  70.         if(timeflag==1)
  71.         {
  72.                 seconds--;
  73.                 if(seconds==0)
  74.                 {
  75.                 time--;
  76.                         if(time == 0)
  77.                         {
  78.                                 timeflag = 0;
  79.                         }
  80.                 seconds=20;
  81.                 }
  82.         }
  83. }
  84. uchar get_AD_Res()            //ADC0832启动读取函数 有害气体
  85. {
  86.         uchar i, data1=0, data2=0;
  87.         CS=0;
  88.        
  89.         CLK=0;DIO=1;_nop_();
  90.         CLK=1;_nop_();
  91.        
  92.         CLK=0;DIO=1;_nop_();
  93.         CLK=1;_nop_();
  94.        
  95.         CLK=0;DIO=0;_nop_();
  96.         CLK=1;_nop_();
  97.        
  98.         CLK=0;DIO=1;_nop_();
  99.        
  100.         for(i=0; i<8; i++)
  101.         {
  102.                 CLK=1;_nop_();
  103.                 CLK=0;_nop_();
  104.                 data1=(data1<<1)|(uchar)DIO;
  105.         }
  106.        
  107.         for(i=0; i<8; i++)
  108.         {
  109.                 data2=data2|(uchar)DIO<<i;
  110.                 CLK=1;_nop_();
  111.                 CLK=0;_nop_();
  112.         }
  113.         CS=1;
  114.        
  115.         return(data1 == data2)?data1:0;
  116. }
  117. void dsreset(void)            //发出命令
  118. {
  119.   uint i;
  120.   DS=0;                              
  121.   i=103;                                   //将总线拉低480us~960us
  122.   while(i>0)i--;
  123.   DS=1;                                           //然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低
  124.   i=4;                                           //15us~60us等待
  125.   while(i>0)i--;
  126.   //while(DS);
  127. }
  128. bit tmpreadbit(void)          //读取数据
  129. {
  130.    uint i;
  131.    bit dat;
  132.    DS=0;i++;          //i++ for delay
  133.    DS=1;i++;i++;
  134.    dat=DS;
  135.    i=8;while(i>0)i--;
  136.    return (dat);
  137. }
  138. uchar tmpread(void)           //读取数据
  139. {
  140.   uchar i,j,dat;
  141.   dat=0;
  142.   for(i=1;i<=8;i++)
  143.   {
  144.     j=tmpreadbit();
  145.     dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  146.   }
  147.   return(dat);
  148. }
  149. void tmpwritebyte(uchar dat)  //传输数据给DS18B20
  150. {
  151.   uint i;
  152.   uchar j;
  153.   bit testb;
  154.   for(j=1;j<=8;j++)
  155.   {
  156.     testb=dat&0x01;
  157.     dat=dat>>1;
  158.     if(testb)     //write 1
  159.     {
  160.       DS=0;
  161.       i++;i++;
  162.       DS=1;
  163.       i=8;while(i>0)i--;
  164.     }
  165.     else
  166.     {
  167.       DS=0;       //write 0
  168.       i=8;while(i>0)i--;
  169.       DS=1;
  170.       i++;i++;
  171.     }
  172.   }
  173. }
  174. void tmpchange(void)          //DS18B20开始工作
  175. {
  176.   dsreset();
  177.   Delay(1);
  178.   tmpwritebyte(0xcc);  
  179.   tmpwritebyte(0x44);  
  180. }                                          
  181. uint tmp()                    //获得温度
  182. {
  183.   float tt;
  184.   uchar a,b;
  185.   dsreset();
  186.   Delay(1);
  187.   tmpwritebyte(0xcc);
  188.   tmpwritebyte(0xbe);
  189.   a=tmpread();//低八位
  190.   b=tmpread();//高八位
  191.   temp=b;
  192.   temp<<=8;             //two byte  compose a int variable
  193.   temp=temp|a;
  194.   tt=temp*0.0625; //算出来的是测到的温度,数值可到小数点后两位
  195.   temp=tt*10+0.5; //为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数
  196.   return temp;
  197. }
  198. void beep_warning() //温度传感器蜂鸣器警报并且电机转动
  199. {
  200.         if(ftemp>sswd && ftemp < bwwd)
  201.         {
  202.                 ssled = 1;
  203.         }
  204.         else
  205.         {
  206.                 ssled = 0;
  207.         }
  208.         if(ftemp>=bwwd && ftemp < skwd)
  209.         {
  210.                 bwled = 1;
  211.         }
  212.         else
  213.         {
  214.                 bwled = 0;
  215.         }
  216.         if(ftemp >= skwd)
  217.         {
  218.                 skled = 1;
  219.         }
  220.         else
  221.         {
  222.                 skled = 0;
  223.         }
  224.         if(time == 0)
  225.         {
  226.                 flag2 = 0;
  227.                 ssled = 0;
  228.           bwled = 0;
  229.           skled = 0;
  230.         }
  231. }
  232. //串口初始化
  233. void init_com(void)
  234. {
  235.         TMOD =0x21;                   //设T0为方式1,GATE=1;
  236.         SCON=0x50;        //开启串口
  237.         TH1=0xFD;          //波特率是9600bps
  238.         TL1=0xFD;
  239.         TR1=1;                           //开启定时器
  240.         TI=1;
  241.         EA=1;
  242. }
  243. void main()                                          //主函数
  244. {       
  245.         LCD_Init();         //显示屏初始化
  246.         Time0_Init();
  247.         init_com();
  248.         beep = 1;
  249.         ssled = 0;
  250.         bwled = 0;
  251.         skled = 0;
  252.         led = 0;
  253.         while(1)
  254.         {
  255.                 ajpd(); //按键判断
  256.                 swhq(); //水位获取
  257.                 xianshi();//显示
  258.                 if(flag2 == 1  && flag3 == 1)
  259.                 {
  260.                 beep_warning();//不同状态显示
  261.                 }
  262.         if(u1>swxx && u1<swsx)
  263.         {
  264.                 beep = 1;
  265.     flag3 = 1;
  266.         }
  267.         else
  268.         {
  269.                 beep = 0;
  270.                 led = 1;
  271.                 flag3 = 0;
  272.                 ssled = 0;
  273.           bwled = 0;
  274.           skled = 0;
  275.                 time = 0;
  276.         }
  277.         }
  278. }
  279.        
  280. void swhq()
  281. {
  282.                 u=get_AD_Res(); //液位
  283.                 u1 = (u/255)*180;
  284. }
  285. void xianshi()
  286. {
  287.                 LCD_ShowString(1,1,"wendu:");
  288.                 LCD_ShowNum(1,7,ftemp,3); //显示温度
  289.     LCD_ShowString(1,10,"sw:");
  290.                 LCD_ShowNum(1,13,u1,3); //显示水位
  291.                 LCD_ShowNum(2,1,sswd,2); //显示烧水温度
  292.                 LCD_ShowNum(2,4,bwwd,2); //显示保温温度
  293.                 LCD_ShowNum(2,7,skwd,3); //显示烧开温度
  294.                 LCD_ShowString(2,10,"djs:");
  295.                 LCD_ShowNum(2,14,time,2); //时间
  296. }
  297. void ajpd()
  298. {
  299.         if(key4==0)
  300.         {
  301.                 Delay(150);
  302.                 if(key4==0)
  303.                 {
  304.                   flag++;
  305.                 if(flag>4)
  306.                 {
  307.                         flag = 0;
  308.                 }
  309.         }
  310.         }
  311.        
  312.         if(!key2)
  313.         {
  314.                 switch(flag)
  315.                 {
  316.                         case 1:sswd++;break;
  317.                         case 2:bwwd++;break;
  318.                         case 3:skwd++;break;
  319.                         case 4:time+=30;if(time>90){time = 90;}break;
  320.                 }
  321.     while(!key2);
  322.         }
  323.        
  324.         if(!key3)
  325.         {
  326.                 switch(flag)
  327.                 {
  328.                         case 1:sswd--;break;
  329.                         case 2:bwwd--;break;
  330.                         case 3:skwd--;break;
  331.                         case 4:time-=30;if(time<0){time = 0;}break;
  332.                 }
  333.     while(!key3);
  334.         }
  335.        
  336.         if(!key1)
  337.         {
  338.                 flag2=1;
  339.                 flag=0;
  340.                 timeflag=1;
  341.     while(!key1);
  342.         }
  343.        
  344. }
复制代码
四、实现征象

具体动态结果看B站演示视频:
基于单片机的烧水壶体系设计_哔哩哔哩_bilibili
全部资料(源步伐、仿真文件、安装包、演示视频):
百度网盘资料下载
https://pan.baidu.com/s/1SqGW0Bg_J_bVHhplPzHAfA?pwd=0cid



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

知者何南

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表