使用定时器的输出比较模式实现:当定时器计数值与比较寄存器值相等时,电平翻转
使用定时器3的通道1,2进行实验
打开全局中断
在tim.c中加入上面代码,f1和f2用于修改通道频率,duty_cycle用于修改通道占空比。arr的自动装载值设置为最大65535,相当于计数器从0开始计数,直到65535才结束,分频系数为72,计算器计数一次为1us;对通道1:f1=100,即一个脉冲周期为100us,则频率为10khz
中断函数如下:
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
uint16_t OC_Count = 0;
if(htim->Instance == TIM3)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
OC_Count=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);//获取定时器计数值
if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6))
{
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count +f1*duty_cycle1);
}
else
{
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count + f1*(1-duty_cycle1));
}
}
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
OC_Count=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_2);
if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7))
{
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + f2*duty_cycle2);
}
else
{
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + f2*(1-duty_cycle2));
}
}
}
}
定时器一直都在计数,因此每次设置比较值时,都要用__HAL_TIM_GET_COMPARE获取计数值。对通道1:当其输出为低电平时,设置低电平翻转时间OC_Count +f1duty_cycle1;OC_Count为当前计数值,OC_Count +f1duty_cycle1为翻转时计数器的值,等待时间为f1duty_cycle1=50个计数值,即为50us。相同,当其输出为高电平时,设置高电平持续时间OC_Count + f1(1-duty_cycle1)。高低电平的总时间即为一个脉冲的周期duty_cycle1。
输出波形如下:
一个通道频率为10khz,另外一个通道为5khz,和预期相同