蓝桥杯stm32学习笔记(七):输入捕获(频率,占空比测量)
Published in:2024-03-18 | category: 嵌入式
Words: 673 | Reading time: 2min | reading:

跳线帽拔了不能烧工程。。。。(好像可以。。。那天不知道怎么了板子抽风)

CubeMX配置

配置引脚

我们这里使用PA7进行捕获

配置PA7TIM17_CH1
(只有一个通道没关系,我的题目里不用测占空比,但是我后面会写加上测占空比的引脚和程序的)

  • 配置一下引脚
  • 使能定时器中断

生成工程

点击右上角”GENERATE CODE”,生成工程

代码

中断函数

interrupt.c中:

1
2
3
4
5
6
7
8
uint ccrl_val=0;
uint frq=0;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{


}

中断回调函数名记不住的话和按键那一章一样,在tim.h文件里找

中断回调函数
1
2
3
4
5
6
7
8
9
10
11
12
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM17)
{
ccrl_val = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
frq=(80000000/80)/ccrl_val;
__HAL_TIM_SetCounter(htim,0);
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);//IC:Input Capture

}

}

注意自己写的中断回调函数有什么用,如果不写自己的回调函数,已设置的中断照样正常运行,自己的函数是用来特殊化一些中断流程的,没有特殊化的仍旧按照默认正常运行

原理解释:
当TIM17的中断触发(因为配置了上升沿触发,即当检测到上升沿时)
进入中断回调函数
因为最后一行才启动定时器的输入捕获通道1
所以第一次触发后,计数器归0(__HAL_TIM_SetCounter(htim,0);)
启动定时器的输入捕获通道1,开始计数
第二次触发中断(即第二次上升沿)
ccrl_val读取到两个上升沿间隔(因为第一个上升沿才开始计数)
所以频率等于时钟主频除以分频系数除以周期计数
重新启动定时器的输入捕获通道1

main.c中配置

1
2
3
extern uint frq;
uchar pa1_duty=10;//初始化占空比

main函数里的初始化:

1
2
3
4
5
6
HAL_TIM_Base_Start_IT(&htim4 );//按键的定时器
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//PA1的PWM输出开启

HAL_TIM_IC_Start_IT(&htim17,TIM_CHANNEL_1);//频率测量捕获定时器开启

__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pa1_duty);//设置初始pwm频率

同时测频率和占空比:

引脚配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/////////////////////////////测量频率+占空比///////////////////
double ccr1_val1a=0,ccr1_val2a=0;
uint ccr1_val1b=0,ccr1_val2b=0;
uint frq1=0,frq2=0;//频率
float duty1=0,duty2=0;//占空比
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM17)//PA7
{
// if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)//中断消息来源 选择直接输入的通道
// {
ccr1_val1a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//直接
// ccr1_val1b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);//间接
__HAL_TIM_SetCounter(htim,0);
frq1=(80000000/80)/ccr1_val1a;
// duty1=(ccr1_val1b/ccr1_val1a)*100;
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
// HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
// }
}
if(htim->Instance==TIM3)//PB4
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)//中断消息来源 选择直接输入的通道
{
ccr1_val2a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
ccr1_val2b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);
__HAL_TIM_SetCounter(htim,0);
frq2=(80000000/80)/ccr1_val2a;
duty2=(ccr1_val2b/ccr1_val2a)*100;
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
}
}
}
Prev:
蓝桥杯stm32学习笔记(八):模数转换ADC
Next:
蓝桥杯stm32学习笔记(六):PWM输出