基于51单片机的积雪融化系统

        51单片机积雪融化系统使用51单片机作为系统主控,借助HX711检测积雪厚度,同时集成了LCD显示模块显示实时温度等,系统通过积雪厚度驱动改变加热片的功率进行一个融雪操作,同时集成了按键模块,可以手动调节加热/自动模式,加热强度等。

一、硬件设计

        51单片机积雪融化系统使用洞洞板进行焊接,电路简单,这边不多做阐述。

二、软件设计

 1、HX711

sbit HX711_DOUT = P2^0; 	//声明P2^1口接HX711数据线
sbit HX711_SCK = P2^1;		//声明P2^0口接HX711时钟线
//****************************************************
//延时函数
//****************************************************
void Delay__hx711_us(void)
{
	_nop_();
	_nop_();
}

//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void)	//增益128
{
	unsigned long count; 
	unsigned char i; 
  	HX711_DOUT=1; 
	Delay__hx711_us();
  	HX711_SCK=0; 
  	count=0; 
  	while(HX711_DOUT); 
  	for(i=0;i<24;i++)				
	{ 
	  	HX711_SCK=1; 
	  	count=count<<1; 
		HX711_SCK=0; 
	  	if(HX711_DOUT)
			count++; 
	} 
 	HX711_SCK=1; 
    count=count^0x800000;//第25个脉冲下降沿来时,转换数据
	Delay__hx711_us();
	HX711_SCK=0;  
	return(count);
}

//转化重量函数
long Get_Weight()
{
	HX711_Buffer = HX711_Read();    ///读取此时的传感器输出值
	Weight_Shiwu = HX711_Buffer;     ///将传感器的输出值储存
	Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
	Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);    //AD值转换为重量(g)
	return Weight_Shiwu; 	
}

2、DS18B20

#include <REGX52.H>
#include "OneWire.h"

#define DS18B20_SKIP_ROM        	0xcc
#define DS18B20_CONVERT_T      		0x44
#define DS18B20_READ_SCERATCHPAD 	0xbe

void DS18B20_ConvertT()
{
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_CONVERT_T);
}	

float DS18B20_ReadT()
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_READ_SCERATCHPAD);
	TLSB=OneWire_ReceiveByte();
	TMSB=OneWire_ReceiveByte();
	Temp=(TMSB<<8)|TLSB;
	T=Temp/16.0;
	return T;
}	
#include <REGX52.H>

sbit OneWire_DQ=P2^3;

unsigned char OneWire_Init()
{
	unsigned char i;
	unsigned char AckBit;
	OneWire_DQ=1;
	OneWire_DQ=0;
	i = 247;while (--i);	//delay 500us
	OneWire_DQ=1;
	i = 32;while (--i);		//delay 70us
	AckBit=OneWire_DQ;
	i = 247;while (--i);	//delay 500us
	return AckBit;
}

void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ=0;
	i=4;while(--i);		//delay 10us
	OneWire_DQ=Bit;
	i=24;while(--i);	//delay 50us
	OneWire_DQ=1;
}	

unsigned char OneWire_ReceiveBit()
{
	unsigned char i;
	unsigned char Bit;
	OneWire_DQ=0;
	i=2;while(--i);		//delay 5us
	OneWire_DQ=1;
	i=2;while(--i);		//dealy 5us
	Bit=OneWire_DQ;
	i=24;while(--i);	//delay 50us
	return Bit;
}	

void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i));
	}
}	

unsigned char OneWire_ReceiveByte()
{
	unsigned char i;
	unsigned char Byte=0x00;
	for(i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
	}
	return Byte;
}	
	




3、主程序

#include <REGX52.H>
#include "intrins.h" 
#include "LCD1602.H"
#include "delay.h"
#include "DS18B20.h" 
#include "KEY.h" 
#include "Timer0.h" 
 
//定义加热片引脚
sbit warm = P2^2;
 
unsigned char mode=0;
unsigned char runMode=0;
unsigned char Counter=0;
unsigned char Compare=0;
float tem=0;
unsigned char keyNum=0;
char warm_grade=0;
unsigned char flag=0;

//加热片加热阈值
char warm_th=35;

//HX711有关参数
long HX711_Buffer = 0;
long Weight_Maopi = 0, Weight_Shiwu = 0;
#define GapValue 440     ///该值需校准 每个传感器都有所不同

sbit HX711_DOUT = P2^0; 	//声明P2^1口接HX711数据线
sbit HX711_SCK = P2^1;		//声明P2^0口接HX711时钟线
//****************************************************
//延时函数
//****************************************************
void Delay__hx711_us(void)
{
	_nop_();
	_nop_();
}

