【电子设计课设】基于52单片机的温控风扇

一、概述

  •  主要实现的功能有能够随温度自动控制的风扇,风扇包含至少3个档位, 包含两种模式,按键控制模式和自动控制模式。
  •  监测到的当前温度值能实时显示,用户设置的风扇的自动控制温度最大值和最小值显示在LCD上。 

二、系统组成

        该设计主要使用的元器件有,STC89C52RC、DS18B20、AT24C02、AMS1117-5.0V,LCD1602等。

三、电路设计

1、仿真原理图

2、程序设计

1、main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "Timer0.h"
#include "LCD_STRAT.h"

sbit Motor=P1^0;

unsigned char Counter,KeyNum;
extern float TShow,T;
extern char TLow,THigh,Compare;
extern unsigned char Speed,MOC,FLAG;

void KEY_select();
void COS_select();

void main()
{            
	DS18B20_ConvertT();		//上电先转换一次温度,防止第一次读数据错误
	Delay(1000);			//等待转换完成
	THigh=AT24C02_ReadByte(0);	//读取温度阈值数据
	TLow=AT24C02_ReadByte(1);
	Speed=AT24C02_ReadByte(2);
	LCD_Init();
	Timer0_Init();
	LCD_ZERO();
	Delay(1000);
	LCD_Clear();
	while(1)
	{
		DS18B20_ConvertT();
		CTT();
		KeyNum=Key();
		KEY_select();
		MON_select();
		COS_select();
		MOON_select();

	}
}

void KEY_select()
{
	switch(KeyNum)
	{
		case 1:FLAG++;if(FLAG>4)FLAG=0;;LCD_Clear();break;
		case 2:FLAG--;if(FLAG<1)FLAG=4;LCD_Clear();break;
		case 3:MOC++;MOC%=6;break;
		default:break;
	}
}
void COS_select()
{
	switch(MOC)
	{
		case 1:if(KeyNum==4)THigh++;if(THigh>=125)THigh=124;ATWR_TH();break;
		case 2:if(KeyNum==4)THigh--;if(THigh<=TLow)THigh++;ATWR_TH();break;
		case 3:if(KeyNum==4)TLow++;if(TLow>=THigh)TLow--;ATWR_TL();break;
		case 4:if(KeyNum==4)TLow--;if(TLow<=-55) TLow=-54;ATWR_TL();break;
		case 5:if(KeyNum==4)Speed++;Speed%=5;Delay(5);AT24C02_WriteByte(2,Speed);Delay(5);break;
		default:break;
	}
}


void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1;
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	T0Count1++;
	if(T0Count1>=200)
	{
		T0Count1=0;  
		Key_Loop();		//20ms调用一次按键驱动函数
	}
	Counter++;        
	Counter%=100;
	if(Counter<Compare)   //PWM对比
	{
		Motor=1;
	}
	else
	{
		Motor=0;
	}		
}

2、软件IIC

#include <REGX52.H>

//引脚定义
sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void I2C_Start(void)
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2C_SDA=0;
	I2C_SCL=0;
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void I2C_Stop(void)
{
	I2C_SDA=0;
	I2C_SCL=1;
	I2C_SDA=1;
}

/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		I2C_SDA=Byte&(0x80>>i);
		I2C_SCL=1;
		I2C_SCL=0;
	}
}

/**
  * @brief  I2C接收一个字节
  * @param  无
  * @retval 接收到的一个字节数据
  */
unsigned char I2C_ReceiveByte(void)
{
	unsigned char i,Byte=0x00;
	I2C_SDA=1;
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA){Byte|=(0x80>>i);}
		I2C_SCL=0;
	}
	return Byte;
}

/**
  * @brief  I2C发送应答
  * @param  AckBit 应答位,0为应答,1为非应答
  * @retval 无
  */
void I2C_SendAck(unsigned char AckBit)
{
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
}

/**
  * @brief  I2C接收应答位
  * @param  无
  * @retval 接收到的应答位,0为应答,1为非应答
  */
unsigned char I2C_ReceiveAck(void)
{
	unsigned char AckBit;
	I2C_SDA=1;
	I2C_SCL=1;
	AckBit=I2C_SDA;
	I2C_SCL=0;
	return AckBit;
}

3、LCD1602小菜单

#include <REGX52.H>
#include "LCD1602.h"
#include "LCD_STRAT.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Buzzer.h"

sbit LED_hot=P2^0;
sbit LED_cold=P2^1;

float TShow,T;
char TLow,THigh;
unsigned char Speed,MOC,FLAG=1,Compare;


void LCD_ZERO()
{
	LCD_ShowString(1,3,"AWUFENGSHANG");
	LCD_ShowString(2,7,"V1.0");
}
void LCD_ONE()
{
	LCD_ShowString(1,1,"OnlineT:");
    LCD_ShowNum(1,10,TShow,3);		//显示温度整数部分
    LCD_ShowChar(1,13,'.');		//显示小数点
    LCD_ShowNum(1,14,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
	LCD_ShowString(2,1,"OnlineSpeed:");
	LCD_ShowNum(2,13,Speed,1);
	
}
void LCD_TWO()
{
	LCD_ShowString(1,1,"Waring TH:");
    LCD_ShowSignedNum(1,13,THigh,3);		
	LCD_ShowString(2,1,"Waring TL:");
	LCD_ShowSignedNum(2,13,TLow,3);
}
void LCD_THREE()
{
	LCD_ShowString(1,1,"FAN Speed:");
    LCD_ShowNum(1,11,Speed,1);		
	LCD_ShowString(2,1,"PRTTERN:");
	LCD_ShowNum(2,9,MOC,1);
}
void LCD_FOUR()
{
	LCD_ShowString(1,4,"END DOING");		
	LCD_ShowString(2,5,"GOODBYE");
}
void CTT()
{
		T=DS18B20_ReadT();		//读取温度
		if(T<0)				//如果温度小于0
		{
			TShow=-T;		//将温度变为正数
		}
		else				//如果温度大于等于0
		{
			TShow=T;
		}
}
void MON_select()
{
	switch(FLAG)
	{
		case 0:LCD_ZERO();break;
		case 1:LCD_ONE();break;
		case 2:LCD_TWO();break;
		case 3:LCD_THREE();break;
		case 4:LCD_FOUR();break;
		default:break;
	}
}
void TH()
{
	if(T>THigh){Compare=70;LED_hot=0;Buzzer_Time(100);}
}
void TL()
{
	if(T<TLow){Compare=10;LED_cold=0;Buzzer_Time(100);}
}
void MOON_select()
{
	switch(Speed)
	{
		case 0:Compare=0;break;
		case 1:Compare=50;break;
		case 2:Compare=70;break;
		case 3:Compare=100;break;
		case 4:Compare=0;TH();TL();break;
		default:break;
	}
}

四、小结

        温控风扇本身没有啥技术,而且所需要在LCD上显示的数据也无非是温度数据,温度阈值以及当前风速挡位,所以就想在LCD上做点小改变。刚好也自学了一下怎么做LCD菜单,所以在这本人课设做的电子小垃圾上实验,做出来的效果本人也觉得一般,但具有我想记录以便后续有新的想法继续改进。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值