通过HC05配置ESP01s将获取时间和天气显示到TFT1.3寸彩屏上
在文章最后我会给出百度网盘链接,尽管如此还是希望大家认真观看文章,并琢磨程序代码逻辑在我的基础上可以改出属于自己特点的工程!
对于ESP8266 AT指令不熟悉的可以观看我的上一篇文章 认识 ESP8266—ESP-01S (含AT指令)
登陆心知天气官网,注册
https://www.seniverse.com/
点击"天气实况",打开对应的API接口文档
查看天气实况的接口地址,以及返回的数据结果示例(自行保存后面需要用到)
指令关键字 指令作用 响应 AT 测试指令 OK AT+RST 重启模块指令 OK AT+GMR 查看版本信息 AT version,SDK version,company,date,OK ATE 开关回显功能ATE关闭回显,ATE开启回显 OK AT+RESTORE 恢复出厂设置 OK AT+UART 设置串口配置 OK AT+CWMODE=mode 设置WiFi应用模式 OK AT+CWMODE? 响应返回当前模块的模式 +CWMODE:mode;OK AT+CWLIF 查看已接入设备的IP 已连接所有设备的IP地址 AT+CIPMUX 启动多连接 OK AT+CWJAP 加入AP OK AT+CWQAP 退出与AP的连接 OK AT+CWSMARTSTART 启动智能连接 OK或者ERROR AT+CWSMARTSTOP 停止智能连接 OK或者ERROR
使用AT指令获取到天气情况,这里列出对应的AT指令
串口助手波特率设置位115200,其他设置默认即可
发送 “AT” :正常启动就会响应“OK”
AT
使用串口发送指令AT+CWMODE=1设置模块Wi_Fi应用模式为Station模式
AT+CWMODE=1
发送指令AT+RST使模块重启,重启后等待一段时间
AT+RST
发送指令AT+CWJAP=“ssid”,“pwd”,ssid就是你要连接WiFi的名字,pwd就是密码
AT+CWJAP="amh","12345678"
发送指令AT+CIPSTART=“TCP”,“api.seniverse.com”,80,和心知天气建立TCP连接
AT+CIPSTART="TCP","api.seniverse.com",80
发送指令“AT+CIPMODE=1”设置成功则返回OK
AT+CIPMODE=1
发送指令“AT+CIPSEND” 开始透传
AT+CIPSEND
发送“GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市拼音&language=zh-Hans&unit=c”向网址提出请求
GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市&language=zh-Hans&unit=c
这里的location可以改为自己的城市,我的是西安(XiAn)
私钥为心知天气中获取到的私钥
语言language用的是中文(zh-Hans),这部分可以自行到心知天气官网的文档查看
注意:设置zh-Hans可能会乱码,建议改成en(返回英文)
MCU | ESP8266 |
---|---|
3.3V | VCC |
GND | GND |
PB10 | RXD |
PB11 | TXD |
3.3V | IO |
3.3V | RST |
MCU | USB转TTL |
---|---|
5V | VCC |
GND | GND |
PA9 | RXD |
PA10 | TXD |
MCU | TFT1.3彩屏 |
---|---|
5V | VCC |
GND | GND |
PA5 | SCL |
PA7 | SDA |
PB0 | RES |
PB1 | DC |
A4 | BLK |
MCU | HC-05 |
---|---|
5V | VCC |
GND | GND |
PA2 | RXD |
PA3 | TXD |
这里只给了部分代码,在文章最后会给出百度网盘链接,尽管如此还是希望大家认真观看。
#ifndef __ESP8266_H
#define __ESP8266_H
#include "sys.h"
#include "stdio.h"
#include "oled.h"
#include
//子对象1结构体--Location
typedef struct
{
char id[32];
char name[32];
char country[32];
char path[64];
char timezone[32];
char timezone_offset[32];
}Location;
//子对象2结构体--Now
typedef struct
{
char text[32];
char code[32];
char temperature[32];
}Now;
typedef struct
{
Location location; //子对象1
Now now; //子对象2
char last_update[64]; //子对象3
}Results;
typedef struct //结构体。
{
vu16 year;
vu8 month;
vu8 date;
vu8 hour;
vu8 min;
vu8 sec;
}nt_calendar_obj;
//用户配置AT指令的函数
//检查WIFI模块是否在线
bool esp_wifi_on_line(char *at);
//设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式
bool esp_work_pattern(char *at);
//esp重启
bool esp_restart(char *at);
//esp设置连接模式
bool esp_Connection_mode(char *at);
//esp连接wifi
bool esp_link_WIFI(char *at);
//函数
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime);
u8* esp8266_send_data(u8 *cmd,u16 waittime);
u8* esp8266_check_cmd(u8 *str);
void esp8266_start_trans(void);
u8 esp8266_quit_trans(void);
u8 get_current_weather(void);
u8 cloes_weather(void);
u8 get_weather(void);
u8 esp8266_quit_trans(void);
int cJSON_WeatherParse(char *JSON, Results *results);
void atk_8266_get_wanip(u8* ipbuf);
u8 get_beijing_time(void);
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);
u8* atk_8266_check_cmd(u8 *str);
u8 Is_Leap_Year(u16 year);
#endif
#include "esp8266.h"
#include "string.h"
#include "usart.h"
#include "usart3.h"
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "stdlib.h"
#include "malloc.h"
#include "cJSON.h"
#include
#include "USART_LY.h"
#include "bsp_systick.h"
nt_calendar_obj nwt; //定义结构体变量
//const u8* wifista_ssid="59"; //路由器SSID号
//const u8* wifista_password="12345678"; //连接密码
#define WEATHER_PORTNUM "80" //天气连接端口号:80
#define WEATHER_SERVERIP "api.seniverse.com" //天气服务器IP
#define TIME_PORTNUM "80" //时间端口号
#define TIME_SERVERIP "www.beijing-time.org" //时间服务器IP
//月份数据表
u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
//平年的月份日期表
const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
u8 *p;
Results results[] = {{0}};
extern char USART2_RX_BUF[USART2_MAX_RECV_LEN];
extern vu16 USART2_RX_STA;
/*********************************************************************************
* Function Name : esp8266_start_trans,ESP8266初始化设置
* Parameter :
* Return Value :
* Function Explain : 连接wifi
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
void esp8266_start_trans(void)
{
int i=0;
while(esp_wifi_on_line(USART2_RX_BUF))
{
i++;
if(i==5)
{
LY_Printf("err");
printf("\r\nAT指令输入有误,重新输入\r\n");
USART2_RX_BUF[0]='\0';
i=0;
}
}
//设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式
i=0;
while(esp_work_pattern(USART2_RX_BUF))
{
i++;
if(i==5)
{
LY_Printf("err");
printf("\r\nAT指令输入有误,重新输入\r\n");
USART2_RX_BUF[0]='\0';
i=0;
}
}
//Wifi模块重启
i=0;
esp_restart(USART2_RX_BUF);
//设置连接到的WIFI网络名称/加密方式/密码,这几个参数需要根据您自己的路由器设置进行修改!!
//esp设置连接模式
i=0;
while(esp_Connection_mode(USART2_RX_BUF))
{
i++;
if(i==5)
{
LY_Printf("err");
printf("\r\nAT指令输入有误,重新输入\r\n");
USART2_RX_BUF[0]='\0';
i=0;
}
}
//连接目标路由器,并且获得IP
i=0;
while(esp_link_WIFI(USART2_RX_BUF))
{
i++;
printf("\r\n%d\r\n",i);
if(i==5)
{
LY_Printf("err");
printf("\r\nAT指令输入有误,重新输入\r\n");
USART2_RX_BUF[0]='\0';
i=0;
}
}
}
//检查WIFI模块是否在线
bool esp_wifi_on_line(char *at)
{
printf("检查WIFI模块是否在线\r\n");
while(USART2_RX_BUF[0]=='\0')
{
}
delay_ms(1000);
return esp8266_send_cmd(at,"OK",20); //检查WIFI模块是否在线
}
//设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式
bool esp_work_pattern(char *at)
{
printf("\r\n设置工作模式\r\n");
while(USART2_RX_BUF[0]=='\0')
{
}
delay_ms(1000);
return esp8266_send_cmd(at,"OK",50);;
}
//esp重启
bool esp_restart(char *at)
{
printf("\r\nesp重启\r\n");
while(USART2_RX_BUF[0]=='\0')
{
}
esp8266_send_cmd(at,"OK",20); //延时4S等待重启成功
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
USART2_RX_BUF[0]='\0';
//Wifi模块重启
LY_Printf("OK");
return 1;
}
//esp设置连接模式
bool esp_Connection_mode(char *at)
{
printf("\r\n设置连接模式\r\n");
while(USART2_RX_BUF[0]=='\0')
{
}
return esp8266_send_cmd(at,"OK",20); //0:单连接,1:多连接 ;
}
//esp连接wifi
bool esp_link_WIFI(char *at)
{
printf("\r\nesp连接wifi\r\n");
while(USART2_RX_BUF[0]=='\0')
{
}
return esp8266_send_cmd(at,"WIFI GOT IP",300); //连接目标路由器,并且获得IP;
delay_ms(1000);
}
/*********************************************************************************
* Function Name : esp8266_send_cmd,向ESP8266发送命令
* Parameter : cmd:发送的命令字符串;ack:期待的应答结果,如果为空,则表示不需要等待应答;waittime:等待时间(单位:10ms)
* Return Value : 返回值:0,发送成功(得到了期待的应答结果);1,发送失败
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
delay_ms(1000);
u3_printf("%s\r\n",cmd); //发送命令
printf("发送命令了-->%s\r\n",cmd);
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到期待的应答结果
{
u8 *a= esp8266_check_cmd(ack);
if(esp8266_check_cmd(ack))
{
printf("receive:%s\r\n",(u8*)ack);
LY_Printf(ack);
USART2_RX_BUF[0]='\0';
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
/*********************************************************************************
* Function Name : esp8266_check_cmd,ESP8266发送命令后,检测接收到的应答
* Parameter : str:期待的应答结果
* Return Value : 返回值:0,没有得到期待的应答结果;其他,期待应答结果的位置(str的位置)
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8* esp8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
/*********************************************************************************
* Function Name : esp8266_quit_trans,ATK-ESP8266退出透传模式
* Parameter :
* Return Value : 返回值:0,退出成功;1,退出失败
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8 esp8266_quit_trans(void)
{
while((USART3->SR&0X40)==0); //等待发送空
USART3->DR='+';
delay_ms(15); //大于串口组帧时间(10ms)
while((USART3->SR&0X40)==0); //等待发送空
USART3->DR='+';
delay_ms(15); //大于串口组帧时间(10ms)
while((USART3->SR&0X40)==0); //等待发送空
USART3->DR='+';
delay_ms(500); //等待500ms
printf("退出看透传模式\r\n");
return esp8266_send_cmd("AT","OK",20);//退出透传判断.
}
/*********************************************************************************
* Function Name : get_current_weather,获取一次实时天气
* Parameter :
* Return Value : 返回:0---获取成功,1---获取失败
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8 get_current_weather(void)
{
u8 res;
p=mymalloc(SRAMIN,40); //申请40字节内存
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",WEATHER_SERVERIP,WEATHER_PORTNUM); //配置目标TCP服务器
// printf("send:AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",WEATHER_SERVERIP,WEATHER_PORTNUM);
res = esp8266_send_cmd(p,"OK",200);//连接到目标TCP服务器
delay_ms(300);
printf("send:AT+CIPMODE=1\r\n");
esp8266_send_cmd("AT+CIPMODE=1","OK",100); //传输模式为:透传
USART3_RX_STA=0;
printf("send:AT+CIPSEND\r\n");
esp8266_send_cmd("AT+CIPSEND","OK",100); //开始透传
printf("start trans...\r\n");
u3_printf("GET https://api.seniverse.com/v3/weather/now.json?key=SBE-txu7v25szUfOf&location=XiAn&language=en&unit=c\n\n");
delay_ms(20);//延时20ms返回的是指令发送成功的状态
USART3_RX_STA=0; //清零串口3数据
delay_ms(1000);
if(USART3_RX_STA&0X8000) //此时再次接到一次数据,为天气的数据
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
}
printf("USART3_RX_BUF=%s\r\n",USART3_RX_BUF);
cJSON_WeatherParse(USART3_RX_BUF, results); //解析天气数据
//打印结构体内内容
printf("打印结构体内内容如下: \r\n");
printf("%s \r\n",results[0].now.text);
printf("%s \r\n",results[0].now.temperature);
esp8266_quit_trans();//退出透传
esp8266_send_cmd("AT+CIPCLOSE","OK",50); //关闭连接
myfree(SRAMIN,p);
return 0;
}
/*********************************************************************************
* Function Name : cJSON_WeatherParse,解析天气数据
* Parameter : JSON:天气数据包 results:保存解析后得到的有用的数据
* Return Value : 0:成功 其他:错误
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
int cJSON_WeatherParse(char *JSON, Results *results)
{
cJSON *json,*arrayItem,*object,*subobject,*item;
json = cJSON_Parse(JSON); //解析JSON数据包
if(json == NULL) //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效
{
printf("Error before: [%s] \r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置
return 1;
}
else
{
if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL) //匹配字符串"results",获取数组内容
{
int size = cJSON_GetArraySize(arrayItem); //获取数组中对象个数
printf("cJSON_GetArraySize: size=%d \r\n",size);
if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容
{
/* 匹配子对象1 */
if((subobject = cJSON_GetObjectItem(object,"location")) != NULL)
{
printf("---------------------------------subobject1-------------------------------\r\n");
if((item = cJSON_GetObjectItem(subobject,"id")) != NULL) //匹配子对象1成员"id"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.id,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //匹配子对象1成员"name"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.name,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)//匹配子对象1成员"country"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.country,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"path")) != NULL) //匹配子对象1成员"path"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.path,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)//匹配子对象1成员"timezone"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.timezone,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)//匹配子对象1成员"timezone_offset"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].location.timezone_offset,item->valuestring,strlen(item->valuestring));
}
}
/* 匹配子对象2 */
if((subobject = cJSON_GetObjectItem(object,"now")) != NULL)
{
printf("---------------------------------subobject2-------------------------------\r\n");
if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//匹配子对象2成员"text"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].now.text,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//匹配子对象2成员"code"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].now.code,item->valuestring,strlen(item->valuestring));
}
if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //匹配子对象2成员"temperature"
{
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring);
memcpy(results[0].now.temperature,item->valuestring,strlen(item->valuestring));
}
}
/* 匹配子对象3 */
if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL)
{
printf("---------------------------------subobject3-------------------------------\r\n");
printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",subobject->type,subobject->string,subobject->valuestring);
memcpy(results[0].last_update,item->valuestring,strlen(subobject->valuestring));
}
}
}
}
cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间
return 0;
}
/*********************************************************************************
* Function Name : get_beijing_time,获取时间
* Parameter :
* Return Value : 返回:0---获取成功,1---获取失败
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8 get_beijing_time(void)
{
u8 *p;
u8 res;
u8 *resp;
u8 *p_end;
u8 ipbuf[16]; //IP缓存
p=mymalloc(SRAMIN,40); //申请40字节内存
resp=mymalloc(SRAMIN,10);
p_end=mymalloc(SRAMIN,40);
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",TIME_SERVERIP,TIME_PORTNUM); //配置目标TCP服务器
printf("%s",p);
res = esp8266_send_cmd(p,"OK",200);//连接到目标TCP服务器
delay_ms(300);
esp8266_send_cmd("AT+CIPMODE=1","OK",100); //传输模式为:透传
esp8266_send_cmd("AT+CIPSEND","OK",100); //开始透传
printf("start trans...\r\n");
u3_printf("GET /time15.asp HTTP/1.1Host:www.beijing-time.org\n\n");
delay_ms(20);//延时20ms返回的是指令发送成功的状态
USART3_RX_STA=0; //清零串口3数据
delay_ms(1000);
if(USART3_RX_STA&0X8000) //此时再次接到一次数据,为天气的数据
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
}
printf("USART3_RX_BUF=%s\r\n",USART3_RX_BUF);
//USART3_RX_BUF 为时间信息
if(USART3_RX_STA & 0x8000)
{
resp="Date";
USART3_RX_BUF[USART3_RX_STA & 0x7ff] = 0;
printf("get_tim_srt:%s\r\n",USART3_RX_BUF);
if(strstr((char*)USART3_RX_BUF,(char*)resp))
{
resp="GMT";
p_end = (u8*)strstr((char*)USART3_RX_BUF,(char*)resp);
p = p_end - 9;
printf("get_net_str %s\r\n",p);
nwt.hour = ((*p - 0x30)*10 + (*(p+1) - 0x30) + 8) % 24; //GMT0-->GMT8
nwt.min = ((*(p+3) - 0x30)*10 + (*(p+4) - 0x30)) % 60;
nwt.sec = ((*(p+6) - 0x30)*10 + (*(p+7) - 0x30)) % 60;
nwt.year = ((*(p-5) - 0x30)*1000 + (*(p-4) - 0x30)*100+ (*(p-3) - 0x30)*10+ (*(p-2) - 0x30));
nwt.date = ((*(p-12) - 0x30)*10 + (*(p-11) - 0x30));
if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jan")) nwt.month=1;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Feb")) nwt.month=2;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Mar")) nwt.month=3;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Apr")) nwt.month=4;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "May")) nwt.month=5;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jun")) nwt.month=6;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Jul")) nwt.month=7;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Aug")) nwt.month=8;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Sep")) nwt.month=9;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Oct")) nwt.month=10;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Nov")) nwt.month=11;
else if ((u8*)strstr((char*)USART3_RX_BUF,(char*) "Dec")) nwt.month=12;
printf("nwt.year = %d\r\n",nwt.year);
printf("nwt.month = %d\r\n",nwt.month);
printf("nwt.date = %d\r\n",nwt.date); //获取data 28日
printf("nwt.hour = %d\r\n",nwt.hour);
printf("nwt.min = %d\r\n",nwt.min);
printf("nwt.sec = %d\r\n",nwt.sec);
USART3_RX_STA = 0;
printf("uddate:nettime!!!");
}
USART3_RX_STA = 0;
myfree(SRAMIN,resp);
myfree(SRAMIN,p_end);
}
printf("\r\n\r\n");
esp8266_quit_trans();//退出透传
esp8266_send_cmd("AT+CIPCLOSE","OK",50); //关闭连接
printf("获取数据成功");
myfree(SRAMIN,p);
return 0;
}
/*********************************************************************************
* Function Name : atk_8266_check_cmd,ATK-ESP8266发送命令后,检测接收到的应答
* Parameter : str:期待的应答结果
* Return Value : 返回值:0,没有得到期待的应答结果,其他,期待应答结果的位置(str的位置)
* Function Explain :
**********************************************************************************/
u8* atk_8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
/*********************************************************************************
* Function Name : atk_8266_send_cmd,向ATK-ESP8266发送命令
* Parameter : cmd:发送的命令字符串,ack:期待的应答结果,如果为空,则表示不需要等待应答,waittime:等待时间(单位:10ms)
* Return Value : 返回值:0,发送成功(得到了期待的应答结果),1,发送失败
* Function Explain :
**********************************************************************************/
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%s\r\n",cmd); //发送命令
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到期待的应答结果
{
if(atk_8266_check_cmd(ack))
{
printf("%s ack:%s\r\n",cmd,(u8*)ack);
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
/*********************************************************************************
* Function Name : Is_Leap_Year,判断是否闰年
* Parameter : year年份
* Return Value : 1,闰年,0,不是闰年
* Function Explain :
* Create Date : 2021/6/5 by zzh
**********************************************************************************/
u8 Is_Leap_Year(u16 year)
{
if(year%4==0) //必须能被4整除
{
if(year%100==0)
{
if(year%400==0)return 1;//如果以00结尾,还要能被400整除
else return 0;
}else return 1;
}else return 0;
}
#ifndef __USART_LY_H
#define __USART_LY_H
#include "stm32f10x.h" // Device header
#include
#define DEBUG_USART2 1
#if DEBUG_USART2
#define USART2_MAX_RECV_LEN 200 //最大接收缓存字节数
#define USART2_MAX_SEND_LEN 200 //最大发送缓存字节数
#define USART2_RX_EN 1 //0,不接收;1,接收.
// 串口2-USART2
#define DEBUG_USARTx USART2
#define DEBUG_USART_CLK RCC_APB1Periph_USART2
#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd
#define DEBUG_USART_BAUDRATE 9600
// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3
#define DEBUG_USART_IRQ USART2_IRQn
#define DEBUG_USART_IRQHandler USART2_IRQHandler
#endif
void USART2_HC05_Init(void);
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data);
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num);
void Usart_SendString(USART_TypeDef* pUSARTx, char *String);
void LY_Printf(char *format, ...);
#endif
#include "stm32f10x.h" // Device header
#include "USART_LY.h"
#include "timer.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "delay.h"
#include "usart.h"
#include "usart3.h"
#include "string.h"
#include "esp8266.h"
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
//串口接收缓存区
char USART2_RX_BUF[USART2_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
char USART2_TX_BUF[USART2_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节
//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART2_RX_STA=0;
void USART2_HC05_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//设置中断优先级
NVIC_InitTypeDef NVIC_InitStructure;
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
// 配置 8针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No ;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(DEBUG_USARTx, &USART_InitStructure);
// 串口中断优先级配置
NVIC_Configuration();
// 使能串口接收中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
TIM2_Int_Init(1000-1,7200-1); //10ms中断
USART2_RX_STA=0; //清零
TIM_Cmd(TIM2,DISABLE); //关闭定时器2
// 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
}
void USART2_IRQHandler()
{
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
USART2_RX_BUF[USART2_RX_STA] = USART_ReceiveData(USART2); //接收串口2数据到buff缓冲区
USART2_RX_STA++;
if(USART2_RX_BUF[USART2_RX_STA-1] == ';' || USART2_RX_STA == USART2_MAX_RECV_LEN) //如果接收到尾标识是换行符(或者等于最大接受数就清空重新接收)
{
USART2_RX_BUF[USART2_RX_STA-1]=0;//清除 标志位 ;
printf("这是蓝牙发给ESP的AT命令-->%s\r\n",USART2_RX_BUF); //这里我做打印数据处理
USART2_RX_STA=0;
}
}
}
void LY_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg);
va_end(arg);
Usart_SendString(DEBUG_USARTx,String);
}
/* 发送一个字节 */
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
USART_SendData(pUSARTx, data);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}
/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
uint8_t temp_h,temp_l;
temp_h = (data&0xff00) >> 8 ;
temp_l = data&0xff;
USART_SendData(pUSARTx, temp_h);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
USART_SendData(pUSARTx, temp_l);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}
/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
uint8_t i;
for( i=0; i<num; i++ )
{
Usart_SendByte(pUSARTx, array[i]);
}
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}
/* 发送字符串 */
void Usart_SendString(USART_TypeDef* pUSARTx, char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)
{
Usart_SendByte(pUSARTx,String[i]);
}
}
#ifndef __TFTOLED_H
#define __TFTOLED_H
#include "sys.h"
#include "stdlib.h"
#define TFT_W 240
#define TFT_H 240
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
//TFT模式设置
//0:4线串行模式
//1:并行8080模式
#define TFT_MODE 0
#define SIZE 16
#define XLevelL 0x00
#define XLevelH 0x10
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF
#define X_WIDTH 128
#define Y_WIDTH 64
//-----------------TFT端口定义----------------
#define TFT_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//CLK
#define TFT_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define TFT_SDIN_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DIN
#define TFT_SDIN_Set() GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define TFT_RST_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_0)//RES
#define TFT_RST_Set() GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define TFT_DC_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_1)//DC
#define TFT_DC_Set() GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define TFT_BLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//CS
#define TFT_BLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define TFT_CMD 0 //写命令
#define TFT_DATA 1 //写数据
extern u16 BACK_COLOR, POINT_COLOR; //背景色,画笔色
void TFT_Init(void);
void TFT_Clear(u16 Color);
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);
void TFT_WR_DATA8(char da); //发送数据-8位参数
void TFT_WR_DATA(int da);
void TFT_WR_REG(char da);
void TFT_DrawPoint(u16 x,u16 y);//画点
void TFT_DrawPoint_big(u16 x,u16 y);//画一个大点
u16 TFT_ReadPoint(u16 x,u16 y); //读点
void Draw_Circle(u16 x0,u16 y0,u8 r);
void TFT_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);
void TFT_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);
void TFT_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);
void TFT_ShowChar(u16 x,u16 y,u8 num,u8 mode);//显示一个字符
void TFT_ShowNum(u16 x,u16 y,u32 num,u8 len);//显示数字
void TFT_Show2Num(u16 x,u16 y,u16 num,u8 len);//显示2个数字
void TFT_ShowString(u16 x,u16 y,const u8 *p); //显示一个字符串,16字体
void showhanzi(unsigned int x,unsigned int y,unsigned char index);
//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
//GUI颜色
#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
//以上三色为PANEL的颜色
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
#endif
#include "stm32f10x.h" // Device header
#include "TFToled.h"
#include "stdlib.h"
#include "TFToledfont.h"
#include "delay.h"
u16 BACK_COLOR, POINT_COLOR; //背景色,画笔色
void TFT_Writ_Bus(char dat) //串行数据写入
{
u8 i;
for(i=0;i<8;i++)
{
TFT_SCLK_Clr();
if(dat&0x80)
TFT_SDIN_Set();
else
TFT_SDIN_Clr();
TFT_SCLK_Set();
dat<<=1;
}
}
void TFT_WR_DATA8(char da) //发送数据-8位参数
{
TFT_DC_Set();
TFT_Writ_Bus(da);
}
void TFT_WR_DATA(int da)
{
TFT_DC_Set();
TFT_Writ_Bus(da>>8);
TFT_Writ_Bus(da);
}
void TFT_WR_REG(char da)
{
TFT_DC_Clr();
TFT_Writ_Bus(da);
}
void TFT_WR_REG_DATA(int reg,int da)
{
TFT_WR_REG(reg);
TFT_WR_DATA(da);
}
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
TFT_WR_REG(0x2a);
TFT_WR_DATA8(x1>>8);
TFT_WR_DATA8(x1);
TFT_WR_DATA8(x2>>8);
TFT_WR_DATA8(x2);
TFT_WR_REG(0x2b);
TFT_WR_DATA8(y1>>8);
TFT_WR_DATA8(y1);
TFT_WR_DATA8(y2>>8);
TFT_WR_DATA8(y2);
TFT_WR_REG(0x2C);
}
void TFT_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能A端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOD3,6
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_4);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能A端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOD3,6
GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1);
//TFT_CS_Clr(); //打开片选使能
TFT_RST_Clr();
delay_ms(20);
TFT_RST_Set();
delay_ms(20);
TFT_BLK_Set();
//************* Start Initial Sequence **********//
TFT_WR_REG(0x36);
TFT_WR_DATA8(0x00);
TFT_WR_REG(0x3A);
TFT_WR_DATA8(0x05);
TFT_WR_REG(0xB2);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x00);
TFT_WR_DATA8(0x33);
TFT_WR_DATA8(0x33);
TFT_WR_REG(0xB7);
TFT_WR_DATA8(0x35);
TFT_WR_REG(0xBB);
TFT_WR_DATA8(0x19);
TFT_WR_REG(0xC0);
TFT_WR_DATA8(0x2C);
TFT_WR_REG(0xC2);
TFT_WR_DATA8(0x01);
TFT_WR_REG(0xC3);
TFT_WR_DATA8(0x12);
TFT_WR_REG(0xC4);
TFT_WR_DATA8(0x20);
TFT_WR_REG(0xC6);
TFT_WR_DATA8(0x0F);
TFT_WR_REG(0xD0);
TFT_WR_DATA8(0xA4);
TFT_WR_DATA8(0xA1);
TFT_WR_REG(0xE0);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2B);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x54);
TFT_WR_DATA8(0x4C);
TFT_WR_DATA8(0x18);
TFT_WR_DATA8(0x0D);
TFT_WR_DATA8(0x0B);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0xE1);
TFT_WR_DATA8(0xD0);
TFT_WR_DATA8(0x04);
TFT_WR_DATA8(0x0C);
TFT_WR_DATA8(0x11);
TFT_WR_DATA8(0x13);
TFT_WR_DATA8(0x2C);
TFT_WR_DATA8(0x3F);
TFT_WR_DATA8(0x44);
TFT_WR_DATA8(0x51);
TFT_WR_DATA8(0x2F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x1F);
TFT_WR_DATA8(0x20);
TFT_WR_DATA8(0x23);
TFT_WR_REG(0x21);
TFT_WR_REG(0x11);
//Delay (120);
TFT_WR_REG(0x29);
}
//清屏函数
//Color:要清屏的填充色
void TFT_Clear(u16 Color)
{
u16 i,j;
Address_set(0,0,TFT_W-1,TFT_H-1);
for(i=0;i<TFT_W;i++)
{
for (j=0;j<TFT_H;j++)
{
TFT_WR_DATA(Color);
}
}
}
//在指定位置显示一个汉字(32*33大小)
//dcolor为内容颜色,gbcolor为背静颜色
void showhanzi(unsigned int x,unsigned int y,unsigned char index)
{
unsigned char i,j;
unsigned char *temp=hanzi;
Address_set(x,y,x+31,y+31); //设置区域
temp+=index*128;
for(j=0;j<128;j++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
TFT_WR_DATA(POINT_COLOR);
}
else
{
TFT_WR_DATA(BACK_COLOR);
}
}
temp++;
}
}
//画点
//POINT_COLOR:此点的颜色
void TFT_DrawPoint(u16 x,u16 y)
{
Address_set(x,y,x,y);//设置光标位置
TFT_WR_DATA(POINT_COLOR);
}
//画一个大点
//POINT_COLOR:此点的颜色
void TFT_DrawPoint_big(u16 x,u16 y)
{
TFT_Fill(x-1,y-1,x+1,y+1,POINT_COLOR);
}
//在指定区域内填充指定颜色
//区域大小:
// (xend-xsta)*(yend-ysta)
void TFT_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
Address_set(xsta,ysta,xend,yend); //设置光标位置
for(i=ysta;i<=yend;i++)
{
for(j=xsta;j<=xend;j++)TFT_WR_DATA(color);//设置光标位置
}
}
//画线
//x1,y1:起点坐标
//x2,y2:终点坐标
void TFT_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if(delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平线
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//画线输出
{
TFT_DrawPoint(uRow,uCol);//画点
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//画矩形
void TFT_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)
{
TFT_DrawLine(x1,y1,x2,y1);
TFT_DrawLine(x1,y1,x1,y2);
TFT_DrawLine(x1,y2,x2,y2);
TFT_DrawLine(x2,y1,x2,y2);
}
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r :半径
void Draw_Circle(u16 x0,u16 y0,u8 r)
{
int a,b;
int di;
a=0;b=r;
di=3-(r<<1); //判断下个点位置的标志
while(a<=b)
{
TFT_DrawPoint(x0-b,y0-a); //3
TFT_DrawPoint(x0+b,y0-a); //0
TFT_DrawPoint(x0-a,y0+b); //1
TFT_DrawPoint(x0-b,y0-a); //7
TFT_DrawPoint(x0-a,y0-b); //2
TFT_DrawPoint(x0+b,y0+a); //4
TFT_DrawPoint(x0+a,y0-b); //5
TFT_DrawPoint(x0+a,y0+b); //6
TFT_DrawPoint(x0-b,y0+a);
a++;
//使用Bresenham算法画圆
if(di<0)di +=4*a+6;
else
{
di+=10+4*(a-b);
b--;
}
TFT_DrawPoint(x0+a,y0+b);
}
}
//在指定位置显示一个字符
//num:要显示的字符:" "--->"~"
//mode:叠加方式(1)还是非叠加方式(0)
//在指定位置显示一个字符
//num:要显示的字符:" "--->"~"
//mode:叠加方式(1)还是非叠加方式(0)
void TFT_ShowChar(u16 x,u16 y,u8 num,u8 mode)
{
u8 temp;
u8 pos,t;
u16 x0=x;
u16 colortemp=POINT_COLOR;
if(x>TFT_W-16||y>TFT_H-16)return;
//设置窗口
num=num-' ';//得到偏移后的值
Address_set(x,y,x+8-1,y+16-1); //设置光标位置
if(!mode) //非叠加方式
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(u16)num*16+pos]; //调用1608字体
for(t=0;t<8;t++)
{
if(temp&0x01)POINT_COLOR=colortemp;
else POINT_COLOR=BACK_COLOR;
TFT_WR_DATA(POINT_COLOR);
temp>>=1;
x++;
}
x=x0;
y++;
}
}else//叠加方式
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(u16)num*16+pos]; //调用1608字体
for(t=0;t<8;t++)
{
if(temp&0x01)TFT_DrawPoint(x+t,y+pos);//画一个点
temp>>=1;
}
}
}
POINT_COLOR=colortemp;
}
//m^n函数
u32 mypow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//color:颜色
//num:数值(0~4294967295);
void TFT_ShowNum(u16 x,u16 y,u32 num,u8 len)
{
u8 t,temp;
u8 enshow=0;
num=(u16)num;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
TFT_ShowChar(x+8*t,y,' ',0);
continue;
}else enshow=1;
}
TFT_ShowChar(x+8*t,y,temp+48,0);
}
}
//显示2个数字
//x,y:起点坐标
//num:数值(0~99);
void TFT_Show2Num(u16 x,u16 y,u16 num,u8 len)
{
u8 t,temp;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
TFT_ShowChar(x+8*t,y,temp+'0',0);
}
}
//显示字符串
//x,y:起点坐标
//*p:字符串起始地址
//用16字体
void TFT_ShowString(u16 x,u16 y,const u8 *p)
{
while(*p!='\0')
{
if(x>TFT_W-16){x=0;y+=16;}
if(y>TFT_H-16){y=x=0;TFT_Clear(RED);}
TFT_ShowChar(x,y,*p,0);
x+=8;
p++;
}
}
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "usart3.h"
#include "esp8266.h"
#include "string.h"
#include "timer.h"
#include "led.h"
#include "exti.h"
#include "oled.h"
#include "USART_LY.h"
#include "dog.h"
#include "dog.h"
#include "TFToled.h"
#include "TFTbmp.h"
/*
项目的主要内容:STM32配合ESP8266模块与服务器数据交互
MCU ESP8266
3.3V VCC
GND GND
PB10 RXD
PB11 TXD
3.3V IO
3.3V RST
--------------------------------
MCU USB转TTL
5V VCC
GND GND
PA9 RXD
PA10 TXD
----------------------------------------------------------------
MCU TFT1.3
GND 电源地
VCC 接5V或3.3v电源
CLK 接PA5(SCL)
MOSI 接PA7(SDA)
RES 接PB0
DC 接PB1
BLK 接A4 可以悬空
MISO 可以不接
*/
u8 flag = 0;
char t;
extern Results results[];
extern nt_calendar_obj nwt; //定义结构体变量
int year,month,date,hour,min,sec; //时间变量
//TFT
u8 ref=0;//刷新显示
u16 vx=15542,vy=11165; //比例因子,此值除以1000之后表示多少个AD值代表一个像素点
u16 chx=140,chy=146;//默认像素点坐标为0时的AD起始值
void xianshi1()//显示信息
{
BACK_COLOR=WHITE;
POINT_COLOR=RED;
showhanzi(15,0,0); //网
showhanzi(50,0,1); //络
showhanzi(85,0,2); //天
showhanzi(120,0,3); //气
showhanzi(155,0,4); //时
showhanzi(190,0,5); //钟
POINT_COLOR=BLACK;
TFT_ShowString(40,90,"WIFI"); //wife
showhanzi(75,80,21); //初
showhanzi(110,80,22); //始
showhanzi(145,80,23); //化
showhanzi(180,80,24); //中
}
void xianshi2()//显示信息
{
BACK_COLOR=WHITE;
POINT_COLOR=RED;
showhanzi(15,0,0); //网
showhanzi(50,0,1); //络
showhanzi(85,0,2); //天
showhanzi(120,0,3); //气
showhanzi(155,0,4); //时
showhanzi(190,0,5); //钟
POINT_COLOR=BLACK;
showhanzi(40,80,21); //初
showhanzi(75,80,22); //始
showhanzi(110,80,23); //化
showhanzi(145,80,25); //成
showhanzi(180,80,26); //功
}
void xianshi3()//显示信息
{
BACK_COLOR=WHITE;
POINT_COLOR=RED;
showhanzi(15,0,0); //网
showhanzi(50,0,1); //络
showhanzi(85,0,2); //天
showhanzi(120,0,3); //气
showhanzi(155,0,4); //时
showhanzi(190,0,5); //钟
POINT_COLOR=BLACK;
showhanzi(40,80,27); //获
showhanzi(75,80,28); //取
showhanzi(110,80,29); //数
showhanzi(145,80,30); //据
showhanzi(180,80,24); //中
}
void xianshi4()//显示信息
{
BACK_COLOR=WHITE;
POINT_COLOR=RED;
showhanzi(15,0,0); //网
showhanzi(50,0,1); //络
showhanzi(85,0,2); //天
showhanzi(120,0,3); //气
showhanzi(155,0,4); //时
showhanzi(190,0,5); //钟
POINT_COLOR=BLACK;
showhanzi(40,80,27); //获
showhanzi(75,80,28); //取
showhanzi(110,80,25); //成
showhanzi(145,80,26); //功
}
void showimage40() //显示40*40图片
{
int i; //数组一半长度
int j; //显示几列 [0~6]
int k; //图片显示第几行
for(k=1; k<2; k++)
{
for(j=4; j<5; j++)
{
Address_set(40*j,40*k,40*j+39,40*k+39); //坐标设置
for(i=0; i<1600; i++)
{
TFT_WR_DATA8(image_top[i*2+1]);
TFT_WR_DATA8(image_top[i*2]);
}
}
}
ref=0;
}
int Change(int year, int month, int day) //根据日期判断出星期几
{
if(month == 1 || month == 2)
{
month += 12;
year--;
}
int c = year / 100;
int y = year % 100;
int m = month;
int d = day;
int W = c / 4 - 2 * c + y + y / 4 + 26 * (m + 1) / 10 + d - 1;
int ans;
if(W < 0)
ans = (W + (-W / 7 + 1) * 7) % 7;
else
ans = W % 7;
if(ans == 0) //星期7而不是星期0
return ans + 7;
return ans;
}
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置中断优先级分组2
TFT_Init(); //初始化TFT
EXTIX_Init(); //外部中断初始化
uart_init(115200); //串口初始化为115200
usart3_init(115200); //串口初始化为115200 esp
USART2_HC05_Init(); //串口初始化为9600 hc05
OLED_Init(); //OLED初始化
TIM3_Int_Init(9999,7199); //10Khz的计数频率,计数到10000为1s
TIM4_Init(); //15min更新天气
TFT_Clear(WHITE); //清屏
xianshi1();
LY_Printf("开始");
esp8266_start_trans(); //初始化
TFT_Clear(WHITE); //清屏
xianshi2();
delay_ms(1000);
TFT_Clear(WHITE); //清屏
xianshi3();
get_current_weather(); //获取天气
delay_ms(200);
get_beijing_time(); //获取时间
sec = nwt.sec;
TIM_Cmd(TIM3, ENABLE); //使能TIM3外设
year = nwt.year;
month = nwt.month;
date = nwt.date;
hour = nwt.hour;
min = nwt.min;
TFT_Clear(WHITE); //清屏
xianshi4();
delay_ms(1000);
Iwdg_Init();//设置看门狗重装载值,确定溢出时间:4s
LY_Printf("\n\r获取完成");
TFT_Clear(WHITE); //清屏
while (1)
{
if(sec >= 60)
{
sec = 0;
min ++;
}
if(min >= 60)
{
min = 0;
hour ++;
}
if(hour >= 24)
{
hour = 0;
date=date+1;
}
/*******************************************
时间计数判断,其中秒的自加在中断3实现。
******************************************/
BACK_COLOR=WHITE;
POINT_COLOR=RED;
showhanzi(15,0,34); //西
showhanzi(50,0,35); //安
showhanzi(85,0,2); //天
showhanzi(120,0,3); //气
showhanzi(155,0,4); //时
showhanzi(190,0,5); //钟
//显示头像图片
showimage40();
showhanzi(40,50,9); //星
showhanzi(80,50,10); //期
if(Change(year,month,date)==1)
{
showhanzi(120,50,11); //一
}else if(Change(year,month,date)==2)
{
showhanzi(120,50,12); //二
}else if(Change(year,month,date)==3)
{
showhanzi(120,50,13); //三
}else if(Change(year,month,date)==4)
{
showhanzi(120,50,14); //四
}else if(Change(year,month,date)==5)
{
showhanzi(120,50,15); //五
}else if(Change(year,month,date)==6)
{
showhanzi(120,50,16); //六
}else if(Change(year,month,date)==7)
{
showhanzi(120,50,17); //日
}
POINT_COLOR=BLACK;
TFT_ShowNum(145,135,sec,3); //显示秒
showhanzi(170,125,20);
TFT_ShowNum(95,135,min,3); //显示分钟
showhanzi(120,125,19);
TFT_ShowNum(35,135,hour,3); //显示小时
showhanzi(70,125,18);
POINT_COLOR=BLACK;
TFT_ShowNum(30,100,year,4); //显示年份
showhanzi(70,90,6);
TFT_ShowNum(95,100,month,3); //显示月份
showhanzi(120,90,7);
TFT_ShowNum(145,100,date,3); //显示日
showhanzi(170,90,8);
showhanzi(50,165,2); //天
showhanzi(90,165,3); //气
TFT_ShowString(120,175,":");
TFT_ShowString(145,175,(u8*)results[0].now.text); //采集到的天气
showhanzi(50,205,31); //温
showhanzi(90,205,32); //度
TFT_ShowString(120,215,":");
TFT_ShowString(145,215,(u8*)results[0].now.temperature); //采集到的温度
showhanzi(175,205,33); //℃
//喂狗
// IWDG_Feed();
// delay_ms(1000);//一秒
// delay_ms(1000);//1秒
/*******************************************
按键中断触发,改变LED状态以及flag的值,
当按键按下时,flag = 1,开始更新数据。
******************************************/
if (flag == 1)
{
get_current_weather(); //获取天气
delay_ms(200);
get_beijing_time(); //获取时间
flag = 0;
year = nwt.year;
month = nwt.month;
date = nwt.date;
hour = nwt.hour;
min = nwt.min;
sec = nwt.sec;
}
}
}
关注收藏不迷路
注:本文,参考绵绵呀的博客-CSDN博客,感谢这位博主。
所以我学习博主的精神,在文章最后我会给出百度网盘链接,尽管如此还是希望大家认真观看文章,并琢磨程序代码逻辑在我的基础上可以改出属于自己特点的工程!
给那些看完的朋友,奖励一个 赤赤博客-后端+前端,觉得不错的话可以推荐给身边的朋友哟!