蓝桥杯嵌入式STM32G431RBT6拓展板测量频率和占空比

国赛12届中有测量拓展板PULS1频率,PWM1、PWM2占空比。

一、原理图以及两个通道的实际频率

 

PWM1的实际频率大概在11KHz左右  

PWM2实际频率在1.1KHz左右 

二、CubeMX配置

 对于单通道双边沿测量占空比,由于PWM1频率太大,当占空比太大或太小时测不准,我觉得可以在CubeMX中加入数字滤波。当然,这仅仅是拙见,如果有更好的方法,请在评论区留言。

 使用Both Edges测量占空比,测量三次来获得占空比Duty = (Value1-Value0)/(Value2-Value0);

第一次:上升沿触发,获得第一次的值Value0,触发方式改为下降沿;

第二次:下降沿触发,获得第二次的值Value1,触发方式改为上升沿;

第三次:上升沿触发,获得第三次的值Value2,寄存器清零,Duty = (Value1-Value0)/(Value2-Value0)。

三、代码

 IC_PWM.C

#include "ic_pwm.h"
#include "tim.h"

uint32_t PULS1_Fre = 0;
struct IC_Dat TIM3Dat = {0.0f,0,{0,0,0}}, TIM17Dat = {0.0f,0,{0,0,0}};

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获中断回调函数
{
	if(htim == &htim2 )//PULS1
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)//来自于通道2
		{
			uint32_t n = 0;
			n = HAL_TIM_ReadCapturedValue (htim ,TIM_CHANNEL_2 );
			__HAL_TIM_SetCounter (htim ,0);
			PULS1_Fre = 1000000 / n;
			HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_2 );//重新启动
		}
	}
	else if(htim == &htim3)
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)//来自于通道1
		{
			//Edge:0(rise)->1(fall)->2(rise),三次捕获完成
			if((TIM3Dat.Edge % 2) == 0)//上升沿
			{
				TIM3Dat.Value [TIM3Dat.Edge] = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1 );
				if(TIM3Dat.Edge == 2)//三次捕获完成
				{
					TIM3Dat.Duty = (TIM3Dat.Value[1] * 1.0f - TIM3Dat.Value[0])/(TIM3Dat.Value[2] - TIM3Dat.Value[0]);
					TIM3Dat.Edge = 0;
					__HAL_TIM_SetCounter (htim ,0);//清零
					__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);//重新设置为上升沿捕获
					HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
				}
				else
				{
					TIM3Dat.Edge = 1;
					__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);//设置为下降沿捕获
					HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
				}
			}
			else//下降沿
			{
				TIM3Dat.Value [TIM3Dat.Edge] = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1 );
				TIM3Dat.Edge = 2;
				__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);//重新设置为上升沿捕获
				HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
			}
		}
	}
	else if(htim == &htim17 )
	{
		if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)//来自于通道1
		{
			//Edge:0(rise)->1(fall)->2(rise),三次捕获完成
			if((TIM17Dat.Edge % 2) == 0)//上升沿
			{
				TIM17Dat.Value [TIM17Dat.Edge] = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1 );
				if(TIM17Dat.Edge == 2)//三次捕获完成
				{
					TIM17Dat.Duty = (TIM17Dat.Value[1] * 1.0f - TIM17Dat.Value[0])/(TIM17Dat.Value[2] - TIM17Dat.Value[0]);
					TIM17Dat.Edge = 0;
					__HAL_TIM_SetCounter (htim ,0);//清零
					__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);//重新设置为上升沿捕获
					HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
				}
				else
				{
					TIM17Dat.Edge = 1;
					__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);//设置为下降沿捕获
					HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
				}
			}
			else//下降沿
			{
				TIM17Dat.Value [TIM17Dat.Edge] = HAL_TIM_ReadCapturedValue (htim,TIM_CHANNEL_1 );
				TIM17Dat.Edge = 2;
				__HAL_TIM_SET_CAPTUREPOLARITY (htim ,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);//重新设置为上升沿捕获
				HAL_TIM_IC_Start_IT (htim ,TIM_CHANNEL_1 );
			}
		}
	}
}

IC_PWM.h

#ifndef __IC_PWM_H
#define __IC_PWM_H

#include "stm32g4xx_hal.h"

struct IC_Dat{
	float Duty;
	uint8_t Edge;
	uint32_t Value[3];
};


#endif

main函数的功能函数

/*******************************************LCD*****************************/
char LCD_BUF[30];
/*************************************IC************************************/
extern uint32_t PULS1_Fre;
extern struct IC_Dat TIM3Dat, TIM17Dat;
void LCD_Display(void )/***********************************LCD*************************/
{	
	sprintf (LCD_BUF ,"PULS1:%dHz    ",PULS1_Fre);
	LCD_DisplayStringLine (Line1 ,(uint8_t *)LCD_BUF);
	
	sprintf (LCD_BUF ,"PWM1_Duty:%.1f    ",TIM3Dat.Duty*100.0f );
	LCD_DisplayStringLine (Line2 ,(uint8_t *)LCD_BUF);
	sprintf (LCD_BUF ,"PWM2_Duty:%.1f    ",TIM17Dat.Duty*100.0f);
	LCD_DisplayStringLine (Line3 ,(uint8_t *)LCD_BUF);
}

四、功能演示

改良后测量占空比

### 关于蓝桥杯嵌入式比赛中的占空比单沿实现方法 在嵌入式开发中,占空比通常用于描述脉冲信号高电平时间与整个周期的比例。对于单沿检测或控制的应用场景,可以通过硬件外设(如定时器)配合软件逻辑来完成。 #### 定时器配置与单沿捕获 在STM32微控制器中,通过设置定时器的输入捕获模式可以实现对信号边沿的精确捕捉。具体来说,当需要检测单沿时,可以选择只触发某一特定类型的边沿(上升沿或下降沿),而忽略另一类边沿。这种机制能够有效减少干扰并提高精度[^1]。 例如,在初始化阶段,如果希望仅响应上升沿,则需正确配置CCER寄存器的相关位。如下所示: ```c // 设置 CC1P 为 1 表示选择上升沿作为有效的捕获事件 TIM2->CCER |= 0x0002; ``` 上述代码片段展示了如何利用 STM32 的寄存器操作指定某个通道的工作方式为上升沿捕获[^2]。 #### 主函数中的初始化过程 为了使能中断处理以便实时获取数据变化情况,在主程序部分还需要调用相应的启动接口函数。以下是针对 TIM3 输入捕获功能开启 IT 中断的例子: ```c HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); ``` 这里分别开启了两个独立信道上的输入捕获中断服务请求(ISR),从而允许同时监测多路信号特性[^3]。 #### PWM 输出调整频率占空比 除了单纯读取外部源参数之外,有时也需要动态改变本地生成波形的各项属性值。下面给出了一段简单的示范代码说明怎样修改 ARR CCR 寄存器数值达到自定义输出效果的目的: ```c // 开启PWM模式下的中断支持 HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_2); // 设定自动重载寄存器(ARR)决定基本周期长度 TIM2->ARR = 499; // 配置比较寄存器(CCRn)确立实际高低时段比例关系 TIM2->CCR2 = 50; ``` 此段脚本里设置了总时间为500单位刻度,并让其中一半处于激活状态即实现了理论意义上的百分之五十占比情形下运行状况模拟演示[^4]。 综上所述,无论是执行单一方向边缘探测还是灵活调控内部组件行为表现形式等方面均提供了详尽指导方针供参赛者参考学习实践应用价值极高值得深入研究探讨交流分享经验成果共同进步成长!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EE蒋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值