一、实验目的
使用两个TIM时钟分别发送不同频率的脉冲,并使用从定时器对两路脉冲分别计数。
二、实验内容
2.1 引脚配置
初始化配置:三件套
配置TIM1时钟通道3作为第一路脉冲发送,配置TIM2时钟通道1作为第二路脉冲发送。
TIM1的Clock Source(时钟源)为内部时钟,频率为168MHZ, Prescaler(预分频系数):即PSC寄存器值设为168-1,计数脉冲频率:168MHz÷168=1MHz,即每秒产生1百万个计数信号,每个计数脉冲的时长:1秒/1M=1us,Counter Period (计数周期): 即ARR寄存器值,多少个计数脉冲作为1个波形周期。
TIM2的Clock Source(时钟源)为内部时钟,频率为84MHZ。
Repetition Counter(重复计数器): 简单地理解,多少个周期才触发1次中断;
auto-reload preload (自动重载值的预装载): 当改变周期值ARR时,是否等到下一个更新事件再写入数值,使得数值的更改不影响执行中的波形。
注:
- TIM1、8、9、10、11的时钟频率是168MHz;
- 其它TIM的时钟频率是84MHz。
设置TRGO(Trigger Outpu)参数,Enable 主从模式,Update Event 作为触发事件。
配置TIM4作为TIM1的从定时器,计数脉冲 ,配置TIM8作为TIM2的从定时器,计数脉冲 。
配置从模式和触发源 ,打开中断。
2.2 发送脉冲并计数程序
设置ARR的值来设定发送脉冲的频率,1M/(ARR+1) = fpwm;设置CCR的值为(ARR+1) *0.5来设定发送脉冲的占空比为50%。
uint16_t pwmVal1=500; //PWM???
uint16_t ARR1=1000-1; //PWM???
uint16_t pwmVal2=500; //PWM???
uint16_t ARR2=1000-1; //PWM???
void set_pwm_param(uint16_t f1,uint16_t f2)
{
ARR1 = 1000000/f1 - 1;
pwmVal1 = (ARR1+1)*0.5;
ARR2 = 1000000/f2 - 1;
pwmVal2 = (ARR2+1)*0.5;
TIM1->CCR3 = pwmVal1;
TIM1->ARR = ARR1;
TIM2->CCR1 = pwmVal2;
TIM2->ARR = ARR2;
}
调用函数设定两路脉冲的频率,并开启脉冲发送。 开启TIM4和TIM8的中断,并设定两个定时器的自动重装载计数值作为输出脉冲的个数。
set_pwm_param(5000,10000); //set pwm1 frequence and pwm2 frequence
__HAL_TIM_SET_AUTORELOAD(&htim4,1000-1); //ÉèÖÃÒªÊä³öµÄPWMÂö³åÊý1000¸ö
__HAL_TIM_SET_AUTORELOAD(&htim8,5000-1); //ÉèÖÃÒªÊä³öµÄPWMÂö³åÊý1000¸ö
HAL_TIM_Base_Start_IT(&htim4); //Æô¶¯´Ó¶¨Ê±Æ÷
HAL_TIM_Base_Start_IT(&htim8); //Æô¶¯´Ó¶¨Ê±Æ÷
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
在中断回调函数里面编写程序,当两个计数脉冲的时钟触发更新中断,清除定时器中断标志位并停止主定时器的脉冲输出。这样使得主定时器输出给定数目的脉冲。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_CC2) != RESET) //????????
{
__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC2); //??????
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3); //??????
HAL_TIM_Base_Stop_IT(&htim4); //??????
// HAL_GPIO_WritePin(GPIOE, EN1_Pin, GPIO_PIN_RESET);
}
if(__HAL_TIM_GET_FLAG(&htim8, TIM_FLAG_CC2) != RESET) //????????
{
__HAL_TIM_CLEAR_FLAG(&htim8, TIM_FLAG_CC2); //??????
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1); //??????
HAL_TIM_Base_Stop_IT(&htim8); //??????
// HAL_GPIO_WritePin(GPIOE, EN12_Pin, GPIO_PIN_RESET);
}
}