合宙AIR001 HAL库 串口接收空闲中断+DMA

合宙AIR001 HAL库 串口接收空闲中断+DMA

HAL库嘛,与STM32操作基本一致,下面是流程

初始化UART

这里用的是串口1,所以以下都是串口1的初始化

首先创建串口1的操作句柄

然后使能串口1的时钟与配置串口1的各项参数

UART_HandleTypeDef huart1;        // uart句柄
__HAL_RCC_USART1_CLK_ENABLE();               // 使能uart1时钟
huart1.Instance = USART1;                    // USART1
huart1.Init.BaudRate = 460800;               // 波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B; // 8位数据长度
huart1.Init.StopBits = UART_STOPBITS_1;      // 1位停止位
huart1.Init.Parity = UART_PARITY_NONE;       // 无校验位
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控
huart1.Init.Mode = UART_MODE_TX_RX;          // 收发模式

调用HAL库串口初始化函数进行串口初始化

HAL_UART_Init(&huart1);

配置串口1中断,中断号可以在air001_dev.h头文件中找到

如下图

image-20230818134448665

    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); // 抢占优先级0,子优先级0
    HAL_NVIC_EnableIRQ(USART1_IRQn);         // 使能串口1中断

复用GPIO复用功能

此处使用PF0与PF1作为串口1的RX与TX脚,引脚功能可以看手册

image-20230818142847553

首先使能GPIOF的时钟

__HAL_RCC_GPIOF_CLK_ENABLE(); // 使能GPIOF时钟

创建GPIO操作句柄

GPIO_InitTypeDef GPIO_InitStruct;

复用PF0与PF1为串口的输入输出

GPIO复用功能表可以看手册中的端口复用功能列表

image-20230818143346801

image-20230818143425323

    // PF0复用为USART1_RX
    GPIO_InitStruct.Pin = GPIO_PIN_0;                  // PF1
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;            // 推挽输出
    GPIO_InitStruct.Pull = GPIO_PULLUP;                // 上拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 高速
    GPIO_InitStruct.Alternate = GPIO_AF8_USART1;       // 复用为USART1_RX
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

    // PF1复用为USART1_TX
    GPIO_InitStruct.Pin = GPIO_PIN_1;                  // PF1
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;            // 推挽输出
    GPIO_InitStruct.Pull = GPIO_PULLUP;                // 上拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 高速
    GPIO_InitStruct.Alternate = GPIO_AF8_USART1;       // 复用为USART1_TX
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

到这里串口中断与GPIO部分就初始化完成了,下面初始化DMA部分

初始化DMA

同样的步骤,与STM32基本无异

首先使能DMA1时钟

__HAL_RCC_DMA_CLK_ENABLE();

创建DMA操作句柄

DMA_HandleTypeDef hdma_usart1_rx; // DMA句柄

配置DMA通道,模式,方向等信息

hdma_usart1_rx.Instance = DMA1_Channel1;                       // DMA1通道1
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;          // 外设到内存 方向
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;              // 外设非增量模式
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;                  // 内存增量模式
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 外设数据宽度为8位
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;    // 内存数据宽度为8位
hdma_usart1_rx.Init.Mode = DMA_NORMAL;                         // 正常模式
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;         // 优先级为非常高

调用接口初始化DMA

HAL_DMA_Init(&hdma_usart1_rx);

这里要注意,不要忘记把DMA与串口进行关联,不然读不到数据

__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);                 // 关联串口1的hdmarx
HAL_DMA_ChannelMap(&hdma_usart1_rx, DMA_CHANNEL_MAP_USART1_RX); // DMA与UART关联

DMA初始化完成

编写串口中断处理函数

首先找到startup_air_dev.s汇编启动代码,找到里面的串口1中断函数名,如下图

image-20230818135414385

复制此名称,在air001xx_it.c中编写中断处理函数

这里要注意,在中断处理函数最后一定要加上清除溢出错误这部分(读SR与DR寄存器),不然会导致上电就产生一个硬错误中断(暂时不清楚为啥)

中断内尽量简洁,不要有复杂耗时操作,这里是置位标志位,然后在main函数中处理

void USART1_IRQHandler(void) // 串口1中断
{
  if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 判断是否为空闲中断
  {
    UART1_FLAG = 1;
    __HAL_UART_CLEAR_IDLEFLAG(&huart1);
  }
  HAL_UART_IRQHandler(&huart1);
  // 清除溢出错误
  __HAL_UART_CLEAR_OREFLAG(&huart1);
}

开启串口接收中断与DMA

初始化完成串口与DMA之后使能串口空闲中断,开启串口DMA接收

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);     // 开启串口1空闲中断
HAL_UART_Receive_DMA(&huart1, UART_BUF, RX_NUM); // 串口1接收DMA

这事如果有数据发送完成串口空闲,会触发串口空闲中断,中断中置位标志位,

在main函数while循环中判断标志位进行处理即可,先停止DMA接收然后处理完成后重新使能串口DMA接收

  while (1)
  {
    if (UART1_FLAG)
    {
      HAL_UART_DMAStop(&huart1);
      debug_print("%s", UART_BUF); // 打印串口接收到的数据
      APP_UART_Analysis();
      memset(UART_BUF, 0, sizeof(UART_BUF));
      HAL_UART_Receive_DMA(&huart1, UART_BUF, RX_NUM); // 串口1接收DMA
      UART1_FLAG = 0;
    }
}

END

QQ录屏20230818150853

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