STM32定时器输入捕获频率(cube)

发布时间:2022-10-08 17:00

STM32用cube配置HAL库进行的pwm输入捕获已经搞定。
stm32中的通用定时器和高级定时器直接可以设定PWM输入模式,pwm输入模式直接会打开两个输入捕获通道,通道1,3是用来捕获频率的,通道2,4是用来捕获空占比的,而且在进入主函数之前需要打开定时器输入捕获通道中断,通过HAL_TIM_ReadCapturedValue可以直接读取两个输入捕获通道中的信息,十分方便,但是在进行频率计算的时候,方法:芯片设定的时钟频率**/(读取到的输入捕获的频率数值+2)**这样可以得到近乎完全正确的数据。

频率捕获计算公式:
// 输入捕获能捕获到的最小的频率为 72M/{ (ARR+1)*(PSC+1) }
#define ADVANCE_TIM_PERIOD (1000-1)
#define ADVANCE_TIM_PSC (720-1)

pwm输出频率计算公式:
// 输出PWM的频率为 72M/{ (ARR+1)*(PSC+1) }
#define GENERAL_TIM_PERIOD (2000-1)
#define GENERAL_TIM_PSC (720-1)

    /* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);//如果不需要占空比和频率数据就只开通道2即可。第一次的数据是不正确的,实际工作中要将第一次的数据丢弃

以下为主函数中的代码
*/ USER CODE END 2 */

/* USER CODE BEGIN WHILE */
while (1)
{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
if (tmp1 == 0)
{
    duty = 0;
    freq = 0;
}
else
{
    duty = tmp2 * 100.0f / tmp1 + 0.5f;
		/*tmp1前后需要各加1,及tmp+2*/
    freq = 72000000.0f / (tmp1+2);
}
		
printf ("freq: %d Hz\tduty: %d %%\r\n", freq, duty);
printf ("tmp1: %d\t%d\r\n", tmp1, tmp2);

// printf (“pos pulse= %lf\r\n”, tmp1 * 1.111111111111111e-8);// 这个1.xe-8就是90M时钟分之一
HAL_Delay(500);
}
/* USER CODE END 3 /*
以下为tim.c中的代码
*/ USER CODE BEGIN 1 */
uint32_t duty = 0;
uint32_t freq = 0;
uint32_t tmp1 = 0, tmp2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
// volatile static uint32_t tmp1 = 0, tmp2 = 0;

if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
    tmp1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);//周期
}
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
    tmp2 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);//占空比
}

}**
配置图片如下
STM32定时器输入捕获频率(cube)_第1张图片
STM32定时器输入捕获频率(cube)_第2张图片
STM32定时器输入捕获频率(cube)_第3张图片
STM32定时器输入捕获频率(cube)_第4张图片
经过实验检验同时打开了三路定时器输入捕获频率和占空比,运行正常,且三个定时器的优先级都是0,0,正常运行,数据都比较准确
据目前知识掌握程度看,定时器回调函数只有一个,所以在对只有一个输入捕获的定时器进行了修改:uint32_t duty = 0,duty2 = 0,duty3 = 0;
uint32_t freq = 0,freq2 = 0;
uint32_t tmp1 = 0, tmp2 = 0,tmp3 = 0,tmp4 = 0,tmp5 = 0,tmp6 = 0;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
// volatile static uint32_t tmp1 = 0, tmp2 = 0;

if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
		/*tem1,3分别是定时器2,3的输入捕获周期*/
    tmp1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);//周期
			tmp3 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);//周期
			tmp5 = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1);//周期
}
else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
		/*tem2,4分别是定时器2,3的输入捕获占空比*/
    tmp2 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);//占空比
			tmp4 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);//占空比
			tmp6 = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_2);//占空比
}

}
/读取定时器输入捕获数据/
void Read_Timer_Data(void)
{
if (tmp1 == 0)
{
duty = 0;
}
else
{
duty = tmp2 * 100.0f / tmp1 + 0.5f;
}

if (tmp3 == 0)
{
    duty2 = 0;
}
else
{
    duty2 = tmp4 * 100.0f / tmp3 + 0.5f;
}
	
if (tmp5 == 0)
{
    duty3 = 0;
}
else
{
    duty3 = tmp6 * 100.0f / tmp5 + 0.5f;
}	

}

经过实际检验同一个定时器同时进行PWM输出和PWM输入捕获的时候,不是非常的好用,因此如果以后需要使用编码器电机,推荐使用一个定时器用来输出PWM波,再用四个定时器进行PWM频率的输入捕获,这样的话,虽然说有点浪费定时器资源,但是自认为效率会高不少。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号