文章目录[隐藏]
摘要
本文章基于国信长天M4开发板,讲述了STM32G4 定时器TIM输入捕获频率测量的应用,祝各位学生蓝桥杯比赛取得好成绩!
M4开发板 频率发生器部分原理图
由上图可以看出,开发板上配置了两个555作为频率发生器,通过可调电阻R39,R40可调节输出频率,两个输出引脚分别连接在PA15和PB4引脚上。查阅芯片资料,可以得知这两个引脚可用作以下定时器的输入捕获:
PA15 --> TIM2_CH1(AF1)
PB4 --> TIM3_CH1(AF2)
TIM 输入捕获 使用步骤
下面将基于硬件原厂提供的显示屏示例代码:HAL_06_LCD
介绍TIM频率捕获的使用步骤:
① 添加 stm32g4xx_hal_tim.c,stm32g4xx_hal_tim_ex.c
双击Drivers/STM32G4xx_HAL_Driver,打开添加文件对话框,在向上一级
-> Drivers
-> STM32G4xx_HAL_Driver
-> Src
中,找到stm32g4xx_hal_tim.c
和 stm32g4xx_hal_tim_ex.c
并添加。添加后如下图所示:
② 修改 stm32g4xx_hal_conf.h
文件
在如下位置找到该文件,并打开:
取消注释 #define HAL_TIM_MODULE_ENABLED
这一行,取下注释后如下图所示:
③ main.c
添加#include "stm32g4xx_hal_tim.h"
在 main.c
适当位置添加#include "stm32g4xx_hal_tim.h"
和#include "stdio.h"
,添加后如下图所示:
④ 复制如下 TIM 初始化的代码
注意:下列代码包含了TIM2_CH1和TIM3_CH1的初始化,同学们按需复制!
TIM_HandleTypeDef htim2,htim3;
uint32_t cc1_value_2 = 0;
uint32_t f39 = 0, f40 = 0; //分别用来存储TIM2_CH1和TIM3_CH1的捕获频率
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
cc1_value_2 = __HAL_TIM_GET_COUNTER(htim);
__HAL_TIM_SetCounter(htim,0);
HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_1); //启动频率捕获
if(htim == &htim2)
{
f40 = 1000000/cc1_value_2;
}
if(htim == &htim3)
{
f39 = 1000000/cc1_value_2;
}
}
static void MX_TIM2_Init(void) //定时器2输入捕获初始化
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.Prescaler = 80;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_IC_Init(&htim2);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; //复用推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; //复用为定时器2
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化PA15
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//启动定时器2
}
void TIM2_IRQHandler(void) //定时器2中断
{
HAL_TIM_IRQHandler(&htim2);
}
static void MX_TIM3_Init(void) //定时器3输入捕获初始化
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_TIM3_CLK_ENABLE();
htim3.Instance = TIM3;
htim3.Init.Prescaler = 80;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 0xFFFF;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_IC_Init(&htim3);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1); //使用通道1
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; //复用输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; //复用为定时器3
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //初始化PA15
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); //启动定时器3
}
void TIM3_IRQHandler(void) //定时器3中断函数
{
HAL_TIM_IRQHandler(&htim3);
}
⑤ 在main()
中调用 MX_TIM2_Init();
, MX_TIM3_Init();
如下图所示,在main()
函数的适当位置调用 MX_TIM2_Init();
, MX_TIM3_Init();
⑥ 获取捕获的频率
在main()
的while()
中插入如下代码:
char buf[64] = {0};
sprintf(buf , "TIM2(R40): %d Hz ", f40);
LCD_DisplayStringLine(Line8, (uint8_t *)buf);
sprintf(buf , "TIM3(R39): %dHz ", f39);
LCD_DisplayStringLine(Line9, (uint8_t *)buf);
HAL_Delay(100);
⑦ 运行效果图
总结
TIM 定时器输入捕获 使用步骤总结如下:
- 添加
stm32g4xx_hal_tim.c
,stm32g4xx_hal_tim_ex.c
- 打开
stm32g4xx_hal_conf.h
,取消注释HAL_TIM_MODULE_ENABLED
- 主函数 添加
#include "stm32g4xx_hal_tim.h"
- 复制(手打)代码 到
main()
上面; - 在主函数中调用
MX_TIM2_Init();
,MX_TIM3_Init();
- 捕获的频率值存放在变量
f40_2
和f40_3
中
如果此文章对你有帮助,欢迎点赞
关注
收藏
转发
.
版权声明:本文为CSDN博主「我是鹏老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48033504/article/details/115539486
暂无评论