1.修改结构体
typedef struct { uint8_t dma_rx_buff[RX_BUF_MAX_LEN];//DMA缓存区 uint8_t rec_rx_buff[RX_BUF_MAX_LEN];//REC缓存区 uint16_t rec_len; //DMA接收长度 uint16_t dma_len; //REC接收长度 volatile uint8_t flag; //用于判断是否接收完 1为接收完 }USRAT_RX;
2.修改中断接收函数
void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)//产生空闲中断(说明接收完一包) { __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除空闲中断标志(否则会一直不断进入中断) HAL_UART_DMAStop(&huart1);//停止本次DMA传输 usart1_rx.dma_len = RX_BUF_MAX_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//计算接收到的数据长度 if(usart1_rx.rec_len>0)//证明数据未处理即还有未完成数据 { memcpy(&usart1_rx.rec_rx_buff[usart1_rx.rec_len],usart1_rx.dma_rx_buff,usart1_rx.dma_len); //转存到待处理区域 usart1_rx.rec_len += usart1_rx.dma_len; } else { memcpy(usart1_rx.rec_rx_buff,usart1_rx.dma_rx_buff,usart1_rx.dma_len);//转存到待处理区域 usart1_rx.rec_len = usart1_rx.dma_len; } usart1_rx.flag = 1; if(usart1_rx.rec_len == 0)//防止误入 { usart1_rx.flag = 0; } HAL_UART_Receive_DMA(&huart1, (uint8_t*)usart1_rx.dma_rx_buff, RX_BUF_MAX_LEN);//设置DMA传输,串口2的数据搬运到缓存中 HAL_UART_DMAResume(&huart1);//恢复DMA传输 } /* USER CODE END USART1_IRQn 1 */ }
3.修改清空函数
void Clear_Usart(USRAT_RX *usart_rx)//初始化(清空)串口结构体 { memset(&usart_rx->rec_rx_buff[0], 0, RX_BUF_MAX_LEN);//全写0 usart_rx->rec_len = 0; usart_rx->flag = 0; }
4.将之前的数据处理中的rx_buff全改为rec_rx_buff,len都改为rec_len
5.稍微修改代码
Start_Count(); OLED_Init(); AHT10Init(); Clear_Usart(&usart1_rx);//初始化串口结构体 __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//使能空闲中断 HAL_UART_Receive_DMA(&huart1, (uint8_t*)usart1_rx.dma_rx_buff, RX_BUF_MAX_LEN);//设置DMA传输,串口2的数据搬运到缓存中 esp_init(); /*电子产品世界*/ OLED_ShowCHinese(0u,0u,0); OLED_ShowCHinese(16u,0u,1); OLED_ShowCHinese(32u,0u,2); OLED_ShowCHinese(48u,0u,3); OLED_ShowCHinese(64u,0u,4); OLED_ShowCHinese(80u,0u,5); /**************/ /* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { static uint16_t num; num++; BH1750_Send_Cmd(ONCE_H_MODE);//单次模式 sprintf(buf,"tem:%.1f ",pv.tem); OLED_P8x16Str(0u,2u,(uint8_t *)buf); sprintf(buf,"hum:%d%% ",pv.hum); OLED_P8x16Str(0u,4u,(uint8_t *)buf); sprintf(buf,"lux:%d ",pv.lux_16); OLED_P8x16Str(0u,6u,(uint8_t *)buf); AHT10ReadData(&pv.tem,&pv.hum); BH1750_Read_Dat(pv.lux);//读取数据 pv.lux_16 = BH1750_Dat_To_Lux(pv.lux);//转换数据 if(num>100) { num = 0; printf("lux:%d\r\n",pv.lux_16); printf("tem:%.1f\r\nhum:%d%%\r\n",pv.tem,pv.hum); OneNet_SendData();//上传数据 HAL_Delay(200);//等待平台回复 } if(usart1_rx.flag)//接收到数据 { ipd_rx = ESP8266_GetIPD();//解析数据 if(ipd_rx.len>0)//判断是否为网络下发数据 { printf("\r\n\r\nipd_rx.IPD_buff:%s\r\n\r\n",ipd_rx.IPD_buff); } Clear_Usart(&usart1_rx);//清空缓存 } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
6.烧录看结果
返回数据已经完整接收到了
发现,当发送POST数据之后,它能返回一串数据,仔细看,会发现里边有一串时间这就是GMT时间
GMT时间就是英国格林威治时间,也就是世界标准时间,是本初子午线上的地方时,是0时区的区时,与我国的标准时间北京时间(东八区)相差8小时,即晚8小时
比如GMT时间为14:54:11,北京时间就是(15+8):54:11即为23:54:11,下面就通过字符串操作来取出这段时间,并显示在OLED上,因为我POST的速度并不是很快,所以我只截取了小时和分钟
下面上程序
if(usart1_rx.flag)//接收到数据 { ipd_rx = ESP8266_GetIPD();//解析数据 if(ipd_rx.len>0)//判断是否为网络下发数据 { printf("\r\n\r\nipd_rx.IPD_buff:%s\r\n\r\n",ipd_rx.IPD_buff); dateadr= strstr((char *)ipd_rx.IPD_buff, "GMT");//找到"GMT" memcpy(buf,dateadr-9,5); hour = (buf[0]-0x30)*10+(buf[1]-0x30); hour+=8; if(hour>23) hour-=24; min = (buf[3]-0x30)*10+(buf[4]-0x30); printf("%02d:%02d\r\n",hour,min); sprintf(buf,"%02d:%02d EEPW",hour,min); OLED_P8x16Str(0u,0u,(uint8_t *)buf); } Clear_Usart(&usart1_rx);//清空缓存 }
思路很简单就是找到GMT的位置,再往前9个字符,然后截取前5个,把小时数加8,超过23就减24,然后显示在OLED上
效果如下
http有POST了,当然不能少了GET,下篇搞一个api get获取天气,制作一个简单的桌面天气