AT串口抽象层的设计思路及代码实现
生活随笔
收集整理的這篇文章主要介紹了
AT串口抽象层的设计思路及代码实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 AT串口抽象層的設計思路及代碼實現
- 1.1 AT串口抽象層的設計思路
- 1.2 AT串口抽象層的代碼實現
1 AT串口抽象層的設計思路及代碼實現
1.1 AT串口抽象層的設計思路
我們先來看下AT串口的發送模型和AT串口接收模型:
下面看一下發送流程、接收流程及中斷處理流程:
1.2 AT串口抽象層的代碼實現
at_uart_hal.h:
#ifndef __AT_UART_HAL_H #define __AT_UART_HAL_H#include <stdbool.h>bool at_uart_init(void); bool at_uart_deinit(void); uint32_t at_uart_send(const void *pdata, uint32_t size, uint32_t timeout); uint32_t at_uart_receive(void *pdata, uint32_t expect_size,uint32_t timeout); void at_uart_irq_handler(void);#endifat_uart_hal.c:
#include <stdbool.h> #include "main.h" #include "usart.h" #include "app_debug.h"#include "FreeRTOS.h" #include "stream_buffer.h"#define AT_UART huart4 #define AT_UART_SEND_BUF_SIZE 300 #define AT_UART_RECV_BUF_SIZE 300 static StreamBufferHandle_t stream_send=NULL; static StreamBufferHandle_t stream_recv=NULL; static bool is_inited=false;bool at_uart_deinit(void) {DEBUG("at uart deinit");is_inited=false;__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_RXNE);__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_TXE);if(stream_send!=NULL){vStreamBufferDelete(stream_send);}if(stream_recv!=NULL){vStreamBufferDelete(stream_recv);}return true; }bool at_uart_init(void) {if(is_inited)return true;DEBUG("at uart init!");do{stream_send=xStreamBufferCreate(AT_UART_SEND_BUF_SIZE,1);if(stream_send==NULL)break;stream_recv=xStreamBufferCreate(AT_UART_RECV_BUF_SIZE,1);if(stream_recv==NULL)break;__HAL_UART_ENABLE_IT(&AT_UART,UART_IT_RXNE);is_inited=true; DEBUG("at uart init ok!"); return true;} while (0);at_uart_deinit();return false; }uint32_t at_uart_send(const void *pdata, uint32_t size, uint32_t timeout) {uint32_t write_len;if(is_inited==false)return 0;write_len=xStreamBufferSend(stream_send,pdata,size,timeout);__HAL_UART_ENABLE_IT(&AT_UART,UART_IT_TXE);return write_len; } uint32_t at_uart_receive(void *pdata, uint32_t expect_size,uint32_t timeout) {uint32_t read_len;if(is_inited==false)return 0;read_len=xStreamBufferReceive(stream_recv,pdata,expect_size,timeout);return read_len; } void at_uart_irq_handler(void) {uint8_t ch;BaseType_t xHigherPriorityTaskWoken = pdFALSE;if ((__HAL_UART_GET_IT(&AT_UART,UART_IT_TXE))&&(__HAL_UART_GET_IT_SOURCE(&AT_UART,UART_IT_TXE)!=RESET)){if(xStreamBufferReceiveFromISR(stream_send,&ch,1,&xHigherPriorityTaskWoken)==1){AT_UART.Instance->TDR=ch;}else{__HAL_UART_DISABLE_IT(&AT_UART,UART_IT_TXE); }}if ((__HAL_UART_GET_IT(&AT_UART,UART_IT_RXNE))&&(__HAL_UART_GET_IT_SOURCE(&AT_UART,UART_IT_RXNE)!=RESET)){ch=(uint8_t)(AT_UART.Instance->RDR&0xff);xStreamBufferSendFromISR(stream_recv,&ch,1,&xHigherPriorityTaskWoken);}portYIELD_FROM_ISR(xHigherPriorityTaskWoken); }中斷中需加入如下代碼:
/*** @brief This function handles USART4 and USART5 interrupt.*/ void USART4_5_IRQHandler(void) {/* USER CODE BEGIN USART4_5_IRQn 0 */extern void at_uart_irq_handler(void);at_uart_irq_handler();/* USER CODE END USART4_5_IRQn 0 *//* USER CODE BEGIN USART4_5_IRQn 1 *//* USER CODE END USART4_5_IRQn 1 */ }測試代碼如下:
/* USER CODE BEGIN Header_StartDefaultTask */ /*** @brief Function implementing the defaultTask thread.* @param argument: Not used* @retval None*/ /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void const * argument) {/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */float temp,humi;uint8_t write_buf[]="1234567890";uint8_t read_buf[20];uint16_t read_len;#define TEST_NAME 0X0001uint8_t buf[5];debug_init();led_init();key_init();led_blink(2,5);sht30_init();at_uart_init();for(;;){if(at_uart_receive(buf,1,1000)){DEBUG("-%c-",buf[0]);}//at_uart_send("12345\r\n",7,1000);// storage_write(TEST_NAME,sizeof(write_buf),write_buf);// memset(read_buf,0,20);// read_len=20;// if(storage_read(TEST_NAME,&read_len,read_buf))// {// DEBUG("------%s-----",read_buf);// }// if(sht30_get_temp_humi(&temp,&humi))// {// DEBUG("temp=%f,humi=%f",temp,humi);// }osDelay(1);}/* USER CODE END StartDefaultTask */ }總結
以上是生活随笔為你收集整理的AT串口抽象层的设计思路及代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字节跳动上市了吗 哪一年成立的
- 下一篇: AT框架架构图