本次设计的灵感来自于日常空调以及打印机
设计思路
- 现在的空调,风扇等温度控制产品都没有广泛的普及“智能家居”的概念,所以一个WiFi控制模块是必要的;
- 温度控制产品都缺少“自动控制温度”的一种功能,在我看来是不够合理的,所以程序之中设定自动温度调整
- 空调仅仅显示它所被设定的温度值,我觉得这个不是很合理,那种座式的空调,占据了大量的空间,只显示设定的温度值,这个温度数值也没什么实际意义,所以我设计显示环境温度以及当前时间
本次实物设计仅为一个想法的小demo,还有许多不够合理的地方
产品框架和实现思路
日期,时间,天气模块
使用lcd1602和ds1302进行实现
ds1302时钟芯片是将时分秒年月日以BCD码的形式存储在八个时钟寄存器之中的,数据先发低位再发高位,核心要点就是进行在写入和读出的时候都要注意去进行数制转换,这款芯片的功耗很低,51开发板上面没有备用电源,所以无法做到掉电后时钟不停,只需要外接一个备用电源即可。
lcd1602的端口不再是P0,我进行了相应的端口调整,从而在开发板上能够同时使用lcd1602以及数码管
温度模块
使用ds18b20和数码管实现
数码管摈弃了传统的使用74ls138译码器实现位选,转而去使用两片74hc595级联实现位选和段选的功能,仅用三个IO口就可以满足16个IO口的驱动,但也带来了一个问题,开发板上的74hc245芯片是固定接在了P0端口上的,没有了这块芯片,数码管的显示不是很稳定,外接一块74hc245即可解决
ds18b20温度传感器是以16位二进制数表示温度值,高五位代表正负,后十一位代表温度的数值,转换为十进制再乘以0.0625即为此时的温度值
“温度控制模块”(使用步进电机进行代替)
28BYJ48 步进电机和ULN2003驱动模块(这个模块没有跑通,还未找到问题所在)
WiFi控制模块
两套方式,适用于不同的场景,在教室的空调使用AP模式进行控制,直接连上设备的wifi即可调整设备的温度,Station模式就是平常的智能家居的模式,配置在同一个局域网下即可实现控制
引脚配置
各模块代码
lcd1602
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0//定义lcd1602数据端口,八位输入
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=0;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
ds1302
#include "intrins.h"
#include "public.h"
//引脚定义
sbit DS1302_RST=P3^5;//复位管脚
sbit DS1302_CLK=P3^6;//时钟管脚
sbit DS1302_IO=P3^4;//数据管脚
//DS1302写入和读取时分秒的地址命令
u8 gREAD_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
u8 gWRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//DS1302时钟初始化2023年12月26日星期二15点00分22秒
//存储顺序是秒分时日月周年,存储格式是用BCD码
u8 gDS1302_TIME[7] = {0x22, 0x00, 0x15, 0x26, 0x12, 0x02, 0x23};
//DS1302写单字节,addr地址/命令,dat数据
void ds1302_write_byte(u8 addr,u8 dat)
{
u8 i=0;
DS1302_RST=0;
DS1302_CLK=0;//CLK低电平
DS1302_RST=1;//RST由低到高变化
for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
{
DS1302_IO=addr&0x01;
addr>>=1;
DS1302_CLK=1;//CLK由低到高产生一个上升沿,从而写入数据
DS1302_CLK=0;
}
for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
{
DS1302_IO=dat&0x01;
dat>>=1;
DS1302_CLK=1;//CLK由低到高产生一个上升沿,从而写入数据
DS1302_CLK=0;
}
DS1302_RST=0;//RST拉低
}
//ds1302读单字节,addr地址/命令
u8 ds1302_read_byte(u8 addr)
{
u8 i=0;
u8 temp=0;
u8 value=0;
DS1302_RST=0;
DS1302_CLK=0;//CLK低电平
DS1302_RST=1;//RST由低到高变化
for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
{
DS1302_IO=addr&0x01;
addr>>=1;
DS1302_CLK=1;//CLK由低到高产生一个上升沿,从而写入数据
DS1302_CLK=0;
}
for(i=0;i<8;i++)//循环8次,每次读1位,先读低位再读高位
{
temp=DS1302_IO;
value=(temp<<7)|(value>>1);//先将value右移1位,然后temp左移7位,最后或运算
DS1302_CLK=1;//CLK由低到高产生一个上升沿,从而写入数据
DS1302_CLK=0;;
}
DS1302_CLK=1;// 使数据口有一个上升沿脉冲。
DS1302_IO = 0;
DS1302_IO = 1;
return value;
}
//DS1302初始化时间
void ds1302_init(void)
{
u8 i=0;
ds1302_write_byte(0x8E,0X00);//在写寄存器之前,关闭写寄存器保护
for(i=0;i<7;i++)
{
ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);
}
ds1302_write_byte(0x8E,0X80); //重新开启保护
}
//ds1302读取时间
void ds1302_read_time(void)
{
u8 i=0;
for(i=0;i<7;i++)
{
gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);
}
}
数码管
#include "smg.h"
#include <intrins.h>
sbit stcp=P1^0; //RC(RCLK)
sbit shcp=P1^1; //SC(SRCLK)
sbit DS=P1^2; //SE(SER)
// 数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void hc595_write(u8 show_number)
{
u8 i=0;
for(i=0;i<8;i++)
{
DS=show_number&(0x80>>i);
shcp=0;
shcp=1;
}
}
void hc595_latch(void)
{
stcp=0;
stcp=1;
}
//dat:要显示的数据
//pos:从左开始第几个位置开始显示,范围1-8
void smg_display(u8 dat[],u8 pos)
{
static u8 i=0;
static u8 pos_temp;
pos_temp=pos-1;
for(i=pos_temp;i<8;i++)
{
hc595_write((0xfe << i) | (0xfe >> (8 - i)));//传送位选数据
hc595_write(dat[i-pos_temp]);//传送段选数据
hc595_latch();//锁存
delay_10us(100);//延时一段时间,等待显示稳定
hc595_write(0x00);//消影
hc595_latch();//锁存
}
}
ds18b20
#include "public.h"
#include "intrins.h"
//引脚定义
sbit DS18B20_PORT=P3^7; //DS18B20数据口定义
//ds18b20复位功能
void ds18b20_reset(void)
{
DS18B20_PORT=0; //拉低DQ
delay_10us(75); //拉低750us
DS18B20_PORT=1; //拉高DQ
delay_10us(2); //拉高20US
}
//检测DS18B20是否存在,1表示不存在
u8 ds18b20_check(void)
{
u8 time_temp=0;
while(DS18B20_PORT&&time_temp<20) //等待DQ为低电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回1
else time_temp=0;
while((!DS18B20_PORT)&&time_temp<20) //等待DQ为高电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回1
return 0;
}
//从DS18B20读取一个位bit
u8 ds18b20_read_bit(void)
{
u8 dat=0;
DS18B20_PORT=0;
DS18B20_PORT=1; //该段时间不能过长,必须在15us内读取数据
if(DS18B20_PORT)dat=1; //如果总线上为1则数据dat为1,否则为0
else dat=0;
delay_10us(5);
return dat;
}
//从DS18B20读取一个字节,读八次bit即读一个字节
u8 ds18b20_read_byte(void)
{
u8 i=0;
u8 dat=0;
u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位
{
temp=ds18b20_read_bit();
dat=(temp<<7)|(dat>>1);
}
return dat;
}
//写一个字节到ds18b20
void ds18b20_write_byte(u8 dat)
{
u8 i=0;
u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位
{
temp=dat&0x01;//选择低位准备写入
dat>>=1;//将次高位移到低位
if(temp)
{
DS18B20_PORT=0;
_nop_();_nop_();
DS18B20_PORT=1;
delay_10us(6);
}
else
{
DS18B20_PORT=0;
delay_10us(6);
DS18B20_PORT=1;
_nop_();_nop_();
}
}
}
//开始温度转换
void ds18b20_start(void)
{
ds18b20_reset();//复位
ds18b20_check();//检查DS18B20
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0x44);//转换命令
}
//初始化ds18b20并且检测其是否
u8 ds18b20_init(void)
{
ds18b20_reset();
return ds18b20_check();
}
//读取温度数值
float ds18b20_read_temperture(void)
{
float temp;
u8 dath=0;
u8 datl=0;
u16 value=0;
ds18b20_start();//开始转换
ds18b20_reset();//复位
ds18b20_check();
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0xbe);//读存储器
datl=ds18b20_read_byte();//低字节
dath=ds18b20_read_byte();//高字节
value=(dath<<8)+datl;//合并为16位数据
if((value&0xf800)==0xf800)//判断符号位,负温度
{
value=(~value)+1; //数据取反再加1
temp=value*(-0.0625);//乘以精度
}
else //正温度
{
temp=value*0.0625;
}
return temp;
}
key
#include "public.h"
//定义独立按键控制脚
sbit k1=P2^4;
sbit k2=P2^3;
sbit k3=P2^2;
u8 cur_sta[4]={1,1,1,1};
u8 pre_sta[4]={1,1,1,1};
u8 key_scan()
{
u8 i;
u8 key_value=0;
//判断两个按键是否同时按下
for(i=0;i<3;i++)
{
if(pre_sta[i]!=cur_sta[i])
{
if(pre_sta[i])
{
// if(i==1 && cur_sta[0]==0) //当第二个按键按下时,第一个按键也正好处于按下状态
if(i==2 && cur_sta[1]==0)//当第三个按键按下的时候,第二个按键也处于按下的状态
key_value=4;
else
{
key_value=i+1;
}
}
pre_sta[i]=cur_sta[i];// 状态更新
}
}
return(key_value);
}
void cur_sta_update()
{
u8 i;
static u8 keybuff[3]={0xff,0xff,0xff};
//八次更新状态,要是按键对应的八位都为1则是按下
keybuff[0]=(keybuff[0]<<1)|k1;
keybuff[1]=(keybuff[1]<<1)|k2;
keybuff[2]=(keybuff[2]<<1)|k3;
//遍历三个按键
for(i=0;i<3;i++)
{
if(keybuff[i]==0xff)
cur_sta[i]=1;
else if(keybuff[i]==0x00)
cur_sta[i]=0;
}
}
stepmotor
#include <REG52.H>
#include "public.h"
//对步进电机引脚的定义
sbit IN1_D=P1^4;
sbit IN1_C=P1^5;
sbit IN1_B=P1^6;
sbit IN1_A=P1^7;
//步进电机旋转配置
void stepmotor(u8 step,u8 dir)//步数和方向设置函数
{
u8 temp=step;
if(dir==0) temp=7-step;
switch(temp)
{
case 0: IN1_A=1;IN1_B=1;IN1_C=1;IN1_D=0;break;
case 1: IN1_A=1;IN1_B=1;IN1_C=0;IN1_D=0;break;
case 2: IN1_A=1;IN1_B=1;IN1_C=0;IN1_D=1;break;
case 3: IN1_A=1;IN1_B=0;IN1_C=0;IN1_D=1;break;
case 4: IN1_A=1;IN1_B=0;IN1_C=1;IN1_D=1;break;
case 5: IN1_A=0;IN1_B=0;IN1_C=1;IN1_D=1;break;
case 6: IN1_A=0;IN1_B=1;IN1_C=1;IN1_D=1;break;
case 7: IN1_A=0;IN1_B=1;IN1_C=1;IN1_D=0;break;
}
}
uart
#include "uart.h"
#define RELOAD_COUNT 0xFA //宏定义波特率发生器的载入值 9600
//配合外部晶振频率11.0592M使用可以更加精确的进行串口通信
void UART_Init(void)
{
SCON|=0X50; //设置为工作方式1
TMOD|=0X20; //设置计数器工作方式2
PCON=0X80; //波特率加倍
TH1=RELOAD_COUNT; //计数器初始值设置
TL1=TH1;
ES=0; //关闭接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void UART_SendData(u8 dat)
{
ES=0; //关闭串口中断
TI=0; //清发送完毕中断请求标志位
SBUF=dat; //发送
while(TI==0); //等待发送完毕
TI=0; //清发送完毕中断请求标志位
ES=1; //允许串口中断
}
void UART_SendString(u8 *pbuf)
{
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendData(*pbuf);
delay_10us(5);
pbuf++;
}
}
u8 UART_RX_BUF[UART_REC_LEN];//接收缓冲,最大UART_REC_LEN个字节.
u16 UART_RX_STA=0;//接收状态标记
//串口中断模板
//void UART_IRQn() interrupt 4
//{
// u8 r;
// static u8 i=0;
//
// if(RI)
// {
// RI=0;
// UART_RX_BUF[i]=SBUF;//读取接收到的数据
// if(UART_RX_BUF[0]=='+')i++;
// else i=0;
// if(i==10)
// {
// i=0;
// }
// }
//}
WiFi control(main)
#include "wifi_control.h"
#include "ds18b20.h"
#include "uart.h"
#include "smg.h"
#include "lcd1602.h"
#include "ds1302.h"
#include "timer0.h"
//#include "key.h"
//#include "beep.h"
//#include "stepmotor.h"
//定义LED1管脚
sbit LED1=P2^0;//黄灯
sbit LED2=P2^1;//红灯
//定义WIFI控制命令
#define LED1_ON_CMD '1'
#define LED1_OFF_CMD '2'
//#define SPEEDMAX 1//设定步进旋转速度最大值
//#define SPEEDMIN 5//设置步进旋转速度最小值
//u8 key=0;
extern unsigned char gDS1302_TIME[7];
//ESP8266 WIFI发送AT指令
//pbuf:AT指令,字符串格式,如:"AT"
void ESP8266_SendCmd(u8 *pbuf)
{
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendData(*pbuf);
delay_10us(5);
pbuf++;
}
delay_10us(5);
UART_SendData('\r');//回车
delay_10us(5);
//WiFi模块发送AT指令需要发送一个换行结束符
UART_SendData('\n');//换行
delay_ms(1000);
}
//ESP8266 WIFI发送数据到APP
//pbuf:数据
void ESP8266_SendData(u8 *pbuf)
{
ESP8266_SendCmd("AT+CIPSEND=0,7");//id0号,数据长度为128(最大为2048)
while(*pbuf!='\0') //遇到空格跳出循环
{
UART_SendData(*pbuf);
delay_10us(5);
pbuf++;
}
//WiFi模块发送AT指令需要发送一个换行结束符
UART_SendData('\n');//换行
}
//ESP8266-WIFI模块工作模式初始化
void ESP8266_ModeInit(void)//station模式连接
{
ESP8266_SendCmd("AT+CWMODE=1");//设置路由器模式 1 station模式 2 AP点 路由器模式 3 station+AP混合模式
ESP8266_SendCmd("AT+CWJAP=\"lingqii\",\"77777777\""); //设置连接WIFI名及密码
ESP8266_SendCmd("AT+RST");//重新启动wifi模块
delay_ms(2000);
ESP8266_SendCmd("AT+CIPMUX=1"); //开启多路连接模式,允许多个各客户端接入
ESP8266_SendCmd("AT+CIPSERVER=1,5000");
//启动TCP/IP 端口为8080 实现基于网络控制
ESP8266_SendCmd("AT+CIPSTO=0");
}
//ESP8266-WIFI模块工作模式初始化
//void ESP8266_ModeInit(void)//AP模式连接
//{
// ESP8266_SendCmd("AT+CWMODE=2");//设置路由器模式 1 staTIon模式 2 AP点 路由器模式 3 station+AP混合模式
// ESP8266_SendCmd("AT+CWSAP=\"PRECHIN\",\"prechin168\",11,0"); //设置WIFI热点名及密码
// ESP8266_SendCmd("AT+CIPAP=\"192.168.4.1\"");
ESP8266_SendCmd("AT+RST");//重新启动wifi模块
delay_ms(2000);
// ESP8266_SendCmd("AT+CIPMUX=1"); //开启多连接模式,允许多个各客户端接入
// ESP8266_SendCmd("AT+CIPSERVER=1,8080"); //启动TCP/IP 端口为8080 实现基于网络控制
//}
//WIFI控制初始化
void wifi_control_init(void)
{
UART_Init();
ds18b20_init();//初始化DS18B20
ESP8266_ModeInit();
ES=1;//允许串口中断
}
//WIFI控制(主函数)
void wifi_control(void)
{
u16 i=0;
u16 temp_value;
u8 temp_buf[5];
u8 wifi_send_buf[7];
u8 time_buf[7];
u8 j;
// u8 dir=0;
// u8 step=0;
// u8 speed=SPEEDMAX;
// bit stepmove=0;//步进电机旋转标志位,0为停止,1为旋转
while(1)
{
// key=key_scan();
//
// if(key==1)//按键一按下令步进电机旋转或停止
// {
// stepmove=!stepmove;
// beep_alarm(100,7);
// }
// if(stepmove==1) //判断是否要让步进电机旋转
// {
// stepmotor(step++,dir);
// if(step==8) step=0;
// delay_ms(speed);
// beep_alarm(100,7);
// }
// if(key==4)//同时按下二三键令步进电机反转
// {
// dir=!dir;
// beep_alarm(100,7);
// }
//
// //步进电机速度控制
// else if (key==2)//按下按键二令步进电机加速
// {
// if(speed>SPEEDMAX) speed-=1;
// beep_alarm(100,7);
// }
// else if (key==3)//按下按键三令步进电机减速
// {
// if(speed<SPEEDMIN) speed+=1;
// beep_alarm(100,7);
// }delay_ms(SPEEDMAX);//通过每一步的延时来调节步进电机的速度
i++;
if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间60us
temp_value=ds18b20_read_temperture()*10;//保留温度值小数后一位
// //读出来的是乘以十的温度值,故做此判断
// if(temp_value>220)
// {
// LED2=0;//温度超过阈值,亮红灯,电机正转
stepmove=1;
// }
// else LED2=1;
// if(temp_value<190)
// {
// LED1=0;//温度低于阈值,亮黄灯,电机反转
dir=~dir;
// }
// else LED1=1;
if(temp_value<0)//如果温度是零下
{
temp_value=-temp_value;//数值取反
temp_buf[0]=0x40;//显示负号
wifi_send_buf[0]='-';
}
else
{
temp_buf[0]=0x00;//不显示
wifi_send_buf[0]='+';
}
temp_buf[1]=gsmg_code[temp_value/1000];//百位
temp_buf[2]=gsmg_code[temp_value%1000/100];//十位
temp_buf[3]=gsmg_code[temp_value%1000%100/10]|0x80;//个位+小数点
temp_buf[4]=gsmg_code[temp_value%1000%100%10];//小数点后一位
smg_display(temp_buf,4);
if(i%100==0)//间隔一定时间发送
{
wifi_send_buf[1]=temp_value/1000+0x30;
wifi_send_buf[2]=temp_value%1000/100+0x30;
wifi_send_buf[3]=temp_value%1000%100/10+0x30;
wifi_send_buf[4]='.';
wifi_send_buf[5]=temp_value%1000%100%10+0x30;
wifi_send_buf[6]='\0';
ESP8266_SendData(wifi_send_buf);//通过串口发送温度数据到APP
}
for (j = 0 ; j< 7 ; j++)
{
time_buf[j]=(gDS1302_TIME[j]/16)*10+gDS1302_TIME[j]%16;//将数组中的bcd形式的值转换成10进制并保存在其他数组中
}
//显示日期,周几,24时制时间,天气
LCD_ShowNum(1,1,20,2);
LCD_ShowNum(1,3,time_buf[6],2);
LCD_ShowChar(1,5,'-');
LCD_ShowNum(1,6,time_buf[4],2);
LCD_ShowChar(1,8,'-');
LCD_ShowNum(1,9,time_buf[3],2);
LCD_ShowString(1,12,"Day");
LCD_ShowNum(1,15,time_buf[5],1);
LCD_ShowNum(2,1,time_buf[2],2);
LCD_ShowChar(2,3,':');
LCD_ShowNum(2,4,time_buf[1],2);
LCD_ShowChar(2,6,':');
LCD_ShowNum(2,7,time_buf[0],2);
LCD_ShowString(2,12,"Sunny");
}
}
//串口中断服务函数
//接收手机APP发送的信号后控制51
void UART_IRQn() interrupt 4
{
static u8 i=0;
if(RI)
{
RI=0;//恢复为0,停止中断
UART_RX_BUF[i]=SBUF;//读取接收到的数据
if(UART_RX_BUF[0]=='+')i++;
else i=0;
if(i==10)
{
i=0;
//WIFI控制
if(UART_RX_BUF[9]==LED1_ON_CMD)
LED1=0;
else if(UART_RX_BUF[9]==LED1_OFF_CMD)
LED1=1;
// else if(UART_RX_BUF[9]==3)
// key=1;
// else if(UART_RX_BUF[9]==4)
// key=2;
// else if(UART_RX_BUF[9]==5)
// key=3;
}
}
}
void Timer1_Routine() interrupt 1
{
static unsigned int T0Count;//配置了静态变量,保证值不丢
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
T0Count++; //计数器,每次加1微妙
if(T0Count>=1000)
{
T0Count=0;
ds1302_read_time();
}
}
//void Timer2_Routine() interrupt 3
//{
// TH0=63536>>8;
// TL0=63536;
// cur_sta_update();
//}
后言
本次作业也有许多不足的地方
- 没能实现用wifi模块实时获取天气信息,json解析数据没整明白
- 步进电机模块和按键模块都没能正常运行
- 代码结构以及变量大小控制都不是很精细