一、概述
- 主要实现的功能有能够随温度自动控制的风扇,风扇包含至少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菜单,所以在这本人课设做的电子小垃圾上实验,做出来的效果本人也觉得一般,但具有我想记录以便后续有新的想法继续改进。
1939

被折叠的 条评论
为什么被折叠?



