代码仓库本次使用的外设是WiFi模块ESP8484该模块搭载AT固件可通过AT指令进行配置和操作其通信方式与蓝牙模块类似。模块通过串口与MCU连接用MCU的最后一个可用串口UART1来实现通信。建议在连接WiFi前先通过USB转TTL连接模块使用电脑发送AT指令测试模块功能是否正常。初始化voidUART_WIFI_Init(uint32_tbuad){GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;//时钟开启RCC_AHB1PeriphClockCmd(UARTx_WIFI_GPIO_CLK,ENABLE);RCC_APB2PeriphClockCmd(UARTx_WIFI_RCC_CLK,ENABLE);//串口1对应引脚复用映射GPIO_PinAFConfig(UARTx_WIFI_TX_GPIO_PORT,UARTx_WIFI_TX_PIN_SOURCE,UARTx_WIFI_TX_AF);GPIO_PinAFConfig(UARTx_WIFI_RX_GPIO_PORT,UARTx_WIFI_RX_PIN_SOURCE,UARTx_WIFI_RX_AF);/* Reset GPIO init structure parameters values */GPIO_InitStruct.GPIO_PinUARTx_WIFI_TX_PIN|UARTx_WIFI_RX_PIN;GPIO_InitStruct.GPIO_ModeGPIO_Mode_AF;GPIO_InitStruct.GPIO_SpeedGPIO_Speed_50MHz;GPIO_InitStruct.GPIO_OTypeGPIO_OType_PP;GPIO_InitStruct.GPIO_PuPdGPIO_PuPd_UP;GPIO_Init(UARTx_WIFI_TX_GPIO_PORT,GPIO_InitStruct);/* USART_InitStruct members default value */USART_InitStruct.USART_BaudRatebuad;USART_InitStruct.USART_WordLengthUSART_WordLength_8b;USART_InitStruct.USART_StopBitsUSART_StopBits_1;USART_InitStruct.USART_ParityUSART_Parity_No;USART_InitStruct.USART_ModeUSART_Mode_Rx|USART_Mode_Tx;USART_InitStruct.USART_HardwareFlowControlUSART_HardwareFlowControl_None;USART_Init(UARTx_WIFI,USART_InitStruct);// 使能接收中断 (RXNE)USART_ITConfig(UARTx_WIFI,USART_IT_RXNE,ENABLE);//使能USART_Cmd(UARTx_WIFI,ENABLE);}也是由中断来接收数据voidNVIC_WIFI_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannelUSART1_IRQn;// 中断通道为 USART1NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority0;// 抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority1;// 响应优先级NVIC_InitStructure.NVIC_IRQChannelCmdENABLE;// 使能中断NVIC_Init(NVIC_InitStructure);}voidUSART1_IRQHandler(void){if(USART_GetITStatus(UARTx_WIFI,USART_IT_RXNE)!RESET){if(USARTx_WIFI_Rx_Index4096){USARTx_WIFI_Rx_Data[USARTx_WIFI_Rx_Index](uint8_t)USART_ReceiveData(UARTx_WIFI);}else{// 缓冲区满丢弃数据并重置索引(void)USART_ReceiveData(UARTx_WIFI);USARTx_WIFI_Rx_Index0;// 重置避免溢出}}// printf(Received: %.*s\r\n, USARTx_WIFI_Rx_Index, USARTx_WIFI_Rx_Data);}接收后的数据处理任务voidWifi_RxTask(void*pvParameters){uint16_tlen;uint16_tlast_index0;uint32_tlast_recv_time0;while(1){if(USARTx_WIFI_Rx_Index0){if(last_index!USARTx_WIFI_Rx_Index){// 有新的数据到达更新时间戳last_indexUSARTx_WIFI_Rx_Index;last_recv_timexTaskGetTickCount();}// 检查是否超过10ms没有新数据elseif((xTaskGetTickCount()-last_recv_time)pdMS_TO_TICKS(50)last_indexUSARTx_WIFI_Rx_Index){// 超时认为接收完成taskENTER_CRITICAL();lenUSARTx_WIFI_Rx_Index;USARTx_WIFI_Rx_Index0;taskEXIT_CRITICAL();last_index0;printf(Received: %.*s\r\n,len,USARTx_WIFI_Rx_Data);}}else{last_index0;// 重置}vTaskDelay(pdMS_TO_TICKS(1));// 1ms轮询}}发送接口uint16_tUSARTx_Wifi_Send(uint8_t*data,uint16_tlength){USARTx_Wifi_TxPacket_t packet;// 检查队列是否已创建if(USARTx_Wifi_TxQueueNULL){printf(Queue not initialized!\r\n);returnUSART_WIFI_QUEUE_CREATION_FAILED;}// printf(Queueing data for transmission: %.*s\r\n, length, data);packet.lengthlength;if(packet.length1024)returnUSART_WIFI_SEND_LEN_ERROR;memcpy(packet.buffer,data,packet.length);BaseType_t retxQueueSend(USARTx_Wifi_TxQueue,packet,pdMS_TO_TICKS(100));if(ret!pdTRUE){printf(Queue send failed!\r\n);returnUSART_WIFI_QUEUE_SEND_FAILED;}return0;}发送任务voidWifi_TxTask(void*pvParameters){USARTx_Wifi_TxPacket_t packet;USARTx_Wifi_TxQueuexQueueCreate(10,sizeof(USARTx_Wifi_TxPacket_t));// 添加队列创建失败的检查if(USARTx_Wifi_TxQueueNULL){printf(USARTx_Wifi_TxQueue creation failed!\r\n);while(1);// 队列创建失败停机喂狗任务也无法执行会复位}printf(USARTx_Wifi_TxQueue created successfully.\r\n);while(1){if(xQueueReceive(USARTx_Wifi_TxQueue,packet,portMAX_DELAY)pdTRUE){// printf(Sending data: %.*s\r\n, packet.length, packet.buffer);for(inti0;ipacket.length;i){USART_SendData(UARTx_WIFI,packet.buffer[i]);while(USART_GetFlagStatus(UARTx_WIFI,USART_FLAG_TXE)RESET);}}}}先使用几个AT指令测试通讯是否正常uint16_tWifi_Send_AT_Command(char*command){returnUSARTx_Wifi_Send((uint8_t*)command,strlen(command));}staticuint16_tWifi_command_init(void){Wifi_Send_AT_Command(AT\r\n);// 测试AT启动vTaskDelay(pdMS_TO_TICKS(100));Wifi_Send_AT_Command(ATE0\r\n);// 关闭回显vTaskDelay(pdMS_TO_TICKS(100));// Wifi_Send_AT_Command(ATGMR\r\n);// 查看版本信息// vTaskDelay(pdMS_TO_TICKS(100));Wifi_Send_AT_Command(ATCWHOSTNAME?\r\n);// 查询作为Station时的名称vTaskDelay(pdMS_TO_TICKS(100));return0;}voidWifi_Init_Task(void*pvParameters){printf(Wifi initialization task started\r\n);while(xWifiTxTaskHandleNULL||xWifiRxTaskHandleNULL){vTaskDelay(pdMS_TO_TICKS(50));// 等待50ms再检查}// 额外延迟一点确保队列等资源也初始化完成vTaskDelay(pdMS_TO_TICKS(100));// 执行wifi初始化printf(Starting Wifi AT commands...\r\n);Wifi_command_init();printf(Wifi initialization completed, deleting this task\r\n);vTaskDelete(NULL);}测试结果Serial communication is normal Free heap before any task:0bytes After Key_Task:40592bytes After Feeddog_Task:40360bytes After Wifi_TxTask:36160bytes After Wifi_RxTask:31960bytes After Wifi_Init_Task:29808bytes USARTx_Wifi_TxQueue created successfully.Wifi initialization task started Starting Wifi AT commands...Received:OK Received:OK Received:CWHOSTNAME:espressif OK Wifi initialization completed,deleting this task注意当之后若是打开多个外设需要创建多个任务那么就需要合理分配堆栈空间staticvoidAll_Task_Create(void){printf(Free heap before any task: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(Key_Task,Key_Task,64,NULL,1,NULL);printf(After Key_Task: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(Feeddog_Task,Feeddog_Task,32,NULL,1,NULL);printf(After Feeddog_Task: %d bytes\r\n,xPortGetFreeHeapSize());if(dht11_init_flag){xTaskCreate(DHT11_Read_Task,DHT11_Task,512,NULL,2,NULL);printf(After DHT11_Read_Task: %d bytes\r\n,xPortGetFreeHeapSize());}#ifUSE_PERIPHERALS_ROCKERxTaskCreate(Rocker_Read_Task,Rocker_Task,1024,NULL,2,NULL);printf(After Rocker_Read_Task: %d bytes\r\n,xPortGetFreeHeapSize());#endif#ifUSE_PERIPHERALS_BTxTaskCreate(BT_TxTask,BT_TxTask,512,NULL,2,xBTTxTaskHandle);printf(After BT_TxTask: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(BT_RxTask,BT_RxTask,512,NULL,2,xBTRxTaskHandle);printf(After BT_RxTask: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(Bluetooth_Init_Task,Bluetooth_Init_Task,512,NULL,3,NULL);printf(After Bluetooth_Init_Task: %d bytes\r\n,xPortGetFreeHeapSize());#endif#ifUSE_PERIPHERALS_WIFIxTaskCreate(Wifi_TxTask,Wifi_TxTask,1024,NULL,2,xWifiTxTaskHandle);printf(After Wifi_TxTask: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(Wifi_RxTask,Wifi_RxTask,1024,NULL,2,xWifiRxTaskHandle);printf(After Wifi_RxTask: %d bytes\r\n,xPortGetFreeHeapSize());xTaskCreate(Wifi_Init_Task,Wifi_Init_Task,512,NULL,2,NULL);printf(After Wifi_Init_Task: %d bytes\r\n,xPortGetFreeHeapSize());#endif}或者设置大一些的总堆空间#defineconfigTOTAL_HEAP_SIZE(40*1024)不然会一直重启。