STM32 : DMA 驱动 单个GPIO口

本文介绍了如何利用STM32F103RCT6的DMA功能通过BSRR寄存器驱动单个GPIO口,包括GPIOx_ODR与GPIOx_BSRR的工作原理,STM32CubeMX的配置步骤,以及如何修改代码以实现DMA循环模式并验证其功能。
摘要由CSDN通过智能技术生成

STM32 : DMA 驱动 单个GPIO口


前言

最近有需求要使用DMA驱动单个GPIO口实现功能,前辈的文章基本上都是用DMA向ODR寄存器搬运数据驱动一组GPIO,后面自己查找资料发现可以通过向BSRR寄存器写入数据改变特定GPIO口的电平实现翻转。主控芯片为 STM32F103RCT6。


一、GPIOx_ODR与GPIOx_BSRR介绍

在这里插入图片描述
在这里插入图片描述
由上图可知,当我们要将某个GPIO置高电平时,只需要将GPIOx_BSRR低16位中对应的寄存器置1,其它位为0即可,如要设置PB0为高,GPIOB->BSRR=0x00000001;要置低电平时高16位中对应的寄存器置1,其它位为0,如要设置PB0为低,GPIOB->BSRR=0x00010000。这样只会修改我们需要的GPIO对其他GPIO无影响

二、STM32CubeMX 配置

1.Clock Configuration

在这里插入图片描述

2.SYS

在这里插入图片描述

3.RCC

外部高速时钟。
在这里插入图片描述

4.DMA

通道根据具体要求选择,我选择 DMA1 Channel 1,传输方向选择 MEMTOMEM ,通道优先级根据实际使用要求定,我选择低。使能源地址增加,传输模式这里只能选择为 Normal,如果需要使用循环模式后续可在代码中修改。通过寄存器介绍可知BSRR寄存器只能以字(16位)的形式操作,数据宽度选择 Word
在这里插入图片描述

5.GPIO

将PB0管脚配置为输出管脚,可以通过示波器或者逻辑分析仪观察引脚输出。![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bb2fafdf4ba549cfb9c683652c335d9b.png

三、修改代码

1.修改DMA配置

STM32CubeMX 中 DMA 只能选择 Normal 模式,所有需要我们手动将 void MX_DMA_Init(void)函数中DMA模式由 DMA_NORMAL 更改为 DMA_CIRCULAR 模式:

/**
  * Enable DMA controller clock
  * Configure DMA for memory to memory transfers
  *   hdma_memtomem_dma1_channel2
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* Configure DMA request hdma_memtomem_dma1_channel2 on DMA1_Channel2 */
  hdma_memtomem_dma1_channel2.Instance = DMA1_Channel2;
  hdma_memtomem_dma1_channel2.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hdma_memtomem_dma1_channel2.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_memtomem_dma1_channel2.Init.MemInc = DMA_MINC_DISABLE;
  hdma_memtomem_dma1_channel2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_memtomem_dma1_channel2.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  hdma_memtomem_dma1_channel2.Init.Mode = DMA_CIRCULAR;
  hdma_memtomem_dma1_channel2.Init.Priority = DMA_PRIORITY_HIGH;
  if (HAL_DMA_Init(&hdma_memtomem_dma1_channel2) != HAL_OK)
  {
    Error_Handler( );
  }
}

2.定义 DMA 数据区


/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t DMA_buff[8] = {0x00000001, 0x00000001, 0x00000001, 0x00000001,\
                        0x00010000, 0x00010000,0x00010000, 0x00010000};

/* USER CODE END 0 */

2.启动 DMA 传输

/* USER CODE BEGIN 2 */
HAL_DMA_Start(&hdma_memtomem_dma1_channel1, (uint32_t)(dma_buff), (uint32_t)(&GPIOB->BSRR), sizeof(dma_buff)/sizeof(dma_buff[0]));
/* USER CODE END 2 */

三、下载验证

在这里插入图片描述

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值