STM32 DMA驱动实现单个GPIO口控制
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管脚配置为输出管脚,可以通过示波器或者逻辑分析仪观察引脚输出。
三、修改代码
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 */
三、下载验证
作者:weixin_45518952