赞
踩
目录
STM32F103控制器内部的可编程定时器从TIME1—TIME8颗分为基本定时器、通用定时器和高级定时器。
TIM6和TIM7为基本定时器,通用的16位计数器,产生DAC触发信号,只有向上计数形式。 TIM2、TIM3、TIM4和TIM5为通用定时器,是STM32的4个独立的16位通用定时器,具有定时、测量输入信号的脉冲长度(输入捕获)、输出所需波形(输出比较、产生PWM、单脉冲输出等)等功能。
TIM1和TIM8为高级定时器,具有通用定时功能,功能相较于其它两个更为强大。
计数:脉冲计数,使用使用微控制器内部的外部时钟(PCLK)来计数,是对固定周期的脉冲信号计数。
定时:时间控制,通过对微控制器内部的时钟脉冲进行计数实现定时功能。
输入捕获:对输入信号进行捕获,实现对脉冲的频率测量,可用于对外部输入信号脉冲宽度的测量,比如测量电机转速。
输出比较:将计数器计数值和设定值进行比较,根据比较结果输出不同电平,用于控制输出波形,比如直流电机的调速。
PWM(Pulse Width Modulation,脉冲宽度调制)是一种利用脉冲宽度即占空比实现对模拟信号进行控制的技术,即是对模拟信号电平进行数字表示的方法。
占空比(Duty Cycle),是指在一个周期内,高电平时间占整个信号周期的百分比,即高电平时间与周期的比值:占空比=Tp/T。
STM32的定时器除了TIM6和TIM7,其他定时器都可以用来产生PWM输出,高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出,通用定时器能同时产生多达4路的PWM输出。
STM32中每个定时器有4个输入通道:TIMx_CH1~TIMx_CH4,每个通道对应1个捕获/比较寄存器TIMx_CRRx,将寄存器值和计数器值相比较,通过比较结果输出高低电平,从而得到PWM信号,脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。
在PWM的一个周期内,定时器从0开始向上计数,在0-t1时间段,定时器计数器TIMx_CNT值小于TIMx_CCRx值,输出低电平;
在t1-t2时间段,定时器计数器TIMx_CNT值大于TIMx_CCRx值,输出高电平;
当定时器计数器的值TIMx_CNT达到ARR时,定时器溢出,重新从0开始向上计数,如此循环。
本次实例都是使用的HAL库方法,需要使用到CubeMX和Keil两个软件。
首先打开CubeMX,新建项目,设置RCC和SYS。
然后设置GPIO输出(这里用的PA7引脚)
接着设置定时器,这里使用TIM2进行实验,选择内部时钟,同时将arr设为4999,psc设为6399。
最后设置Clock Configuration。
这样就能计算出定时器溢出时间,根据Tout=((arr+1)*(psc+1))/Tclk,即((4999+1)×(6399+1))/(16μs)得到2s。
ARR(TIM_Period):自动重装载值,是定时器溢出前的计数值。
PSC(TIM_Prescaler):预分频值,是用来降低定时器时钟频率的参数。
Tclk:定时器的输入时钟频率(单位Mhz),通常为系统时钟频率或者定时器外部时钟频率(STM32f103c8t6,系统主频72Mhz)。
Tout:定时器溢出时间(单位us)。一定要注意这个单位是us。
接下来就可以生成代码了。为项目命名,同时选择MDK-ARM,以便在Kile进行实验。
进入Kile后,找到main.c文件,在如下位置编写代码。
- /* USER CODE BEGIN 2 */
- HAL_TIM_Base_Start_IT(&htim2);//新增代码
- /* USER CODE END 2 */
- /* USER CODE BEGIN 4 */
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance == htim2.Instance)
- {
- HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
- }
- }
- /* USER CODE END 4 */
接着完成编译,在STM32开发板上进行测试。
基础配置与上述差不多,这里主要对PWM的设置进行叙述。首先是定时器的设置。
然后是Clock Configuration的设置。
接着按实例1的操作生成代码,并在如下位置编写代码。
- /* USER CODE BEGIN 1 */
- uint16_t pwmVal=0; //PWM占空比
- uint8_t dir=1;
- /* USER CODE END 1 */
- /* USER CODE BEGIN 2 */
- HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
- /* USER CODE END 2 */
- while (1)
- {
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
- while (pwmVal< 500)
- {
- pwmVal++;
- __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比
- // TIM3->CCR1 = pwmVal; 与上方相同
- HAL_Delay(1);
- }
- while (pwmVal)
- {
- pwmVal--;
- __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //修改比较值,修改占空比
- // TIM3->CCR1 = pwmVal; 与上方相同
- HAL_Delay(1);
- }
- HAL_Delay(200);
-
- }
- /* USER CODE END 3 */

完成编译后便能看到实验现象。
然后可以在Kile中观察波形。
通过这次对定时器的练习,我认识到了定时器的基本功能,以及利用定时器完成点灯和PWM的一些基本操作,但对于定时本身的控制还需要花更多时间去理解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。