本次实验使用的NUCLEO-G071RB开发板由https://www.stmcu.com.cn/index.p ... /261/layout/product提供,更多相关资讯请进入查询。本次实验是利用NUCLEO-G071RB开发板的通用定时器TIM2模块四个通道输出PWM,TIM2_CH1被配置在PA5引脚,输出占空比可变的PWM驱动LD4产生呼吸灯效果;另外的TIM2_CH2、TIM2_CH3、TIM2_CH4被分配至PA1、PA2、PA3引脚,输出占空比为25%、50%、75%的PWM波型,并通过逻辑分析仪测试验证。
一、实验资源
1、NUCLEO-G071RB开发板;
2、Keil v5.25.2.0;
3、STM32CubeMX v5.0.1;
4、逻辑分析仪;
二、实验过程1、资源简介
在STM32G0071RBT6中共有6个通用定时器,包括TIM2, TIM3, TIM14, TIM15, TIM16, TIM17。其中TIM2是通用带有32位可重加载向上/向下计数定时器,而其它的均为16位。这些定时器较之基本定时器(TIM6、TIM7)无论是在功能及性能都强大了许多。利用其输入捕获功能可以测量输入信号脉冲宽度及频率,或者利用输出比较和PWM功能输出波型。这些功能使得定时器有着非常广泛的用途。
2、工程配置
这里依然是采用STM32CubeMX配置并生成工程文件,之所以选择TIM2是因为LD4接在了PA5引脚,PA5可复用为TIM2_CH1,这样就可以直接利用LD4测试PWM输出了,其它三个PWM输出通道也被配置在了GPIOA的PA1、PA2、PA3;时钟直接选用HSI;TIM2向上计数;PWM输出极性为高,其它的一些配置直接按默认了,具体的参数准备在工程文件调试时根据情况再修改。
3、软件实现
从通用计时器框架图中可以看出,TIM2的计数时钟来自于内部时钟,TPCLK时钟为16MHz经预分频器(CK_PSC)分频(16MHz/160=100KHz)后为TIM2提供计数脉冲。TIM2_CNT以此频率开始向上计数,当计数值小于CCRx期间TIM2_CHx输出高电平;当计数值大于CCRx时TIM2_CHx输出低电平;当TIM2_CNT等于ARR重装载值时TIM2_CNT回零重新开始计数。这些活儿一直重复干,相应PWM输出通道上就产生了频率固定的PWM波型。PWM的频率及占空比均可以通过软件进行改变,改变ARR的值即可改变频率;改变CCRx可以改变占空比。LD4产生呼吸灯效果即是在不同的时间点上在TIM2_CCR1装载变化的值所产生的效果。下面是TIM2的初始化函数,根据自己的理解加了注释,不一定都正确:
- TIM_HandleTypeDef htim2;
- /* TIM2 init function */
- void MX_TIM2_Init(void)
- {
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- TIM_OC_InitTypeDef sConfigOC = {0};
- /*
- TIM2时钟=TPCLK=16000000Hz,经预分频器(Prescaler)16000000/(159+1)=100KHz;
- TIM2计数频率为100KHz,PWM频率=100000/1000(Period)=100Hz;
- */
- htim2.Instance = TIM2;
- htim2.Init.Prescaler = 159; //定时器预分频PSC,
- htim2.Init.CounterMode = TIM_COUNTERMODE_UP; //向上计数模式
- htim2.Init.Period = 1000; //自动重装载值ARR
- htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) //初始化PWM
- {
- 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_PWM1; //模式选择PWM1
- sConfigOC.Pulse = 0; //输出比较值,初始占空比为0
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; //输出比较极性为高
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)//配置TIM2通道1
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
- {
- Error_Handler();
- }
- HAL_TIM_MspPostInit(&htim2);
- }
复制代码
这里出现了一个问题,原打算在PA3引脚配置TIM2_CH4输出通道,但调试时一直没有输出,后来改在了PC7引脚就有输出了。另外PB11也可以配置成TIM2_CH4,但还没有尝试。
下面是主函数的片断,在这里别忘了打开PWM输出通道:
- /* USER CODE BEGIN 2 */
- HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);//开启TIM2PWM通道1
- HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);//开启TIM2PWM通道2
- HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);//开启TIM2PWM通道3
- HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);//开启TIM2PWM通道4
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- TIM2->CCR2 = 250;
- TIM2->CCR3 = 500;
- TIM2->CCR4 = 750;
- for(pwm_val=0; pwm_val<1000; pwm_val++)
- {
- HAL_Delay(1);
- TIM2->CCR1 = pwm_val;
-
- }
- for(pwm_val=1000; pwm_val>0; pwm_val--)
- {
- HAL_Delay(1);
- TIM2->CCR1 = pwm_val;
- }
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- }
复制代码
三、实验结果
四、实验总结
通过本次实验对于通用定时器比较输出有了更加深入地认识和了解,但对于PA3配置为TIM2_CH4没有输出的问题比较疑惑,还没有找到具体的原因,请朋友们指教。
附件:工程文件
TIM2_PWM.rar
(4.56 MB, 下载次数: 6)
此内容由EEWORLD论坛网友lising原创,如需转载或用于商业用途需征得作者同意并注明出处