在之前的帖子中,尝试使用定时器与DMA更新输出频率的方法,这篇文章分享一个定时器输出四路PWM的方法及注意事项;
学习目标:配置time外设生成四个不同的频率的四个不同频率的脉冲频率;
TIM2 频率设置为 SystemCoreClock,目标是获得 1 MHz 的 TIM2 计数器时钟,计算方法可以参考之前帖子,这里就不做过多的介绍了:
NUCLEO-U083RC学习历程13-基本定时器TIME6调试https://forum.eepw.com.cn/thread/388726/1
这里简单分享一下,PWM输出功能调试,需要明确PWM的计算的几个寄存器;
通用定时器也能同时产生多达 4路的 PWM 输出。
3 个寄存器,来控制 PWM 的。
捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2控制 CH3 和 4。
TIMx_CCER,该寄存器控制着各个输入输出通道的开关。 CC1E 位,该位是输入/捕获 1 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。
TIMx_CCR1到4),该寄存器总共有 4 个,对应 4 个通道 CH1到4。
输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。
一:STM32 cube软件配置:
对于 STM32U0xx 器件,SystemCoreClock 设置为 48 MHz。
TIM2 CCR1 寄存器值等于 625:CC1 更新速率 = TIM2 计数器时钟 / CCR1_Val = 1600 Hz,因此 TIM2 通道 1 生成频率等于 800 Hz 的周期信号。
TIM2 CCR2 寄存器值等于 1250:CC2 更新速率 = TIM2 计数器时钟 / CCR2_Val = 800 Hz,因此 TIM2 通道 2 生成频率等于 400 Hz 的周期信号。
TIM2 CCR3 寄存器值等于 2500:CC3 更新速率 = TIM2 计数器时钟 / CCR3_Val = 400 Hz,因此 TIM2 通道 3 生成频率等于 200 Hz 的周期信号。
TIM2 CCR4 寄存器值等于 5000:CC4 更新速率 = TIM2 计数器时钟 / CCR4_Val = 200 Hz,因此 TIM2 通道 4 生成频率等于 100 Hz 的周期信号。
二:软件代码分享:
2.1定时器2配置参数:
/** * @brief TIM2 Initialization Function * @param None * @retval None */ static void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = PRESCALER_VALUE; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_OC_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; sConfigOC.Pulse = PULSE1_VALUE; sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = PULSE2_VALUE; if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = PULSE3_VALUE; if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = PULSE4_VALUE; if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ HAL_TIM_MspPostInit(&htim2); }
2.2 使能定时器2 4路PWM输出功能:
/*## Start signals generation #######################################*/ /* Start channel 1 in Output compare mode */ if(HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_1) != HAL_OK) { /* Starting Error */ Error_Handler(); } /* Start channel 2 in Output compare mode */ if(HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_2) != HAL_OK) { /* Starting Error */ Error_Handler(); } /* Start channel 3 in Output compare mode */ if(HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3) != HAL_OK) { /* Starting Error */ Error_Handler(); } /* Start channel 4 in Output compare mode */ if(HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_4) != HAL_OK) { /* Starting Error */ Error_Handler(); }
HAL TIM OC stant IT和HAL TIM IC start IT分别是用来启动定时器的输出比较中断和输入捕获中断的函数。
HAL TIM OC Star IT函数用于启动定时器的输出比较中断,并且指定了使用的定时器通道。在启动后,当定时器的计数器值达到比较值时,会触发输出比较中断,并执行相应的中断处理函数。
HAL TIM IC Start IT函数用于启动定时器的输入捕获中断,并且同样指定了使用的定时器通道。在启动后,当外部信号触发定时器通道的输入捕获事件时,会触发输入捕获中断,并执行相应的中断处理函数。
需要注意的是,以上函数需要在初始化定时器和相关通道后调用,且需要先使能对应的定时器和通道才能正常工作。
实物测试脉冲图片:
以通道1 ;800hz 脉冲介绍: