基于AT89C51的智能开水机

前言
目前花了一个月时间自学,编写了开水机整套程序,以及仿真,初步完成。
在这里插入图片描述
功能:
检测温度,上传到数码管显示
检测水位,上传到数码管显示
温度上限下限显示和设置
水位上限下限显示和设置
抽水电机自动识别水位高低,并且启动,且进水指示灯亮
出水电机受按键控制,出水和停水按键,且出水指示灯亮
温度过低,接通加热管加热,加热指示灯亮,保温灯灭;过高,关闭继电器,停止加热,加热指示灯灭,保温灯亮;

后期思路:
出水电机转速控制——控制出水量,出水量显示在数码管,并且能够按键调控
串口通讯,为位上位机和下位机;(实物板子操作)
警示灯

主函数
数码管显示
数码管驱动:MAX7221
延迟函数
温度检测:DHT11和DS18B20,我用的是DS18B20
水位检测:ADC0808
仿真软件:protues7.8

在这里插入图片描述
下面放下功能代码

main.h头文件

#ifndef __MAIN_H__
#define __MAIN_H__
#include <reg51.h>
#include <intrins.h>




sbit LED_hot = P0^0;                    //加热LED指示灯
sbit out_water_led = P0^1;              //出水指示灯
sbit LED_stop_hot = P0^2;               //保温指示灯
sbit KEY_WATER = P0^3;                  //控制出水按键
sbit KEY_STOP_WATER = P0^4;             //控制停水按键
sbit in_water_led = P0^5;               //进水指示灯

sbit OUT_WATER_ENT_MOTOR= P3^1;               //出水电机控制
sbit OUT_IN_WATER= P3^2;                      //出水电机正转
sbit IN_WATER_ENT_MOTOR= P3^3;                //进水电机控制
sbit hot = P3^4;                              //加热控制
sbit KEY_HOT = P3^5;                          //按键加热开关
sbit KEY_STOP_HOT = P3^6;                     //按键停止加热开关
sbit KEY_MODEL = P3^7;                        //模式切换开关    


//sbit ADD_A = P3^5;
//sbit ADD_B = P3^6;
//sbit ADD_C = P3^7;
extern void Init_Timer0();

extern unsigned char Count;
extern unsigned int Sec;




#endif

main.c主函数

//E:表示水位值,P表示温度值
#include <reg51.h>
#include "main.h"
#include "digital.h"
#include "MAX7221.h"
#include "delay.h"
#include "DS18B20.h"
#include "ADC0808.h"
//#include "uart.h"

unsigned int Count;                  //温度转换
unsigned int Sec=0;                  //
unsigned long int c=0;
unsigned char model=0;               //模式
unsigned int HOT_L=30;               //温度下限
unsigned int HOT_H=90;               //温度上限
unsigned char WATER_L=50;            //水位上限
unsigned char WATER_H=150;           //水位下限
unsigned char Val;                   //模数转换出的电压值,也就是水位值

void send_byte(unsigned char dat)
{
	SBUF = dat;                        // 将数据送到发送缓冲寄存器SBUF,一位一位的发送
	while(!TI);                        // 等待发送完毕 (发送完毕TI硬件置1)
	TI = 0;                            // 将TI清零,表示可以发送下一字节数据。
}

