本帖最后由 nvjwiciw659 于 2020-12-7 09:26 编辑
最近出差,回到郑州发现暖气已经通了,有暖气的感觉真好.同时因为出差耽误了测评,现在我把之前搞得几个外设综合一下,做一个小DEMO,监测一下家里的温度.
所用外设
* 1.GPIO 一直闪烁,表示运行状态
* 2.USART 串口,与8266通信必备
* 3.SPI 读写外部FLASH(记录上电次数,很无聊的一个功能)
* 4.TIM 定时器,用于计时
* 5.ADC 用于读取内部温度
外观
简单用杜邦线连了连,也没什么外观可言
GPIO
这里只做了简单的点灯,通过计时器,1S中闪烁一次
USART&连接Onenet
上篇我写好了串口收发驱动,这次直接用就行,我们添加一些驱动,用的是最简单的HTTP协议,直接按文档POST即可,代码如下
#include "ESP.h"
#include "tim.h"
#include "usart.h"
#include "debug.h"
#include <stdio.h>
#include <string.h>
#define DEVID "********"
#define APIKEY "********"
extern float tem;
char *const esp_inti_cmd[][2] = {
"AT\r\n", "OK",
"ATE0\r\n", "OK",
"AT+CWMODE=3\r\n", "OK",
"AT+CWJAP=\"********\",\"3673671040\"\r\n", "GOT IP",
"AT+CIFSR\r\n", "OK",
"AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n", "CONNECT",
//"AT+CIPSEND=4\r\n", "OK",
//"test", "SEND OK",
0, 0};
/*
串口发送函数
*str为指令
len为指令长度
*/
void ESP_SendString(unsigned char *str, unsigned short len)
{
uint8_t i;
for(i=0;i<len;i++)
{
USARTx_SendByte(USART3, *(str+i));
}
}
/*
AT指令发送函数
*cmd为AT指令
*res为需匹配的数据
timeOut未等待时间
匹配成功返回 0
匹配失败返回 1
*/
_Bool ESP8266_SendCmd(char *cmd, char *res,uint16_t timeOut)
{
ESP_SendString((unsigned char *)cmd, strlen((const char *)cmd));//发送AT指令
while(timeOut--)//等待
{
if(!uart2_rx.flag) //如果收到数据
{
if(strstr((const char *)uart2_rx.rx_buff, res) != NULL) //如果匹配到数据
{
CLEAR_UART2(); //清空缓存
return 0;
}
}
Delay_Ms(1);
}
return 1;
}
/*
服务器下发解析函数
返回值为结构体
ipd_rx.len
非下发数据返回:0
解析失败返回:-1
正确解析返回:数据长度
*/
IPD_RX ESP8266_GetIPD(void)
{
IPD_RX ipd_rx;
uint8_t i;
char *ptrIPD = NULL;
ipd_rx.len = 0;
ptrIPD = strstr((char *)uart2_rx.rx_buff, "IPD,"); //搜索“IPD”头
if(ptrIPD == NULL)//没找到直接退出
{
ipd_rx.len = 0;
return ipd_rx;
}
else
{
ptrIPD = strchr(ptrIPD, ','); //找到','
ptrIPD++;
for(i=0;i<10;i++)//获取数据长度
{
if((ptrIPD[i]>='0')&&(ptrIPD[i]<='9'))
{
ipd_rx.len = ipd_rx.len*10+(ptrIPD[i]-'0');
}
else break;
}
ptrIPD = strchr(ptrIPD, ':'); //找到':'
if(ptrIPD != NULL)
{
ptrIPD++;
ipd_rx.IPD_buff = (uint8_t *)(ptrIPD);
return ipd_rx;
}
else
{
ipd_rx.len = -1;
return ipd_rx;
}
}
}
_Bool esp_test(void)
{
uint8_t i;
for(i=0;i<100;i++)
{
if(esp_inti_cmd[i][0])
{
if(ESP8266_SendCmd(esp_inti_cmd[i][0],esp_inti_cmd[i][1],5000))
{
printf("Init:%d error\r\n",i);//失败
}
else
{
printf("Init:%d ok\r\n",i);//成功
}
}
else
{
printf("ESP Init Success\r\n");
return 0;//初始化完成
}
}
return 1;
}
void OneNet_FillBuf(char *buf)
{
char text[24];
char buf1[128];
memset(text, 0, sizeof(text));
memset(buf1, 0, sizeof(buf1));
strcpy(buf1, "{");
memset(text, 0, sizeof(text));
sprintf(text, "\"Temperature\":%f",tem);
strcat(buf1, text);
strcat(buf1, "}");
sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\n"
"Content-Length:%d\r\n\r\n",
DEVID, APIKEY, strlen(buf1));
strcat(buf, buf1);
}
//==========================================================
// 函数名称: OneNet_SendData
//
// 函数功能: 上传数据到平台
//
// 入口参数: type:发送数据的格式
//
// 返回参数: 无
//
// 说明:
//==========================================================
void OneNet_SendData(void)
{
char buf[256];
char buf1[50];
memset(buf, 0, sizeof(buf));
memset(buf1, 0, sizeof(buf1));
OneNet_FillBuf(buf); //封装数据流
sprintf(buf1, "AT+CIPSEND=%d\r\n",strlen(buf));
ESP8266_SendCmd(buf1,"OK",5000);
ESP_SendString((unsigned char *)buf, strlen(buf)); //上传数据
}
SPI读写外部FLASH
这里我用了官方的例程,所以只发应用了
/*记录上电次数*/
SPI_Flash_Read(&count,0x0,1);
Delay_Ms(100);
if(!count)
count++;
printf("Number of power on Is: %d\r\n",count);
count++;
SPI_Flash_Write(&count,0,1);
Delay_Ms(500)
TIM
我这里使用定时器主要就是做一个简单的计时,驱动也是例程写好的,直接运用了,就是用来让灯亮灭以及定时上传温度
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3中断是否发生。
{
if(tim_count%2)
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
else
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
tim_count++;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3的中断挂起位。
}
}
ADC
使用ADC计算内部温度,上篇已经说过,这里就不贴代码了.
MAIN
贴一下main函数
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Return : None
*******************************************************************************/
int main(void)
{
u8 count;
/*外设初始化*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
Delay_Init();
USART_Printf_Init(115200);
USARTx_CFG();
adc_Init();
LED_Init();
SPI_Flash_Init();
TIM3_Int_Init(4999,7199);
/*记录上电次数*/
SPI_Flash_Read(&count,0x0,1);
Delay_Ms(100);
if(!count)
count++;
printf("Number of power on Is: %d\r\n",count);
count++;
SPI_Flash_Write(&count,0,1);
Delay_Ms(500);
/*初始化串口缓存结构体*/
CLEAR_UART2();
esp_test();
while(1)
{
if(tim_count>50)
{
tim_count = 0;
tem=get_temperature();
printf("Temperature:%.2f\r\n",tem);
CLEAR_UART2();
OneNet_SendData();
}
}
}
展示一下Onenet的应用
算是基本完结了吧,USB功能一直没能尝试,明天又是周一了,又开始忙碌的一周,有时间再搞(一直想玩USB功能却一直没玩,害),沁恒加油!,俺一直稀罕你支持你,国产加油!最后说一句,期待573.
再展示一个一直想玩但没时间玩的,而且已经买了,板子已经偷偷画好的579
加油,打工人,奥里给!
哎哎哎,最后附上gitee链接,主要文件我都传了上去
https://gitee.com/shihengrui/ch32-vf103
|