文章目录
- 前言
- 基础说明
- 关键配置与代码
- 示例链接
前言
单片机中使用定时器触发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了:
除了配置生成的代码,需要手动添加的代码没几行:
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)
{
}
}
本示例演示结果可以通过逻辑分析仪方便的观察:
示例链接
仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples
本实例为仓库中 TIM_UP_DMA_HAL_H750
。