void send_str(unsigned char *s)
{
	while(*s != '\0')                  // '\0':字符串结束标志
	{
		send_byte(*s);                   // 发送1个字节数据,1个字符占8位,1字节
		s++;                             // 指向下一个字符
	}
}
void main(void)
{
	//------------------------------------参数初始化-------------------------------------------//
	
	 WATER=0;                          //控制进水电机(正转)p3.0
	 hot=1;                            //加热管
	 LED_hot=1;                        //加热灯 
	 LED_stop_hot=0;                   //保温灯
	 IN_WATER_ENT_MOTOR=0;                       //进水电机使能   p3.3
	 OUT_IN_WATER=0;                      //控制出水电机(正转)
	 OUT_WATER_ENT_MOTOR=0;                   //出水电机(出水电机使能)
	 out_water_led=0;                  //出水灯
   in_water_led=0;	
	 KEY_HOT=1;                        //加热按键/加键
   KEY_STOP_HOT=1;                   //停止加热按键/减键
   KEY_MODEL=1;                      //模式切换1234种模式
	
  //------------------------------------函数初始化-------------------------------------------//
	
	 Get_temp();                       //温度值获取
	 Init_Timer0();                    //定时器初始化
   init_max7221();                   //max7221驱动初始化
   DS18B20_Init();                   //温度初始化
//--------------------------------误差清除------------------------------------------//	如果 出现问题则启动  程序运行过程中,仿真提示RAM COMMAND UNSUPPORTED,这是由于读数据太快,以至于DS18B20还没准备好。会有出现0的问题

while(!Val)                          //刚启动时电压会输出0,导致电机启动,目的清零
{
	    ST = 0;      		 
		  ST = 1;                        //复位
		  delay_ms(5);
		  ST = 0;                        //开始转换
		  while(EOC == 0);               //等待EOC变1,等待AD转换信号结束
		  OE = 1;                        //数据输出开启
	    Val=P1;	  
		  OE = 0;                        //数据输出关闭
}
	while(temp==850)Get_temp();        //清除第一次输出的850,取真实值显示

//------------------------------------循环---------------------------------------------//
	while(1)
	{
		 Get_temp();                      //获取温度值,传出一个参数temp
     Count=temp/10;                   //温度值换算
		 if(Count>99)                     //最大值99°
		 {
			 Count=99;
		 }
		 
		 //--------------------------出水电机按键控制--------------------------------//
		 if(KEY_WATER==0||OUT_WATER_ENT_MOTOR==1) 
		 {
			 OUT_WATER_ENT_MOTOR=1;         //出水
			 out_water_led=1;               //LED出水灯亮
		 }
		 if(KEY_STOP_WATER==0||OUT_WATER_ENT_MOTOR==0)
		 {
			 OUT_WATER_ENT_MOTOR=0;         //停止出水
			 out_water_led=0;               //LED出水灯灭
		 }
	  
		//--------------------------------温度值显示----------------------------------//
		if(model==0)
		{
		  digital_show(Count);           //数字显示	
			write_data(6,disp_buff_2[14]); //显示“P.”代表温度
			write_data(5,disp_buff_1[10]); //显示“-”
	
      if(Count<=HOT_L||KEY_HOT==0||hot==0)   //当小于最小温度下限值,则自动加热,或者当加热键按下时,加热。
			{
	   	hot=0;                         //加热
			LED_hot=0;	                   //加热灯亮
			LED_stop_hot=1;                //保温灯灭
			}
     else if(Count>=HOT_H||KEY_STOP_HOT==0||hot==1)  //当大于最大温度上限值,则自动停止加热,或者当停止键按下时,停止加热。
		 {
			hot=1;                         //停止加热
			LED_hot=1;                     //加热灯灭
      LED_stop_hot=0;			           //保温灯亮
		 }
//-------------------------------水位初始化------------------------------------//

		//-------------------------------ADC0808初始化--------------------------------- //
		  ST = 0;      		 
		  ST = 1;                        //复位
		 delay_ms(5);
		  ST = 0;                        //开始转换
		  while(EOC == 0);               //等待EOC变1,等待AD转换信号结束
		  OE = 1;                        //数据输出开启
	    Val=P1;	  
		  OE = 0;                        //数据输出关闭
		  DIGITAL_WATER_SHOW(Val);       //水位显示
		 write_data(1,disp_buff_2[11]); //显示“E.”代表水位
	//------------------------------进水电机转速控制-------------------------------------	//
		 if(Val == 0)                    //当电压等于0的时候
		{
		 	WATER = 0;
			DelayMS(0xff);                 //延迟255
		
		}
		if(Val == 0xff)                  //当电压等于最大值的时候
		{
		 	WATER = 1;
			DelayMS(0xff);                 //延迟255
			
		}
		WATER = 1;
		DelayMS(Val);                    //高电平占空比
		WATER = 0;
		DelayMS(0xff - Val);             //低电平占空比
		//-----------------------高低水位控制进水电机转速条件----------------------------------- //
			 if(Val>WATER_H)
			{
				IN_WATER_ENT_MOTOR=0;                     //电机停止
				in_water_led=0;
			}
			if(Val<WATER_L)
			{
        IN_WATER_ENT_MOTOR=1;                     //电机转动
				in_water_led=1;
			}
		 }
  
	//-------------------------温度上限调节----------------------------------//
	 if(model==1)                      //上限值设置
	 {
		 digital_show(HOT_H);            //数字显示
     write_data(6,disp_buff_2[12]);  //显示“H ”		
		 delay_10um(680);
		 write_data(6,disp_buff_2[15]);  //闪烁
		 write_data(5,disp_buff_1[10]);  //显示“-”
		 if(KEY_HOT==0)                  //上限值加
		 {
			 HOT_H++;
		 }
		  if(HOT_H<=HOT_L)               //上限值不能小于下下限值
		 {
			 HOT_H=HOT_L+1;
		 }
		 if(KEY_STOP_HOT==0)             //上限值减
		 {
			 HOT_H--;
		 }
		  if(HOT_H==99)                  //上限值不能超过98°
		 {
			 HOT_H=98;
		 }
	 }
	 
	//-------------------------温度下限调节----------------------------------//
	 if(model==2)                      //下限值设置
	 {
		 digital_show(HOT_L);            //数字显示
		 write_data(6,disp_buff_2[13]);  //显示“L” ,代表下限
		 delay_10um(680);
		 write_data(6,disp_buff_2[15]);  //闪烁
		 write_data(5,disp_buff_1[10]);  //显示“-”
		 if(KEY_HOT==0)                  //按键加
		 {
			 HOT_L++;
		 }
		  if(HOT_L>=HOT_H)               //下限值不能高于上限值
		 {
			 HOT_L=HOT_H-1;
		 }
		 
		 if(KEY_STOP_HOT==0)             //按键减
		 { 
			 HOT_L--;
		 }
		 if(HOT_L<1)                     //下限值最小不小于1
		 {
			 HOT_L=1;
		 }
		
	 }

	 //-----------------------水位上限调节----------------------------------// //水位值Val,范围0——255//
    if(model==3)                     
		{		
		 DIGITAL_WATER_SHOW(WATER_H);
		 write_data(1,disp_buff_2[12]);  //显示“H.”代表上限值
		 write_data(6,disp_buff_2[14]);  //显示“P.”代表温度
		 delay_10um(770);
		 write_data(1,disp_buff_2[15]);  //闪烁
			if(KEY_HOT==0)
			{
				WATER_H++;
			}
			if(KEY_STOP_HOT==0)
			{
	      WATER_H--;
			}
			if(WATER_H<=WATER_L)WATER_H=WATER_L+1;//上限必定大于下限
				
	   }
	//-----------------------水位下限调节----------------------------------//
		if(model==4)                    
		{
		 DIGITAL_WATER_SHOW(WATER_L);
		 write_data(1,disp_buff_2[13]);  //显示“L.”代表温度		
		 delay_10um(820);
		 write_data(1,disp_buff_2[15]);  //闪烁
			if(KEY_HOT==0)
			{
				WATER_L++;
			}
			if(KEY_STOP_HOT==0)
			{
	      WATER_L--;
			}
				if(WATER_L>=WATER_H)WATER_L=WATER_H-1;                        //下限必定小于上限
	   }
	//-----------------------------模式切换------------------------------------ //
		 
		if(KEY_MODEL==0)
		{
			model++;
 			while(!KEY_MODEL);
		}
		                                 //当模式等于3的时候清零
	  if(model==5)
		{
			model=0;
		}
		
	}
}
//
void Init_Timer0()
{
	TMOD = 0X21;                       // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
  
	TH0 = (65536 - 50000)/256;
	TL0 = (65536 - 50000)%256;

	TR0 = 1;				                   //开启定时器
	ET0 = 1;			                     //开启定时器中断
	SCON = 0x50;		                   // SCON: 方式 1, 8-bit, 允许接收数据              
	TH1 = 0xFD;                        ///
																		 // TH1: 253 初始值为0xFD  波特率:9600 晶振频率:11.0592MHz      //
																		 // 公式:                                                        //
																		 //              波特率:11.0592/((256-253)*384)*2^SMOD==9600 //
																		 //SMOD=0,波特率不加倍                                            //
																		 ///
	TL1 = 0x0;
	TR1 = 1;                           // TR1:  开启定时器1                         
	EA  = 1;                           //打开总中断
	ES  = 1;                           //打开串口中断
	

//	TMOD = 0X02;			               //T0, 工作模式1
//	TH0 = 0x14;                      //换算成十进制 0x00=256us,0xff=1us
//	TL0 = 0x00;
//	IE  = 0x82;
//	TR0 = 1;
}


