1.输出比较
首先配置所需要输出PWM的频率,比如我需要输出频率为25KHz的PWM频率,选择定时器2
生成项目之后,可通过调用函数,产生设定的占空比波形,下面的代码说明可产生占空比为50的PWM波形。
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,50);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
2.输入捕获
选用定时器3进行输入捕获,进行配置。
需要计算输入波形的高电平时间和低电平时间,可根据高低电平时间计算输入波形的频率。
//输入捕获中断
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_3);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_4);
在main函数中开启中断。
定义保存数据的变量。
uint16_t ccr1_cnt = 0; /* 发生第一次下升沿捕获时CCR1的值 */
uint16_t ccr2_cnt = 0; /* 发生第二次上升沿捕获时CCR1的值 */
uint16_t Period_cnt = 0; /* 发生计数器溢出事件的次数(过渡用) */
uint16_t Period_cnt1 =0; /* 发生计数器溢出事件的次数--计数1 */
uint16_t Period_cnt2 = 0; /* 发生计数器溢出事件的次数--计数2 */
uint16_t ic_flag = 0; /* 输入捕获标志 */
uint16_t end_flag = 0; /* 捕获结束标志 */
float frequency = 0; /* 频率 */
float duty_cycle = 0; /* 占空比 */
uint16_t ccr1_cnt_CH3 = 0; /* 发生第一次下升沿捕获时CCR1的值 */
uint16_t ccr2_cnt_CH3 = 0; /* 发生第二次上升沿捕获时CCR1的值 */
uint16_t Period_cnt_CH3 = 0; /* 发生计数器溢出事件的次数(过渡用) */
uint16_t Period_cnt1_CH3 =0; /* 发生计数器溢出事件的次数--计数1 */
uint16_t Period_cnt2_CH3 = 0; /* 发生计数器溢出事件的次数--计数2 */
uint16_t ic_flag_CH3 = 0; /* 输入捕获标志 */
uint16_t end_flag_CH3 = 0; /* 捕获结束标志 */
float frequency_CH3 = 0; /* 频率 */
float duty_cycle_CH3 = 0; /* 占空比 */
uint16_t ccr1_cnt_CH4 = 0; /* 发生第一次下升沿捕获时CCR1的值 */
uint16_t ccr2_cnt_CH4 = 0; /* 发生第二次上升沿捕获时CCR1的值 */
uint16_t Period_cnt_CH4 = 0; /* 发生计数器溢出事件的次数(过渡用) */
uint16_t Period_cnt1_CH4 =0; /* 发生计数器溢出事件的次数--计数1 */
uint16_t Period_cnt2_CH4 = 0; /* 发生计数器溢出事件的次数--计数2 */
uint16_t ic_flag_CH4 = 0; /* 输入捕获标志 */
uint16_t end_flag_CH4 = 0; /* 捕获结束标志 */
float frequency_CH4 = 0; /* 频率 */
float duty_cycle_CH4 = 0; /* 占空比 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{ /* 定时器计数溢出回调函数 */
if(htim==(&htim1))
{
FG_Count++;
}
else if(htim==(&htim3))
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
Period_cnt ++; /* 定时器计数溢出时间次数 */
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{
Period_cnt_CH3 ++; /* 定时器计数溢出时间次数 */
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
Period_cnt_CH4 ++; /* 定时器计数溢出时间次数 */
}
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{ /* 定时器输入捕获回调函数 */
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{ /* 判断是不是通道1 */
//printf("\nHAL_TIM_IC_CaptureCallback");
if(end_flag == 0){ /* 判断结束标志是不是0,在打印期间不进行捕获,防止打印时相关数值改变 */
switch(ic_flag){ /* 判断此时处于捕获的第几个阶段 */
//printf("\nic_flag=%d",ic_flag);
case 0: /* 阶段一:第一次捕获到上升沿 */
{
__HAL_TIM_SET_COUNTER(&htim3,0); /* 将定时器3计数设置为0 */
ccr1_cnt = 0; /* 将相关参数清0 */
ccr2_cnt =0;
Period_cnt = 0;
Period_cnt1 = 0;
Period_cnt2 = 0;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);/* 设置成下降沿捕获 */
ic_flag = 1; /* 捕获设置为等待第二个阶段 */
break;
}
case 1: /* 阶段二:第一次捕获到下降沿 */
{
ccr1_cnt = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);/* 获取存放在CCR寄存器的值(捕获值CCR1) */
Period_cnt1 = Period_cnt; /* 获取计时器溢出次数1 */
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING); /* 设置成上升沿捕获 */
ic_flag = 2; /* 捕获设置等待为第三个阶段 */
break;
}
case 2: /* 阶段三:第二次捕获到上升沿 */
{
ccr2_cnt = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);/* 取存放在CCR寄存器的值(捕获值CCR2) */
Period_cnt2 = Period_cnt; /* 获取计时器溢出次数2 */
ic_flag = 0; /* 捕获设置等待为第一个阶段 */
end_flag = 1; /* 完成一次捕获,将标志置1 */
break;
}
}
}
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{ /* 判断是不是通道3 */
//printf("\nHAL_TIM_IC_CaptureCallback");
if(end_flag_CH3 == 0){ /* 判断结束标志是不是0,在打印期间不进行捕获,防止打印时相关数值改变 */
switch(ic_flag_CH3){ /* 判断此时处于捕获的第几个阶段 */
//printf("\nic_flag=%d",ic_flag);
case 0: /* 阶段一:第一次捕获到上升沿 */
{
__HAL_TIM_SET_COUNTER(&htim3,0); /* 将定时器3计数设置为0 */
ccr1_cnt_CH3 = 0; /* 将相关参数清0 */
ccr2_cnt_CH3 =0;
Period_cnt_CH3 = 0;
Period_cnt1_CH3 = 0;
Period_cnt2_CH3 = 0;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_3,TIM_INPUTCHANNELPOLARITY_FALLING);/* 设置成下降沿捕获 */
ic_flag_CH3 = 1; /* 捕获设置为等待第二个阶段 */
break;
}
case 1: /* 阶段二:第一次捕获到下降沿 */
{
ccr1_cnt_CH3 = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_3);/* 获取存放在CCR寄存器的值(捕获值CCR1) */
Period_cnt1_CH3 = Period_cnt_CH3; /* 获取计时器溢出次数1 */
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_3,TIM_INPUTCHANNELPOLARITY_RISING); /* 设置成上升沿捕获 */
ic_flag_CH3 = 2; /* 捕获设置等待为第三个阶段 */
break;
}
case 2: /* 阶段三:第二次捕获到上升沿 */
{
ccr2_cnt_CH3 = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_3);/* 取存放在CCR寄存器的值(捕获值CCR2) */
Period_cnt2_CH3 = Period_cnt_CH3; /* 获取计时器溢出次数2 */
ic_flag_CH3 = 0; /* 捕获设置等待为第一个阶段 */
end_flag_CH3 = 1; /* 完成一次捕获,将标志置1 */
break;
}
}
}
}
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{ /* 判断是不是通道4 */
//printf("\nHAL_TIM_IC_CaptureCallback");
if(end_flag_CH4 == 0){ /* 判断结束标志是不是0,在打印期间不进行捕获,防止打印时相关数值改变 */
switch(ic_flag_CH4){ /* 判断此时处于捕获的第几个阶段 */
//printf("\nic_flag=%d",ic_flag);
case 0: /* 阶段一:第一次捕获到上升沿 */
{
__HAL_TIM_SET_COUNTER(&htim3,0); /* 将定时器3计数设置为0 */
ccr1_cnt_CH4 = 0; /* 将相关参数清0 */
ccr2_cnt_CH4 =0;
Period_cnt_CH4 = 0;
Period_cnt1_CH4 = 0;
Period_cnt2_CH4 = 0;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_4,TIM_INPUTCHANNELPOLARITY_FALLING);/* 设置成下降沿捕获 */
ic_flag_CH4 = 1; /* 捕获设置为等待第二个阶段 */
break;
}
case 1: /* 阶段二:第一次捕获到下降沿 */
{
ccr1_cnt_CH4 = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_4);/* 获取存放在CCR寄存器的值(捕获值CCR1) */
Period_cnt1_CH4 = Period_cnt_CH4; /* 获取计时器溢出次数1 */
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_4,TIM_INPUTCHANNELPOLARITY_RISING); /* 设置成上升沿捕获 */
ic_flag_CH4 = 2; /* 捕获设置等待为第三个阶段 */
break;
}
case 2: /* 阶段三:第二次捕获到上升沿 */
{
ccr2_cnt_CH4 = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_4);/* 取存放在CCR寄存器的值(捕获值CCR2) */
Period_cnt2_CH4 = Period_cnt_CH4; /* 获取计时器溢出次数2 */
ic_flag_CH4 = 0; /* 捕获设置等待为第一个阶段 */
end_flag_CH4 = 1; /* 完成一次捕获,将标志置1 */
break;
}
}
}
}
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_53197842/article/details/143205402
|