你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 配置DMA不定长接收

[复制链接]
STMCU小助手 发布时间:2022-9-3 19:05
导语
关键词STM32 DMA
本次教程采用的是stm32f401ccu6 + HAL库V1.8.1(F1系列芯片兼容)

CubeMX配置
微信图片_20220903190456.png
微信图片_20220903190454.png
微信图片_20220903190451.png
微信图片_20220903190448.png
最后点击GENERATE CODE生成代码

代码编写
测试串口功能(确定无误可跳过)
  1. /* USER CODE BEGIN Header */
  2. #include <stdio.h>    //C语言标准输入输出库
  3. /* USER CODE END Header */
  4. ...
  5. /* USER CODE BEGIN 1 */
  6. int fputc(int ch, FILE *f){
  7. uint8_t temp[1] = {ch};
  8. HAL_UART_Transmit(&huart1, temp, 1, 0xffff); //注意这里的&huart1更改为你使用的串口&huartx
  9. return ch;
  10. }

  11. int fgetc(FILE * f)
  12. {
  13.   uint8_t ch = 0;
  14.   HAL_UART_Receive(&huart1,&ch, 1, 0xffff); //同理
  15.   return ch;
  16. }
复制代码

  • 在main.c添加头文件#include <stdio.h>
  • 打开KEIL菜单栏的魔术棒(Options for Target...)
  • 在Target栏下勾选Use MicoLIB
  • 在Debug - Setting - Flash Download栏下勾选Rest and Run(否则需要手动复位单片机)
  • 在main.h中写上测试代码printf("nihao\r\n")
  • 编译下载后,打开串口助手可以看到测试信息,至此串口配置完成。

微信图片_20220903190444.png


微信图片_20220903190441.png

DMA测试及不定长DMA的配置DMA发送测试
  • 在usart.c中添加如下代码:

  1. void DMA_USART_Send(uint8_t *buf, uint8_t len)
  2. {

  3.     if(HAL_UART_Transmit_DMA(&huart1, buf, len) != HAL_OK)
  4.     {
  5.         Error_Handler();
  6.     }
  7. }

  8. void DMA_USART_Read(uint8_t *Data, uint8_t len)
  9. {
  10.     HAL_UART_Receive_DMA(&huart1, Data, len);
  11. }
复制代码


  • 在main.c相关位置添加代码

  1. DMA_USART_Send((uint8_t*)"Hello\r\n",sizeof("Hello\r\n"));
复制代码

  • 编译运行后可在串口助手观察到输出。




DMA不定长接收
  • 在usart.c中添加全局定义uint8_t rx_buffer[100] = {0};其中“100”可修改,其值为最大的单次接收字符个数。
    (定义可放在别的文件,使用时包含该文件或者使用extern关键字)

  • 在usart.c中打开串口的空闲中断(IDLE中断)、找到串口初始化函数
    void MX_USARTx_UART_Init(void),其中,X为使用的串口号

相关代码如下:
  1. /* USER CODE BEGIN USART1_Init 2 */
  2.     __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
  3.     HAL_UART_Receive_DMA(&huart1,rx_buffer,100); //100对应了前面定义的数组大小
  4.   /* USER CODE END USART1_Init 2 */
复制代码

注意:此处HAL库较低版本没有用户自定义代码的区域,可自行更新HAL库版本或将代码添加到别处(否则cubemx更新代码时会丢失)

  • 在stm32f*xx_it.c开头中添加extern uint8_t rx_buffer[];引用(其中*为使用的芯片系列,f1,f4云云)。并把前面修改的usart.h包含进来。

  1. // in stm32f*xx_it.c

  2. /* USER CODE BEGIN Header */

  3.     #include "usart.h"
  4.     #include <stdio.h>

  5. /* USER CODE END Header */
复制代码


  • 找到函数void USARTx_IRQHandler(void)在函数
    HAL_UART_IRQHandler(&huartx);添加不定长接收逻辑代码(此处以回显功能为例):

  1. uint16_t tmp = 0;
  2.     uint16_t Rx_Len = 0;
  3.    
  4.     if(__HAL_UART_GET_FLAG(uartHandle, UART_FLAG_IDLE) != RESET)    //是否进入空闲中断
  5.     {
  6.         __HAL_UART_CLEAR_IDLEFLAG(uartHandle); //清除空闲中断标志位
  7.         HAL_UART_DMAStop(uartHandle);       //此时信息已保存至rx_buffer,暂时停止DMA接收   

  8.             //... 在此添加解码程序或其他自定义代码,此处以接收信息后回显代码为例
  9.             tmp = __HAL_DMA_GET_COUNTER(hudma); //读取计数器后自动清除空闲中断,也可以直接读寄存器      
  10.             Rx_Len = BUFFER_SIZE - tmp;
  11.             DMA_USART_Send(rx_buffer, Rx_Len);
  12.             Rx_Len = 0;
  13.             //
  14.         HAL_UART_Receive_DMA(uartHandle,rx_buffer,BUFFER_SIZE);     //重新打开DMA接收
复制代码


  • 此时连接单片机,给单片机发送字符串,可以看到单片机回传相同的信息。


微信图片_20220903190421.png

转载自:hardware

微信图片_20220903190430.png
微信图片_20220903190427.png
收藏 评论0 发布时间:2022-9-3 19:05

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版