STM32单片机示例:使用定时器触发DMA

文章目录

  • 前言
  • 基础说明
  • 关键配置与代码
  • 示例链接

前言

单片机中使用定时器触发DMA是比较好用的一种操作,这里将对此做个示例说明。

基础说明

ST官方的例程中有一个 TIM_DMA 的例程,其功能是启用一个定时器,设置其中一路通道输出PWM,使用 TIM_CH 事件来触发DMA,然后用DMA搬运数据到 CCR 寄存器,从而来改变PWM的占空比。该示例是借鉴官方示例而来。

该示例演示通过 TIM_UP 请求来触发DMA搬运数据。本例中通过DMA从内存中搬运数据修改 GPIOx->BSRR 寄存器的值,从而实现修改GPIO口输出电平。使用该方式下可以实现同步控制一组GPIO口的输出,可以当作方波或是PWM输出等功能。除默认生成的代码,只在 main.c 文件添加几行手动编写的代码。本例中输出引脚为 PB0、PB1、PB2、PB3 。

关键配置与代码

这里只贴出关键的配置与代码,完整示例可以通过文后链接查看。

本示例中关键配置就是下图的通过 TIM_UP 请求来触发DMA了:
STM32单片机示例:使用定时器触发DMA_第1张图片

除了配置生成的代码,需要手动添加的代码没几行:

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM3_Init();

  // BSRR寄存器数据,高16位用于清除端口,低16位用于设置端口
  uint32_t buff[5] ={0x000F0000, 0x00000008, 0x00000004, 0x00000002, 0x00000001};

  // 以下步骤参考函数 HAL_TIM_Base_Start_DMA ,但该函数中外设地址是定时器的ARR寄存器,不符合我这里需求,所以根据该函数来编写下面代码
  HAL_DMA_Start(&hdma_tim3_up, (uint32_t)buff, (uint32_t)&GPIOB->BSRR, 5); // 设置并启动DMA
  __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE); // 使能定时器触发DMA
  HAL_TIM_Base_Start(&htim3); // 启动定时器

  while (1)
  {
  }
}



本示例演示结果可以通过逻辑分析仪方便的观察:
STM32单片机示例:使用定时器触发DMA_第2张图片

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本实例为仓库中 TIM_UP_DMA_HAL_H750

你可能感兴趣的:(RTOS与单片机相关,stm32,嵌入式硬件,单片机,dma,定时器)