void Timer0() interrupt 1//定时器0
{
	Clock = !Clock;
	
	TH0 = (65536 - 1000)/256;//1ms  定时  模式1非自动重装需要手动重装再次定时
	TL0 = (65536 - 1000)%256;
}


// 串口中断处理函数 (串口接收到数据,发送数据完毕都可以引起串口中断)
void uart_interrupt() interrupt 4 		//也叫串行中断服务程序
{
	unsigned char recv_data;// 用来存放接收到的数据

	if(RI) //接收数据(1字节)完毕,RI会被硬件置1
	{
		RI = 0;            		// 将 接收中断标志位 清零(让串口可以继续接收数据)
		recv_data = SBUF;           	//读取接收到的数据,并存放到data
		//--------------------------------------存放功能区--------------------------------------------------//

		switch(recv_data)
		{
			case '0':hot = 1;send_str("停止加热\n");break;
			case '1':hot = 0;send_str("加热\n");break;
			case '2':OUT_WATER_ENT_MOTOR=1;send_str("出水\n");break;
			case '3':OUT_WATER_ENT_MOTOR=0;send_str("停水\n");break;
			case '4':IN_WATER_ENT_MOTOR=1;send_str("抽水\n");break;
			case '5':IN_WATER_ENT_MOTOR=0;send_str("停止抽水\n");break;
			case '6':model++;send_str("模式切换\n");break;
			case '7':if(model==1){HOT_H++;}if(model==2){HOT_L++;}if(model==3){WATER_H++;}if(model==4){WATER_L++;}send_str("加\n");break;
			case '8':if(model==1){HOT_H--;}if(model==2){HOT_L--;}if(model==3){WATER_H--;}if(model==4){WATER_L--;}send_str("减\n");break;
			case '9':break;
		}
	   
	}
	if(TI)// 发送数据(1字节)完毕
	{
		TI = 0;// 将 发送中断标志位 清零(让串口可以继续发送数据)
	}
} 

 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值