目录
一、主要功能
二、硬件资源
三、程序编程
四、实现现象
一、主要功能
基于51单片机
采用滑动变阻器连接ADC0832数模转换器模拟角度传感器,水位传感器;
采样DS18B20温度传感器检测温度
通过LCD1602显示,第一行显示温度、水位、角度、指定温度
两个按键负责L298N驱动电机的正反转:
按键按下不动,电机正转,松开停止;第二个按键按下,电机反转,松开停止
辅助热源按键,按下后,对应的LED灯亮起,此时两个按键负责辅热温度的增减,一次调整10度
温度超过阈值,蜂鸣器启动;
手动上水按键可以启动进水阀继电器和通气阀继电器;
自动上水通过水位判断:水位低于阈值后,辅热对应的LED灯关掉,进水阀和通气阀打开;
水位高于阈值后,打开排水阀和通气阀;
然后如果加热到达阈值和水位到达阈值,蜂鸣器报警2秒。
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
编辑
三、程序编程
#include "public.h"#include <intrins.h> //定义头文件#include <stdio.h> //定义头文件#include "lcd1602.h"#include "ds18b20.h"#include "stdio.h"#include "i2c.h"#define uchar unsigned char //定义变量#define uint unsigned int //定义变量char buff\[15\];char buff1\[3\];
unsigned char readTem = 0 ;//定义读时间标志unsigned char readADCFlag = 0 ; //读取标志unsigned long time_20ms=0; //定时器计数sbit IN1 = P1^0; //进水阀sbit IN2 = P1^1;//排水阀sbit KEY1=P1^2;
sbit KEY2=P1^3;
sbit KEY3=P1^4;
sbit KEY4=P2^2;
sbit IN3=P1^5; //通气阀sbit IN4=P1^6; //LED灯sbit beep=P1^7;
sbit key5=P3^3;
sbit key6=P3^4;
sbit out1=P3^5;
sbit out2=P3^6;sbit CS=P3^0; //adc0832引脚sbit CLK=P3^1; //adc0832引脚sbit DIO=P3^2; //adc0832引脚void Init\_Timer0(void); //函数声明float Lv=0.0; //光照采集电压float Lval =0; //光照值static int sdflag=0;float u;uchar get\_AD_Res() //ADC0832启动读取函数{uchar i, data1=0, data2=0; //赋值变量CS=0; //CS赋值低电平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; //返回值}/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void main(){ u8 i=0; int temp\_yz=60; float temp\_value; char temp_buf\[16\]; int flag=0; int one=0; unsigned char midval; ds18b20_init();//初始化DS18B20Init\_Timer0(); lcd1602\_init();out1 = 0;out2 = 0; while(1){u=get\_AD\_Res(); //读取ADC0832值if(u>80){u=80;} else if(u<10){u=10;}temp\_value=ds18b20\_read_temperture();//保留温度值小数后一位if(KEY2==0){ delay_ms(20);{ if(KEY2==0){temp\_yz=temp\_yz+10; while(KEY2==0);}}} if(KEY3==0){ delay_ms(20);{ if(KEY3==0){temp\_yz=temp\_yz-10; while(KEY3==0);}}} if(KEY1){IN4=1; //控制LED灯} if(KEY4==0){sdflag++; if(sdflag>1){sdflag = 0;} while(KEY4==0);} if(key5){out1 = 0;} else{out1 = 1;} if(key6){out2 = 0;} else{out2 =1;} if(temp_value<0)//负温度{temp\_value=-temp\_value;}else if(temp\_value>0&&temp\_value<100){ sprintf(temp\_buf,"Temp:%2.1f C %d",temp\_value,temp\_yz); lcd1602\_show\_string(0,0,temp\_buf); if(KEY1==0){ if(temp\_value<temp\_yz&&Lval>10){flag=0;IN4=0;}else if(Lval<10||temp\_value>=temp\_yz){IN4=1;} if(temp\_value==temp\_yz && Lval==80){ if(flag==0){beep=0;IN4=1; delay_ms(2000);beep=1;flag=1;}}}} if(readADCFlag == 1) //定时读取adc{midval=ReadADC(3); //转换的结果,在下次,才能读出Lv=(float)midval/255.0*5.0; Lval = Lv*20; delay_ms(10); //延时有助于稳定sprintf(buff,"SW:%3.2fCM %f",Lval,u);//打印电压电流值lcd1602\_show\_string(0,1,buff);//显示if(Lval<10) //液位小于10{one=0; IN1=IN3=0; //打开进水阀和通气阀} else if(Lval>=80){one = 1;} if(one==1){ if(sdflag == 0){IN1=1;IN2=0;IN3=0;} if(sdflag == 1){IN1=0;IN2=0;IN3=0;}} else if(one == 0){ if(KEY4==1)IN2=1;}readADCFlag = 0 ;} delay_ms(1); }
}void Init_Timer0(void){TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 TH0=(65536-20000)/256; //重新赋值 20msTL0=(65536-20000)%256;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}void Timer0_isr(void) interrupt 1
{TH0=(65536-20000)/256; //重新赋值 20msTL0=(65536-20000)%256;time\_20ms++; if(time\_20ms % 20 == 0) //定时读取adc采集{readADCFlag = 1;} if(time_20ms % 40 == 0) //定时读取温度{readTem = 1; //读取温度 标志}
}
四、实现现象
具体动态效果看B站演示视频:
B站演示视频
基于单片机的角度、水位、温度、辅助热源、电机仿真
全部资料(源程序、仿真文件、安装包、演示视频):
百度网盘下载资料https://pan.baidu.com/s/1CHGuhkCkXYeMc5NHkZt8jg?pwd=an2x