本帖最后由 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
|