AT串口抽象层的设计思路及代码实现

本文详细阐述了AT串口抽象层的设计思路,包括发送和接收模型,以及关键的初始化、中断处理和函数实现。通过实例代码展示了如何使用xStreamBuffer进行高效的数据传输和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);


#endif


at_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 0X0001
  uint8_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 */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值