功能介绍:
0.本系统采用STC89C52作为单片机
1.系统实时显示当前的日期/时间,循环显示当前的温度/继电器控制状态
2.按键可设定温度,可控制继电器开关,系统设置了三路继电器,可以分别控制三种不同的家用设备
3.温度传感器采用的型号是常见的DS18B20,该传感器精度和测温范围都良好
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include "main.h"
/*******************变量定义*********************/
enum _MODE_DF_ dispMode;
bit modeFlag = AUTO; //模式标记
uchar setIndex = 0;
bit dispFlag = 0;
float temperature;
bit relay1Flag = 0;
bit relay2Flag = 0;
bit relay3Flag = 0;
char dis[16];
/********************************************************
函数名称:void mian()
函数作用:主函数
参数说明:
********************************************************/
void main()
{
modeFlag = MANUAL;
Timer0_Init(); //初始化定时器0
DS1302_Init(); //初始化DS1302
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_DispStr(4, 0, "Welcome!");
DelayS(1);
LCD_Clear(); //清屏
while (1) //死循环
{
if (dispFlag == 1)
{
dispFlag = 0;
Relay_Ctrl();
if (dispMode == NORMAL)
{
DispNormal();
}
}
KeyProcess();
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 9216) / 256; //重新赋值 10ms
TL0 = (65536 - 9216) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_Interrupt(void) interrupt 1
{
static unsigned int time10ms = 0;
TH0 = (65536 - 9216) / 256; //重新赋值 10ms
TL0 = (65536 - 9216) % 256;
time10ms++;
if (time10ms > 50)
{
time10ms = 0;
dispFlag = 1; //显示标志
}
}
void DispNormal(void)
{
static int tempBuf = 0;
static unsigned char cnt = 0;
DS1302_ReadTime();
switch (timeBufDec[7])
{
case 1: sprintf(dis, "%02d/%02d/%02d Sun. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 2: sprintf(dis, "%02d/%02d/%02d Mon. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 3: sprintf(dis, "%02d/%02d/%02d Tue. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 4: sprintf(dis, "%02d/%02d/%02d Wed. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 5: sprintf(dis, "%02d/%02d/%02d Thur. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 6: sprintf(dis, "%02d/%02d/%02d Fri. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
case 7: sprintf(dis, "%02d/%02d/%02d Sat. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
default: sprintf(dis, "%02d/%02d/%02d Sun. ", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]); break;
}
LCD_DispStr(0, 0, dis);
while(!DS18B20_Start());
DS18B20_GetTemp(&tempBuf);
temperature = (float)tempBuf * 0.0625;
sprintf(dis, "%02d:%02d:%02d ", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6]);
LCD_DispStr(0, 1, dis);
cnt++;
if (cnt < 5) //定时显示温度
{
sprintf(dis, "%5.1f", temperature);
LCD_DispStr(9, 1, dis);
LCD_DispOneChar(14, 1, 0xdf); //℃
LCD_DispOneChar(15, 1, 'C');
}
else if (cnt < 10) //定时显示继电器状态
{
if (relay1Flag == 1)
{
LCD_DispStr(9, 1, " 1o");
}
else
{
LCD_DispStr(9, 1, " 1c");
}
if (relay2Flag == 1)
{
LCD_DispStr(12, 1, "2o");
}
else
{
LCD_DispStr(12, 1, "2c");
}
if (relay3Flag == 1)
{
LCD_DispStr(14, 1, "3o");
}
else
{
LCD_DispStr(14, 1, "3c");
}
}
else
{
cnt = 0;
}
}
void Relay_Ctrl(void)
{
if (relay1Flag == 1)
{
RELAY_1 = ON;
}
else
{
RELAY_1 = OFF;
}
if (relay2Flag == 1)
{
RELAY_2 = ON;
}
else
{
RELAY_2 = OFF;
}
if (relay3Flag == 1)
{
RELAY_3 = ON;
}
else
{
RELAY_3 = OFF;
}
}
void DispSetRealTime(unsigned char setIndex)
{
sprintf(dis, "%02d/%02d/%02d", (int)timeBufDec[1], (int)timeBufDec[2], (int)timeBufDec[3]);
LCD_DispStr(0, 0, dis);
switch (timeBufDec[7])
{
case 1: LCD_DispStr(10, 0, " Sun."); break;
case 2: LCD_DispStr(10, 0, " Mon."); break;
case 3: LCD_DispStr(10, 0, " Tue."); break;
case 4: LCD_DispStr(10, 0, " Wed."); break;
case 5: LCD_DispStr(10, 0, "Thur."); break;
case 6: LCD_DispStr(10, 0, " Fri."); break;
case 7: LCD_DispStr(10, 0, " Sat."); break;
default: LCD_DispStr(10, 0, " Sun."); break;
}
sprintf(dis, " %02d:%02d:%02d ", (int)timeBufDec[4], (int)timeBufDec[5], (int)timeBufDec[6]);
LCD_DispStr(0, 1, dis);
switch (setIndex)
{
case 1: LCD_SetCursor(1, 0, 1); break;
case 2: LCD_SetCursor(4, 0, 1); break;
case 3: LCD_SetCursor(7, 0, 1); break;
case 4: LCD_SetCursor(14, 0, 1); break;
case 5: LCD_SetCursor(5, 1, 1); break;
case 6: LCD_SetCursor(8, 1, 1); break;
case 7: LCD_SetCursor(11, 1, 1); break;
default:break;
}
}