自学内容网 自学内容网

基于单片机的角度、水位、温度、辅助热源、电机仿真

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于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();//初始化DS18B20
Init_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;  //重新赋值 20ms
TL0=(65536-20000)%256;
EA=1;            //总中断打开
ET0=1;           //定时器中断打开
TR0=1;           //定时器开关打开
}

void Timer0_isr(void) interrupt 1 
{
TH0=(65536-20000)/256;  //重新赋值 20ms
TL0=(65536-20000)%256;

time_20ms++;
if(time_20ms % 20 == 0)//定时读取adc采集
{
 readADCFlag = 1;
}
if(time_20ms % 40 == 0)//定时读取温度
{
 readTem = 1; //读取温度标志
}
}

四、实现现象

具体动态效果看B站演示视频:

基于单片机的角度、水位、温度、辅助热源、电机仿真

全部资料(源程序、仿真文件、安装包、演示视频):

百度网盘下载资料icon-default.png?t=O83Ahttps://pan.baidu.com/s/1CHGuhkCkXYeMc5NHkZt8jg?pwd=an2x


原文地址:https://blog.csdn.net/zs849644371/article/details/142549202

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!