一、产生PWM50%占空比
二、TIM4捕获上面产生的PWM(PA8与PB6用杜邦线相连)
三、用串口来显示捕获到的情况
四、串口重定向
/*printf函数重定向*/
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t*) &ch, 1, 100);
return ch;
}
五、打开两个定时器
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim4); //打开定时器中断
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); //打开pwm输出
/* USER CODE END 2 */
六、重写两个中断回调函数
6.1 捕获的回调函数
/*捕获的回调函数*/
/*先设置计数为0 ,防止溢出,因为最大只能到65535,很容易溢出,所以每次翻转极性前清零计数器,下次捕获中断直接就是上个极性的电平时间*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) //中断回调函数
{
if (TIM4 == htim->Instance)
{
if (capture_cnt == 1)
{
__HAL_TIM_SetCounter(htim,0); //先设置计数为0 ,防止溢出
__HAL_TIM_SET_CAPTUREPOLARITY(&htim4, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); //设置成下降沿捕获
capture_cnt++;
}
else if (capture_cnt == 2)
{
capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_1); //低电平捕获,记录此时的值
__HAL_TIM_SetCounter(htim,0); //先设置计数为0 ,防止溢出
__HAL_TIM_SET_CAPTUREPOLARITY(&htim4, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); //设置上升沿捕获
capture_cnt++;
}
else if (capture_cnt == 3)
{
capture_cnt++;
capture_Buf[2] = HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_1); //高电平捕获,记录此时的值
HAL_TIM_IC_Stop_IT(&htim4, TIM_CHANNEL_1); //停止捕获
}
}
}
6.2定时器溢出的回调函数
//时间太长,一个周期不够
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM4)
{
if (falling_flag == 0) //前提是还没捕获到下降沿,如果捕获到下降沿说明一个周期完成了,
{
if (rising_flag == 1) //捕获到上升沿,且没有捕获下降沿,说明高电平还在持续,记录溢出次数
{
if ((overflow_val & 0XFF) == 0XFF) /* 高电平时间太长了,强制捕获成功 */
{
falling_flag = 1;
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
cnt_val = 0XFFFF;
}
else
{
overflow_val++;
}
}
}
}
}
main 函数
while (1)
{
if (capture_cnt == 0)
{
//程序第一次进来,先设置上升沿捕获,计数器清零,然后会进入捕获中断
//先设置计数为0 ,防止溢出
capture_cnt++;
__HAL_TIM_SET_CAPTUREPOLARITY(&htim4, TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿捕获
__HAL_TIM_SetCounter(&htim4,0); //先设置计数为0 ,防止溢出
HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1); //开启输入捕获
}
else if (capture_cnt == 4)
{
high_time = capture_Buf[1]; //计算高电平时间
low_time = capture_Buf[2]; //计算低电平时间
period_time = high_time + low_time; //计算周期
printf("周期:%.2f\r\n", period_time); //计算周期
printf("高电平时间:%.2f\r\n", high_time);
printf("低电平时间:%.2f\r\n", low_time);
capture_cnt = 0; //清空标志位
}
}
结果与设定的50%一致: