【蓝桥杯-嵌入式 STM32】PWM输入捕获,获取频率占空比

本次实验使用的是蓝桥杯嵌入式大赛的指定开发板,STM32G431R8T6。

下面为 CubeMX 和代码部分

CubeMX

选择对应引脚,配置为定时器模式,设置通道一路为“Input Captu direct mode”(输入捕获直接模式用于读取周期)、一路为“Input Captu inindirect mode”(输入捕获间接模式用于计算占空比)。

预分频(PSC)设置为(时钟频率-1)以便于计算。

自动重装初值默认不变。

通道一设置为“Rising Edge”上升沿捕获、通道二设置为“Falling Edge”下降沿捕获。

生成代码。

pwm.c

#include "pwm.h"

/* 用于输入捕获 */
uint32_t tim2_val1, tim2_val2, tim3_val1, tim3_val2;	/* 保存两路通道读取的值 */
uint32_t tim2_freq, tim3_freq;												/* 保存两路PWM的频率 */
float tim2_duty, tim3_duty;														/* 保存两路PWM的占空比*/


/* PWM捕获,占空比频率	(定时器输入捕获回调函数)
 * 参数:定时器
 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)	
	{
		/* 捕获到上升沿 */
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			tim2_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);	/* 读取通道一,上升沿的值 一个完整的周期 */
			tim2_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);	/* 读取通道二,下降沿的值 一个周期中的高电平 */
			__HAL_TIM_SetCounter(htim, 0);						/* 清零定时器中的值,继续读取下一周期的脉冲 */
			
			/* 捕获到的频率 = 时钟频率 / 预分频值 / 捕获的值(从0开始直到上升沿产生读的数值) */
			tim2_freq = (80000000 / 80) / tim2_val1;
			/* 捕获的占空比 = 高电平的时间 / 低电平的时间 * 100 */
			tim2_duty = ((float)tim2_val2 / tim2_val1) * 100;
			HAL_TIM_IC_Start(htim, TIM_CHANNEL_1);
			HAL_TIM_IC_Start(htim, TIM_CHANNEL_1);
		}
	}
	else if(htim->Instance == TIM3)
	{
		/* 捕获到上升沿 */
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			tim3_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);	/* 读取通道一,上升沿的值 一个完整的周期 */
			tim3_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);	/* 读取通道二,下降沿的值 一个周期中的高电平 */
			__HAL_TIM_SetCounter(htim, 0);						/* 清零定时器中的值,继续读取下一周期的脉冲 */
			
			/* 捕获到的频率 = 时钟频率 / 预分频值 / 捕获的值(从0开始直到上升沿产生读的数值) */
			tim3_freq = (80000000 / 80) / tim3_val1;
			/* 捕获的占空比 = 高电平的时间 / 低电平的时间 * 100 */
			tim3_duty = ((float)tim3_val2 / tim3_val1) * 100;
			HAL_TIM_IC_Start(htim, TIM_CHANNEL_1);
			HAL_TIM_IC_Start(htim, TIM_CHANNEL_1);
		}
	}
	
}

pwm.h

#ifndef __PWM_H_
#define __PWM_H_

#include "main.h"

/* 用于输入捕获 */
extern uint32_t tim2_val1, tim2_val2, tim3_val1, tim3_val2;		/* 保存两路通道读取的值 */
extern uint32_t tim2_freq, tim3_freq;													/* 保存两路PWM的频率 */
extern float tim2_duty, tim3_duty;														/* 保存两路PWM的占空比*/

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);

#endif

主函数功能验证部分

sprintf(lcd_string, "R39 freq %d      ",tim3_freq);
		LCD_DisplayStringLine(Line1, (unsigned char *)lcd_string);
		sprintf(lcd_string, "R39 duty %.3f    ",tim3_duty);
		LCD_DisplayStringLine(Line2, (unsigned char *)lcd_string);
		
		sprintf(lcd_string, "R40 freq %d      ",tim2_freq);
		LCD_DisplayStringLine(Line3, (unsigned char *)lcd_string);
		sprintf(lcd_string, "R40 duty %.3f    ",tim2_duty);
		LCD_DisplayStringLine(Line4, (unsigned char *)lcd_string);

注意在 main 函数开始时,我们还需要使能 PWM输入捕获中断使能:

	/* 开启定时器2,3输入捕获中断 */
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
	HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);

演示教程视频

【B 站链接 —— 备战 2025 蓝桥杯 —— 嵌入式】PWM输入捕获

如果您觉得这篇文章不错,且手里较为宽裕,可以支持一下博主,一分也是缘分😊
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