当前位置:网站首页>STM32定时器输入捕获频率(cube)
STM32定时器输入捕获频率(cube)
2022-08-09 05:02:00 【lilei668】
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);//占空比
}
}**
配置图片如下



经过实验检验同时打开了三路定时器输入捕获频率和占空比,运行正常,且三个定时器的优先级都是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频率的输入捕获,这样的话,虽然说有点浪费定时器资源,但是自认为效率会高不少。
边栏推荐
猜你喜欢
随机推荐
C Advanced - Program Compilation (Preprocessing) + Linking
【Harmony OS】【ArkUI】ets开发 创建视图与构建布局
9.jenkins安装
【开发者必看】【push kit】推送服务服务典型问题合集2
How to choose an APS system, it is necessary to clarify these seven key factors
软件测试的方法详细介绍
剑指Offer-双指针类型题目总结
22-08-08 西安 尚医通(04)MongoDB命令、MongoTemplate、MongoRepository
阻塞队列实现异步消费
A case of missing heritability
【Harmony OS】【ARK UI】公共事件模块
perl基础语法归纳
【LeetCode】169. 多数元素
Storage System Architecture Evolution
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarExcept
【HMS core】【Ads Kit】Huawei Advertising——Overseas applications are tested in China. Official advertisements cannot be displayed
【Harmony OS】【FAQ】Hongmeng Questions Collection 1
【Harmony OS】【ARK UI】Date Basic Operation
Anonymous shared memory ashmem
【ITRA】2022年ITRA赛事注册流程 从0-1

![[OpenCV] - Find and draw contours](/img/05/4f877bb779d7e5ffa71ed1fc55ba63.png)






