目次
一、主要功能
二、硬件资源
三、步伐编程
四、实现征象
一、主要功能
基于STC89C52RC单片机,接纳四个按键,通过DS18B20检测温度,开机表实际时温度
第一个按键为切换功能按键,按下后,可以设置烧水温度的大小,两个按键负责增减。
再按切换功能按键,可以设置保温温度的大小,两个按键负责增减。
再按切换功能按键,可以设置烧开温度的大小,两个按键负责增减。
再按切换功能按键,可以设置定时时间,两个按键负责增减。
然后第四个返回键点击返回后,体系开始倒计时。
接纳三个LED灯分别对应烧水温度、保温温度、烧开温度的状态。
比如设置烧水温度为50-80,保温温度为80,烧开温度为100;
如果检测温度在50-80之间,则烧水温度状态灯点亮,如果监测温度在80,则保温温度状态灯点亮。
如果检测温度在100,则烧开温度状态灯点亮。
接纳滑动变阻器连接ADC0832数模转换器模拟水位监测,这个阈值在步伐里设置好,分别为50和150;
如果低于50或高于150,则为缺水或溢水,则蜂鸣器报警,此时所有LED灯熄灭。
全程都通过串口及时打印温度给电脑。
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
三、步伐编程
- #include <REGX52.H>
- #include<intrins.h>
- #include<stdio.h>
- #include "Delay.h"
- #include "LCD1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit DS=P2^4; //DS18B20温度传感器
- sbit CS=P1^0; //adc0832引脚
- sbit CLK=P1^1;
- sbit DIO=P1^2;
- sbit key1=P3^2;
- sbit key2=P3^3;
- sbit key3=P3^4;
- sbit key4=P3^5;
- sbit beep = P3^6;
- sbit ssled=P1^5;
- sbit bwled=P1^4;
- sbit skled=P1^3;
- sbit led = P1^6;
- unsigned char count;
- typedef unsigned char u8;
- typedef unsigned int u16;
- static uint temp;
- static float ftemp = 0.0f;//温度转变
- uint temp;
- static int sswd=70,bwwd=80,skwd=100,swxx=50,swsx=150; //烧水温度,保温温度,烧开温度,水位下限,水位上限
- static unsigned char num;
- static int num1;
- static int flag=1;
- static int flag2=0;
- static int flag3=0;
- static int time=00;
- uchar count=0;
- static double u,u1;
- static int timeflag = 0;
- static int seconds=50;
- void tmpchange();
- uint tmp();
- void beep_warning();
- void ajpd();
- void swhq();
- void xianshi();
- void Time0_Init() //定时器初始化
- {
- TMOD = 0x21;
- TH0 = (65535-50000)/256;
- TL0 = (65535-50000)%256;
- IE = 0x82;
- TR0 = 1;
- }
- void Time0_Int() interrupt 1 //中断程序
- {
- TH0 = (65535-50000)/256; //重新赋值 50ms
- TL0 = (65535-50000)%256;
- num++;
- if(num==5)
- {
- tmpchange(); //让18b20开始转换温度
- temp = tmp(); //读取温度
- ftemp = temp/10.0f; //转换温度
- num=0;
- }
- num1++;
- if(num1 == 20)
- {
- printf("温度=%3.0f℃\r\n",ftemp);
- num1 = 0;
- }
- if(timeflag==1)
- {
- seconds--;
- if(seconds==0)
- {
- time--;
- if(time == 0)
- {
- timeflag = 0;
- }
- seconds=20;
- }
- }
- }
- uchar get_AD_Res() //ADC0832启动读取函数 有害气体
- {
- uchar i, data1=0, data2=0;
- CS=0;
-
- CLK=0;DIO=1;_nop_();
- CLK=1;_nop_();
-
- CLK=0;DIO=1;_nop_();
- CLK=1;_nop_();
-
- CLK=0;DIO=0;_nop_();
- CLK=1;_nop_();
-
- CLK=0;DIO=1;_nop_();
-
- for(i=0; i<8; i++)
- {
- CLK=1;_nop_();
- CLK=0;_nop_();
- data1=(data1<<1)|(uchar)DIO;
- }
-
- for(i=0; i<8; i++)
- {
- data2=data2|(uchar)DIO<<i;
- CLK=1;_nop_();
- CLK=0;_nop_();
- }
- CS=1;
-
- return(data1 == data2)?data1:0;
- }
- void dsreset(void) //发出命令
- {
- uint i;
- DS=0;
- i=103; //将总线拉低480us~960us
- while(i>0)i--;
- DS=1; //然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低
- i=4; //15us~60us等待
- while(i>0)i--;
- //while(DS);
- }
- bit tmpreadbit(void) //读取数据
- {
- uint i;
- bit dat;
- DS=0;i++; //i++ for delay
- DS=1;i++;i++;
- dat=DS;
- i=8;while(i>0)i--;
- return (dat);
- }
- uchar tmpread(void) //读取数据
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbit();
- dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
- }
- return(dat);
- }
- void tmpwritebyte(uchar dat) //传输数据给DS18B20
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //write 1
- {
- DS=0;
- i++;i++;
- DS=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //write 0
- i=8;while(i>0)i--;
- DS=1;
- i++;i++;
- }
- }
- }
- void tmpchange(void) //DS18B20开始工作
- {
- dsreset();
- Delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0x44);
- }
- uint tmp() //获得温度
- {
- float tt;
- uchar a,b;
- dsreset();
- Delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0xbe);
- a=tmpread();//低八位
- b=tmpread();//高八位
- temp=b;
- temp<<=8; //two byte compose a int variable
- temp=temp|a;
- tt=temp*0.0625; //算出来的是测到的温度,数值可到小数点后两位
- temp=tt*10+0.5; //为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数
- return temp;
- }
- void beep_warning() //温度传感器蜂鸣器警报并且电机转动
- {
- if(ftemp>sswd && ftemp < bwwd)
- {
- ssled = 1;
- }
- else
- {
- ssled = 0;
- }
- if(ftemp>=bwwd && ftemp < skwd)
- {
- bwled = 1;
- }
- else
- {
- bwled = 0;
- }
- if(ftemp >= skwd)
- {
- skled = 1;
- }
- else
- {
- skled = 0;
- }
- if(time == 0)
- {
- flag2 = 0;
- ssled = 0;
- bwled = 0;
- skled = 0;
- }
- }
- //串口初始化
- void init_com(void)
- {
- TMOD =0x21; //设T0为方式1,GATE=1;
- SCON=0x50; //开启串口
- TH1=0xFD; //波特率是9600bps
- TL1=0xFD;
- TR1=1; //开启定时器
- TI=1;
- EA=1;
- }
- void main() //主函数
- {
- LCD_Init(); //显示屏初始化
- Time0_Init();
- init_com();
- beep = 1;
- ssled = 0;
- bwled = 0;
- skled = 0;
- led = 0;
- while(1)
- {
- ajpd(); //按键判断
- swhq(); //水位获取
- xianshi();//显示
- if(flag2 == 1 && flag3 == 1)
- {
- beep_warning();//不同状态显示
- }
- if(u1>swxx && u1<swsx)
- {
- beep = 1;
- flag3 = 1;
- }
- else
- {
- beep = 0;
- led = 1;
- flag3 = 0;
- ssled = 0;
- bwled = 0;
- skled = 0;
- time = 0;
- }
- }
- }
-
- void swhq()
- {
- u=get_AD_Res(); //液位
- u1 = (u/255)*180;
- }
- void xianshi()
- {
- LCD_ShowString(1,1,"wendu:");
- LCD_ShowNum(1,7,ftemp,3); //显示温度
- LCD_ShowString(1,10,"sw:");
- LCD_ShowNum(1,13,u1,3); //显示水位
- LCD_ShowNum(2,1,sswd,2); //显示烧水温度
- LCD_ShowNum(2,4,bwwd,2); //显示保温温度
- LCD_ShowNum(2,7,skwd,3); //显示烧开温度
- LCD_ShowString(2,10,"djs:");
- LCD_ShowNum(2,14,time,2); //时间
- }
- void ajpd()
- {
- if(key4==0)
- {
- Delay(150);
- if(key4==0)
- {
- flag++;
- if(flag>4)
- {
- flag = 0;
- }
- }
- }
-
- if(!key2)
- {
- switch(flag)
- {
- case 1:sswd++;break;
- case 2:bwwd++;break;
- case 3:skwd++;break;
- case 4:time+=30;if(time>90){time = 90;}break;
- }
- while(!key2);
- }
-
- if(!key3)
- {
- switch(flag)
- {
- case 1:sswd--;break;
- case 2:bwwd--;break;
- case 3:skwd--;break;
- case 4:time-=30;if(time<0){time = 0;}break;
- }
- while(!key3);
- }
-
- if(!key1)
- {
- flag2=1;
- flag=0;
- timeflag=1;
- while(!key1);
- }
-
- }
复制代码 四、实现征象
具体动态结果看B站演示视频:
基于单片机的烧水壶体系设计_哔哩哔哩_bilibili
全部资料(源步伐、仿真文件、安装包、演示视频):
百度网盘资料下载https://pan.baidu.com/s/1SqGW0Bg_J_bVHhplPzHAfA?pwd=0cid
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |