stm32定时器
1.定时器中断
-
1.关于定时器中断:记得使用中断时启动对应定时器的中断(此处使用了TIM4)
/* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim4);//Starts the TIM Base generation in interrupt mode. /* USER CODE END 2 */
-
2.定时器的中断不需要手动清理标志位,回调函数已经帮你做好。
-
3.注意回调函数要对定时器的句柄进行判断,看是哪一个定时器发生了中断。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance==htim4.Instance){ cnt++; } }
2.PWM
-
使用高级定时器输出互补PWM时需要手动启动各通道(包括互补通道)的PWM输出。
(【注】:PWM模式为输出比较模式的特殊形式,pwm模式在对应定时器上的四个通道产生的频率是同步的(即相同的),而输出比较模式在四个通道可以产生的频率不同。)
/* 启动通道PWM输出 */ HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 注意:只启动了TIM1 CH1 没有启动TIM1 CH1N HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3); // HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); /* 启动定时器互补通道PWM输出 */ HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); // 注意:只启动了TIM1 CH1N 没有启动TIM1 CH1 HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2); HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3); //另:PWM模式可以通过htim1.Instance->CCR4 = i;修改CCR4(ch4的CCR)寄存器的值,从而实现呼吸灯的效果。
-
使用定时器输出PWM时(普通的输出比较模式),需要使用
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
使能某个通道的PWM。__HAL_TIM_SET_COMPARE() // 设置比较寄存器CCRx,一般是用于PWM输出时控制PWM占空比(当计数器CNT的值与CCR的值相等的时候,输出参考信号OCxREF的信号的极性就会改变) //也可以直接控制CCR寄存器。htim1.Instance->CCR4 = i
3.输出比较和PWM模式的对比
-
输出比较模式,可以输出PWM波,而且一个通用定时器的4个通道的PWM波可以频率、占空比互不干扰,完全独立。
而PWM模式产生的波在对应定时器上的四个通道频率是一致的,只有占空比是独立的。 -
PWM是特殊的比较输出模式,可以调节频率周期波长(ARR)、占空比(CCR);比较输出是可以输出各种类型的波形,但是占空比固定50%。
-
两种模式的区别是 CCRx在不同模式下的作用是不一样的:
- 输出比较模式下,CCRx控制的是初相位.即初相位可调。
- PWM模式下,CCRx控制的是高电平的计数周期.初相位不可调,脉宽可调
-
另一个博客:(这个比较清楚了)
- TIM_OCMode_Timing 输出比较时间模式 (输出引脚冻结无效)
- TIM_OCMode_Active 输出比较主动模式 (匹配时设置输出引脚为有效电平,当计数值为比较/捕获寄存器值相同时,强制输出为高电平)
- TIM_OCMode_Inactive 输出比较非主动模式 (匹配时设置输出引脚为无效电平,当计数值为比较/捕获寄存器值相同时,强制输出为低电平)
- TIM_OCMode_Toggle 输出比较翻转触发模式(当计数值与比较/捕获寄存器值相同时,翻转输出引脚的电平)
- TIM_OCMode_PWM1 向上计数时,当TIMx_CNT < TIMx_CCR*时,输出电平有效,否则为无效
向下计数时,当TIMx_CNT > TIMx_CCR*时,输出电平无效,否则为有效 - TIM_OCMode_PWM2 与PWM1模式相反
PWM模式就不说了,通过函数设置频率与占空比。
其余几个所说的“当计数值为比较/捕获寄存器值相同时” 即CCRX=CNT;这时候会触发后面所说的事件,而TIM_OCMode_Active与TIM_OCMode_Inactive
仅触发一次,所以之后就会出现一直为高电平或者低电平。TIM_OCMode_Toggle会每次都翻转,所以也形成一个PWM,而占空比只会是百分之五十,
周期为参数period的两倍,频率为1/2,因为一个period只翻转一次!翻转是在CCRX=CNT时翻转,并不是CNT=ARR(ARR=TIM_TimeBaseStructure.TIM_Period)。
4.输入捕获功能
- 重要函数
- uint32_t HAL_TIM_ReadCapturedValue (TIM_HandleTypeDef *htim, uint32_t Channel)
- Function description:Read the captured value from Capture Compare unit.
- Parameters:
- htim: : TIM handle.
- Channel: TIM Channels to be enabled This parameter can be one of the following values:
- TIM_CHANNEL_1 : TIM Channel 1 selected
- TIM_CHANNEL_2 : TIM Channel 2 selected
- TIM_CHANNEL_3 : TIM Channel 3 selected
- TIM_CHANNEL_4 : TIM Channel 4 selected
- __HAL_TIM_GET_COUNTER(&htimx)
- Function description: Gets the TIM Counter Register value on runtime.
- Parameters: __HANDLE__: TIM handle.
- 注意:CCR寄存器是 捕获/比较寄存器。输出比较时存放要比较的计数值;输入捕获时用来所存捕获到目标信号时计数器的值
CNT寄存器是 计数器计数值(一直在递增或者递减)。
- 这两个函数的区别:一个读取CCR寄存器,一个读取CNT寄存器。
5.定时器编码器模式
-
配置很简单
-
三行代码实现编码器读数
uint16_t cnt = 0;
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
cnt = __HAL_TIM_GET_COUNTER(&htim4);
- 注意你购买的编码器原理图
- 我用的是NPN开路集电极输出,需要通过电阻外接电源。
- 我用的是NPN开路集电极输出,需要通过电阻外接电源。