stm32输入捕获实操

发布时间:2024年01月03日

很多事情下,需要捕获外部传感器的脉宽,频率,周期,从而计数来做一些应用。

这次就来分享下输入捕获

很早之前就听说过这个功能,一直没机会实操,现在,终于开始了。

首先,输入捕获也是用定时器来操作。定时器的功能挺强大的,可以输出一定的波形,又可以作为时基,还可以输入捕获,y1s1,真的太强了。

废话不多说,看看我是怎么操作的吧。

1.我使用PA2引脚产生一个50%的占空比

2.用示波器量,的确是有50%说明,成功

3.用PA1引脚来测上升沿捕获,看是否成功,如果成功,就让一个标志位置一,从而来判断是否捕获到上升沿,那么下面来看代码吧,根据代码来解释。

首先贴出输出50%占空比的代码


/*******************************************************************************
* 函 数 名         : TIM2_CH3_PWM_Init
* 函数功能		   : TIM2通道3 PWM初始化函数
* 输    入         : per:重装载值
					 psc:分频系数
* 输    出         : 无
*******************************************************************************/

void TIM2_CH3_PWM_Init(u16 per,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//改变指定管脚的映射	
	
	TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);	
	
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC3Init(TIM2,&TIM_OCInitStructure); //输出比较通道2初始化
	
	TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable); //使能TIMx在 CCR2 上的预装载寄存器
	TIM_ARRPreloadConfig(TIM2,ENABLE);//使能预装载寄存器
	
	TIM_Cmd(TIM2,ENABLE); //使能定时器
		
}

用正点原子的DS100测的还是挺准的

现在来贴出输入捕获的代码

//PA1
void TIM5_CH2_Input_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//使能TIM5时钟
	
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//管脚设置
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;	 //设置下拉输入模式
	GPIO_Init(GPIOA,&GPIO_InitStructure); 	   /* 初始化GPIO */

	
	TIM_TimeBaseInitStructure.TIM_Period=65535;   //自动装载值65535,最大能计65ms
	TIM_TimeBaseInitStructure.TIM_Prescaler=1; //分频系数72
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);	
		
	
	
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_2; //通道2
	TIM_ICInitStructure.TIM_ICFilter=0x00;  //滤波
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕获
	TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //分频系数
	TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直接映射到TI1
	TIM_ICInit(TIM5,&TIM_ICInitStructure);
	TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);
	
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);
		
	TIM_Cmd(TIM5,ENABLE); //使能定时器
	
	
	
}

通过datasheet可以知道是TIM5_CH2

再写个中断服务函数就完事了

上面代码的配置,65ms就会产生一次计数溢出的中断标志位,还有一个捕获到上升沿的标志位

程序全速跑的时候(这时候我没有用杜邦线接入PA2(产生50%占空比的引脚)),始终不会进入TIM_IT_CC2这个中断的,这个始终是RESET,当我接入PA2的时候,就会进来中断,说明捕获到了上升沿,实际情况也是如此嘛。没什么问题。

还是挺简单的,后续继续分享,怎么测周期,频率,占空比。步步为营,今天就到此结束啦!

文章来源:https://blog.csdn.net/weixin_46323814/article/details/135372531
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。