【国信长天蓝桥杯】③ STM32G431 TIM输入捕获,定时器输入捕获频率测量使用步骤

摘要

本文章基于国信长天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.cstm32g4xx_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 定时器输入捕获 使用步骤总结如下:

  1. 添加stm32g4xx_hal_tim.cstm32g4xx_hal_tim_ex.c
  2. 打开 stm32g4xx_hal_conf.h ,取消注释 HAL_TIM_MODULE_ENABLED
  3. 主函数 添加 #include "stm32g4xx_hal_tim.h"
  4. 复制(手打)代码 到 main() 上面;
  5. 在主函数中调用 MX_TIM2_Init(); , MX_TIM3_Init();
  6. 捕获的频率值存放在变量 f40_2f40_3

如果此文章对你有帮助,欢迎点赞 关注 收藏 转发.

版权声明:本文为CSDN博主「我是鹏老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48033504/article/details/115539486

生成海报
点赞 0

我是鹏老师

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于STM32的室内环境监测系统

设计简介: 本设计是基于单片机的室内环境监测器,主要实现以下功能: 可实现LCD1602显示环境数据实时监测一氧化碳、甲烷、烟雾值空气质量大于各自限值报警,并通过TTS报警 标签&#x

基于stm32f407的示波器

一.设计要求 二.整体思路 硬件部分主要负责电压的缩放以及垂直灵敏度的控制,因为stm32的大部分引脚最高输入电压为3.3v,而要求的电压需要50v,需要进行电压缩放。 软件部分主要负责方波的实现&#x

实验一 stm32F407VETx点亮流水灯

二、设计指标 使电路板上的8个LED轮流点亮,并按键控制点亮速度。 三、操作 1、CubeMX操作 1.1依据开发板LED引脚设置CubeMX中8个LED的引脚为GPIO_Output模式, 2、按键设置