//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void)	//增益128
{
	unsigned long count; 
	unsigned char i; 
  	HX711_DOUT=1; 
	Delay__hx711_us();
  	HX711_SCK=0; 
  	count=0; 
  	while(HX711_DOUT); 
  	for(i=0;i<24;i++)				
	{ 
	  	HX711_SCK=1; 
	  	count=count<<1; 
		HX711_SCK=0; 
	  	if(HX711_DOUT)
			count++; 
	} 
 	HX711_SCK=1; 
    count=count^0x800000;//第25个脉冲下降沿来时,转换数据
	Delay__hx711_us();
	HX711_SCK=0;  
	return(count);
}

//转化重量函数
long Get_Weight()
{
	HX711_Buffer = HX711_Read();    ///读取此时的传感器输出值
	Weight_Shiwu = HX711_Buffer;     ///将传感器的输出值储存
	Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
	Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);    //AD值转换为重量(g)
	return Weight_Shiwu; 	
}

//定义重量变量
unsigned long weight=0; 

void main()
{
	//LCD初始化
    LCD_Init();
	//初始化转换一遍温度
	DS18B20_ConvertT();
	tem = DS18B20_ReadT();
	//等待转化完成
	delay(1000);
	//初始获取一遍HX711的置
	Weight_Maopi = HX711_Read(); 
	//定时器初始化
	Timer0_Init();
	while(1)
    {       
		//获取按键值
		keyNum = KEY();
			
		//按键1按下,进行模式切换
		if(keyNum==1){
			mode++;
			mode%=2;
			LCD_Clear();
			warm_grade=0;
		}
		
		//按键4按下,手动自动模式切换
		if(keyNum == 4){
			runMode++;
			runMode%=2;
			warm_grade=0;			
		}
		
		//默认模式
		if(mode == 0){
			if(runMode==0){
				
				//判断是否达到加热条件
				if(tem < warm_th){
					
					//通过总量进行挡位调节
					if(weight < 200){
						warm_grade=0;
					}
					else if(weight >= 200 && weight <400){
						warm_grade=1;
					}
					else if(weight >= 400 && weight <600){
						warm_grade=2;
					}
					else if(weight >= 600){
						warm_grade=3;
					}					
				}

				//显示自动模式
				LCD_ShowString(2, 13, "Auto");	
			}
			else if(runMode==1){
				//显示手动模式
				LCD_ShowString(2, 13, "Hand");	
				//进行加热挡位的调节,减挡
				if(keyNum==2){
					warm_grade--;
					if(warm_grade<0)warm_grade=3;
				}
				//进行加热挡位的调节,加挡
				else if(keyNum==3){
					warm_grade++;
					warm_grade%=4;
				}
			}	
			
			
			
			//显示加热等级
			LCD_ShowNum(1, 15, warm_grade, 1);
			//显示温度
			LCD_ShowString(1,1,"Tempe:");
			LCD_ShowNum(1, 8, tem, 2);		
			//显示重量
			LCD_ShowNum(2, 1, weight, 4);
			LCD_ShowString(2,5,"g");			
		}

		else if(mode == 1){
			//显示加热阈值
			LCD_ShowString(1,1,"warm_th:");
			LCD_ShowNum(1, 12, warm_th, 2);
			//加热阈值减
			if(keyNum==2){
				warm_th--;
				if(warm_th<-50)warm_th=-50;
			}
			//加热阈值加
			else if(keyNum==3){
				warm_th++;
				if(warm_th>=50)warm_th=50;
			}
		}
		//通过加热阈值调整PWM占空比
		if(warm_grade==0)Compare=0;
		if(warm_grade==1)Compare=1;
		if(warm_grade==2)Compare=2;
		if(warm_grade==3)Compare=3;
    }
}               

//定时器中断函数
void Timer0_Routine() interrupt 1
{
	static unsigned char Tcnt=0;
	TL0 = 0x00;				//设置定时初始值
	TH0 = 0x94;				//设置定时初始值
	//生成PWM波,控制加热挡位
	Counter++;
	Counter%=4;
	if(Counter<Compare)
	{
		warm= 0;
	}
	else
	{
		warm = 1;
	}
	
	//转化温度
	DS18B20_ConvertT();
	tem = DS18B20_ReadT();	
	
	//定时获取重量,500ms
	if(++Tcnt >= 16){
		Tcnt=0;
		weight = Get_Weight();
	}

}

三、项目演示

1、默认状态

        默认状态下,LCD显示温度、重量、加热等级、自动模式

2、自动模式

        自动模式下,加热等级,随着积雪重量的增加而增加,如下:

3、手动模式

        手动模式下,可以通过按键修改加热等级

四、项目总结

        本次项目是一个通过积雪重量进行加热等级的控制,一般而言,重量越中,加热等级越大,同时系统可以手动控制。详情参考我的bilibili:

基于51单片机的积雪融化系统_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值