stm32g4 pwm+dma HAL库
时间: 2025-06-29 10:11:12 浏览: 15
### STM32G4 PWM与DMA配合HAL库开发
对于STM32G4系列微控制器,在使用PWM功能时确实可以不涉及NVIC中断配置,但如果要实现更复杂的功能比如通过DMA传输数据,则需要额外的设置。当利用DMA来更新PWM通道的捕获/比较寄存器(CCRx),可以在不需要CPU干预的情况下动态改变占空比。
下面是一个简单的例子展示如何初始化TIM1定时器并启用其PWM输出以及配置DMA用于周期性地刷新CCR值:
#### 初始化硬件资源
```c
// 定义全局变量保存波形参数表地址和长度
uint16_t WaveformTable[] = { /* 波形数值 */ };
uint16_t WaveformLength;
void MX_TIM1_Init(void)
{
TIM_HandleTypeDef htim1;
TIM_OC_InitTypeDef sConfigOC;
// 配置定时器基本属性...
// 设置预分频系数(PSC)为17000-1, 自动重载计数器(ARR)为100-1
htim1.Instance = TIM1;
htim1.Init.Prescaler = 17000 - 1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 100 - 1;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim1);
// 配置PWM模式1 (边沿对齐), 初始CCR=50
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 50;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
}
```
#### 启用DMA服务函数
为了能够持续不断地向指定的CCR寄存器写入新的脉宽值,还需要创建一个循环模式下的DMA流,并将其链接到相应的定时器外设上。
```c
static void MX_DMA_Init(void)
{
__HAL_RCC_DMAMUX_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_tim1_ch1.Instance = DMA1_Channel1;
hdma_tim1_ch1.Init.Request = DMAMUX_REQ_GEN1;
hdma_tim1_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim1_ch1.InitPeriphInc = DMA_PINC_DISABLE;
hdma_tim1_ch1.InitMemInc = DMA_MINC_ENABLE;
hdma_tim1_ch1.InitPeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_tim1_ch1.InitMemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_tim1_ch1.Init.Mode = DMA_CIRCULAR;
hdma_tim1_ch1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_tim1_ch1) != HAL_OK){
Error_Handler();
}
__HAL_LINKDMA(htim1.hdmar[], hdma_tim1_ch1); // 将DMA实例关联至HTIM句柄中的成员变量
// 开启DMA请求映射单元(DMAMUX)
HAL_DMAMUX_RequestGenConfig(hdmamux_req_gen1.Instance,
DMAMUX_REQUESTGENCFG_REQ_ID_1,
DMAMUX_REQUESTGENCFG_POL_RISING_EDGE,
DMAMUX_REQUESTGENCFG_BURST_INC_SED);
}
int main(void)
{
...
MX_TIM1_Init(); // 调用上述定义的方法完成定时器初始化工作
MX_DMA_Init(); // 进一步准备DMA环境以便后续操作
...
// 建立从内存(WaveformTable[])到外设(Timer CCR Register)的数据路径
HAL_TIMEx_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)WaveformTable, WaveformLength);
while (1){}
}
```
此代码片段展示了基于STM32CubeMX生成的基础框架之上扩展出来的具体应用逻辑——即怎样借助于DMA机制高效地控制多个LED灯亮度变化或其他类似场景下连续调节信号电平的任务[^1]。
阅读全文
相关推荐


















