#include "stm32f10x.h"
#include "beep.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <stdlib.h>
#include "exti.h"
#include "timer.h"
#include "rtc.h"
#include "wdg.h"
#include "oled.h"
#include "fontdata.h"
#include "adc.h"
#include "FunctionConfig.h"
#include "dht11.h"
#include "HumanDetection.h"
#include "esp8266.h"
/*
函数功能: 绘制时钟表盘框架
*/
void DrawTimeFrame(void)
{
u8 i;
OLED_Circle(32,32,31);//画外圆
OLED_Circle(32,32,1); //画中心圆
//画刻度
for(i=0;i<60;i++)
{
if(i%5==0)OLED_DrawAngleLine(32,32,6*i,31,3,1);
}
OLED_RefreshGRAM(); //刷新数据到OLED屏幕
}
/*
函数功能: 更新时间框架显示,在RTC中断里调用
*/
char TimeBuff[20];
void Update_FrameShow(void)
{
/*1. 绘制秒针、分针、时针*/
OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-6-90,27,0);//清除之前的秒针
OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-90,27,1); //画秒针
OLED_DrawAngleLine2(32,32,rtc_clock.min*6-6-90,24,0);
OLED_DrawAngleLine2(32,32,rtc_clock.min*6-90,24,1);
OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-6-90,21,0);
OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-90,21,1);
//绘制电子钟时间
sprintf(TimeBuff,"%d",rtc_clock.year);
OLED_ShowString(65,16*0,16,TimeBuff); //年份字符串
OLED_ShowChineseFont(66+32,16*0,16,4); //显示年
sprintf(TimeBuff,"%d/%d",rtc_clock.mon,rtc_clock.day);
OLED_ShowString(75,16*1,16,TimeBuff); //月
if(rtc_clock.sec==0)OLED_ShowString(65,16*2,16," "); //清除多余的数据
sprintf(TimeBuff,"%d:%d:%d",rtc_clock.hour,rtc_clock.min,rtc_clock.sec);
OLED_ShowString(65,16*2,16,TimeBuff); //秒
//显示星期
OLED_ShowChineseFont(70,16*3,16,5); //星
OLED_ShowChineseFont(70+16,16*3,16,6); //期
OLED_ShowChineseFont(70+32,16*3,16,rtc_clock.week+7); //具体的值
}
/*
函数功能: 温湿度显示
*/
void ShowTemperatureAndHumidity(u8 temp,u8 humi)
{
sprintf(TimeBuff,"T: %d",temp);
OLED_ShowString(40,16*1,16,TimeBuff);
sprintf(TimeBuff,"H: %d%%",humi);
OLED_ShowString(40,16*2,16,TimeBuff);
}
/*
函数功能: OLED所有显示页面信息初始化
*/
u8 ESP8266_Stat=0; //存放ESP8266状态 1 OK ,0 error
u8 ESP8266_WIFI_AP_SSID[10]; //存放WIFI的名称
#define STM32_96BIT_UID (0x1FFFF7E8) //STM32内部96位唯一芯片标识符寄存器地址
/*
函数功能: ESP8266 WIFI 显示页面
*/
char ESP8266_PwdShow[20];
char ESP8266_IP_PortAddr[30]; //存放ESP8266 IP地址与端口号地址
u8 Save_ESP8266_SendCmd[30]; //保存WIFI发送的命令
u8 Save_ESP8266_SendData[50]; //保存WIFI发送的数据
void ESP8266_ShowPageTable(void)
{
if(ESP8266_Stat)OLED_ShowString(0,16*0,16,"WIFI STAT:ERROR");
else OLED_ShowString(0,16*0,16,"WIFI STAT:OK");
//显示字符串
//OLED_ShowString(0,2,(u8*)" "); //清除一行的显示
memset((u8*)ESP8266_PwdShow,0,20); //清空内存
sprintf((char*)ESP8266_PwdShow,"WIFI:%s",ESP8266_WIFI_AP_SSID);
ESP8266_PwdShow[15]='\0';
OLED_ShowString(0,16*1,16,ESP8266_PwdShow);
memset((u8*)ESP8266_PwdShow,0,20); //清空内存
sprintf((char*)ESP8266_PwdShow,"PWD:%s",wifiap_password);
OLED_ShowString(0,16*2,16,ESP8266_PwdShow);
OLED_ShowString(0,16*3,16,"192.168.4.1:8089");
}
void OledShowPageTableInit(void)
{
u8 data[100],i;
u32 stm32_uid=0;
u8 *uid;
/*1. ESP8266 WIFI相关信息初始化*/
OLED_ShowString(0,2,16," "); //清空一行的显示
OLED_ShowString(0,2,16,"WifiInit..."); //显示页面提示信息
/*1.1 设置WIFI AP模式 */
if(ESP8266_SendCmd("AT+CWMODE=2\r\n","OK",50))
{
ESP8266_Stat=1; //OK
}
else
{
ESP8266_Stat=0; //ERROR
}
/*1.2 重启模块 */
ESP8266_SendCmd("AT+RST\r\n","OK",20);
/*1.3 延时3S等待重启成功*/
DelayMs(1000);
DelayMs(1000);
DelayMs(1000);
//得到WIFI的名称
uid=(u8*)STM32_96BIT_UID; //转为指针为1个字节
for(i=0;i<96;i++)
{
stm32_uid+=*uid++; //计算校验和,得到WIFI数字编号
}
printf("stm32_uid=%d\r\n",stm32_uid);
sprintf((char*)data,"%d",stm32_uid);
strcpy((char*)ESP8266_WIFI_AP_SSID,"wbyq_");
strcat((char*)ESP8266_WIFI_AP_SSID,(char*)data);
printf("请用设备连接WIFI热点:%s,%s,%s\r\n",(u8*)ESP8266_WIFI_AP_SSID,(u8*)wifiap_encryption,(u8*)wifiap_password);
/*1.4 配置模块AP模式无线参数*/
memset(data,0,100); //清空数组
sprintf((char*)data,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",ESP8266_WIFI_AP_SSID,wifiap_password);
ESP8266_SendCmd(data,"OK",1000);
/*1.5 设置多连接模式:0单连接,1多连接(服务器模式必须开启)*/
ESP8266_SendCmd("AT+CIPMUX=1\r\n","OK",20);
/*1.6 开启Server模式(0,关闭;1,打开),端口号为portnum */
memset(data,0,100); //清空数组
sprintf((char*)data,"AT+CIPSERVER=1,%s\r\n",(u8*)portnum);
ESP8266_SendCmd(data,"OK",50);
/*1.7 获取当前模块的IP*/
ESP8266_GetWanip((u8*)ESP8266_IP_PortAddr);
strcat(ESP8266_IP_PortAddr,":");
strcat(ESP8266_IP_PortAddr,portnum);
printf("IP地址:%s\r\n",ESP8266_IP_PortAddr);
OLED_ShowString(0,2,16," "); //清空一行的显示
OLED_ShowString(0,2,16,"WifiInitOk"); //显示页面提示信息
}
/*
函数功能: 显示开关状态
*/
void Show_Switch(int state)
{
//清屏
OLED_Clear(0);
if(state)
{
sprintf(TimeBuff,"Socket:ON");
OLED_ShowString(20,16*2,16,TimeBuff);
}
else
{
sprintf(TimeBuff,"Socket:OFF");
OLED_ShowString(20,16*2,16,TimeBuff);
}
}
//int main1(void)
//{
// HumanDetection_Init(); //热释电模块初始化
// UsartInit(USART1,72,115200);//串口1的初始化
// LED_Init(); //初始化LED
// while(1)
// {
// //热释电状态 为真表示有人
// if(HumanState)
// {
// LED1=0; //开灯
// }
// else //为假
// {
// LED1=1; //关灯
// }
// printf("%d\n",HumanState);
// }
//}
int main(void)
{
u8 rlen;
char *p;
u8 temp; //温度
u8 humi; //湿度
u8 stat;
u8 key_val;
u32 TimeCnt=0;
u32 wifi_TimeCnt=0;
u16 temp_data; //温度数据
u8 page_cnt=0; //显示的页面
char *time;
u8 socket_state=0;
UsartInit(USART1,72,115200);//串口1的初始化
BEEP_Init(); //初始化蜂鸣器
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
printf("正在初始化OLED...\r\n");
OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示
//OLED_Init(0xc0,0xa0); //OLED显示屏初始化--翻转显示
OLED_Clear(0x00); //清屏
UsartInit(USART3,36,115200); //WIFI的波特率为115200
Timer2Init(72,10000); //10ms中断一次,辅助串口3接收数据--WIFI数据
printf("正在初始化ESP8266..\r\n");
//ESP8266初始化
OledShowPageTableInit();
//清屏
OLED_Clear(0);
printf("正在初始化RTC...\r\n");
RTC_Init(); //RTC初始化
DrawTimeFrame(); //画时钟框架
USART3_RX_STA=0; //清空串口的接收标志位
USART3_RX_CNT=0; //清空计数器
printf("初始化DHT11...\r\n");
DHT11_Init(); //初始化DHT11
printf("热释电模块初始化...\r\n");
HumanDetection_Init(); //热释电模块初始化
//OLED_Clear(0);
printf("开始进入while(1)\r\n");
while(1)
{
key_val=KEY_GetValue();
if(key_val)
{
page_cnt++;
printf("page_cnt:%d\r\n",page_cnt);
//清屏
OLED_Clear(0);
//时钟页面
if(page_cnt==0)
{
DrawTimeFrame(); //画时钟框架
RTC->CRH|=1<<0; //开启秒中断
}
//温湿度页面
else if(page_cnt==1)
{
RTC->CRH&=~(1<<0); //关闭秒中断
//温湿度
ShowTemperatureAndHumidity(temp,humi);
}
//ESP8266显示
else if(page_cnt==2)
{
ESP8266_ShowPageTable();
}
else if(page_cnt==3)
{
Show_Switch(socket_state);
}
else
{
DrawTimeFrame(); //画时钟框架
RTC->CRH|=1<<0; //开启秒中断
page_cnt=0;
}
}
//时间记录
DelayMs(10);
TimeCnt++;
wifi_TimeCnt++;
if(TimeCnt>=100) //1000毫秒一次
{
TimeCnt=0;
//读取温湿度数据
DHT11_Read_Data(&temp,&humi);
//湿度大于90就关闭开关
if(humi>90)
{
socket_state=0;
if(page_cnt==3)
{
Show_Switch(socket_state);
}
}
//温湿度页面
if(page_cnt==1)
{
//温湿度
ShowTemperatureAndHumidity(temp,humi);
}
}
if(wifi_TimeCnt>=300) //3000毫秒一次
{
wifi_TimeCnt=0;
//温湿度1秒上传一次
sprintf((char*)Save_ESP8266_SendData,"#%d,%d",temp,humi); //拼接数据
sprintf((char*)Save_ESP8266_SendCmd,"AT+CIPSEND=0,%d\r\n",strlen((char*)Save_ESP8266_SendData));
ESP8266_SendCmd(Save_ESP8266_SendCmd,(u8*)"OK",200); //WIFI设置发送数据长度
ESP8266_SendData(Save_ESP8266_SendData,(u8*)"OK",100); //WIFI发送数据
}
//热释电状态 为真表示有人
if(HumanState)
{
LED1=0; //开灯
}
else //为假
{
LED1=1; //关灯
}
/*轮询扫描数据*/
if(USART3_RX_STA) //WIFI 接收到一次数据了
{
rlen=USART3_RX_CNT; //得到本次接收到的数据长度
USART3_RX_BUF[rlen]='\0'; //添加结束符
// printf("接收的数据: %s\r\n",USART3_RX_BUF); //发送到串口
{
/*判断是否收到客户端发来的数据 */
p=strstr((char*)USART3_RX_BUF,"+IPD");
if(p!=NULL) //正常数据格式: +IPD,0,7:LED1_ON +IPD,0表示第0个客户端 7:LED1_ON表示数据长度与数据
{
/*解析上位机发来的数据*/
p=strstr((char*)USART3_RX_BUF,":");
if(p!=NULL)
{
p+=1; //向后偏移1个字节
if(*p=='*') //设置RTC时间
{
p+=1; //向后偏移,指向正确的时间
time=p;
rtc_clock.year=(time[0]-48)*1000+(time[1]-48)*100+(time[2]-48)*10+(time[3]-48)*1;
rtc_clock.mon=(time[4]-48)*10+(time[5]-48)*1;
rtc_clock.day=(time[6]-48)*10+(time[7]-48)*1;
rtc_clock.hour=(time[8]-48)*10+(time[9]-48)*1;
rtc_clock.min=(time[10]-48)*10+(time[11]-48)*1;
rtc_clock.sec=(time[12]-48)*10+(time[13]-48)*1;
RTC_SetTime(rtc_clock.year,rtc_clock.mon,rtc_clock.day,rtc_clock.hour,rtc_clock.min,rtc_clock.sec);
if(page_cnt==0)
{
OLED_Clear(0); //OLED清屏
DrawTimeFrame();//画时钟框架
}
}
else if(strcmp(p,"LED1_ON")==0)
{
socket_state=1;
}
else if(strcmp(p,"LED1_OFF")==0)
{
socket_state=0;
}
if(page_cnt==3)
{
Show_Switch(socket_state);
}
}
}
}
USART3_RX_STA=0;
USART3_RX_CNT=0;
}
}
}