【STM32Cube HAL】输入捕获(六)——脉宽测量

实验内容:使用通用定时器输入捕获测量信号的脉宽(检测按键按下的时间)。

 一、原理图

 二、 CubeMX配置

Step1.打开 STM32CubeMX,点击“New Project”,选择芯片型号,STM32F103VETx。

 Step2.选择时钟源,并配置时钟树。选择Crystal/Ceramic Resonator,并配置系统时钟为72M。

  

Step3.配置SYS,我们这里选择的是Serial Wire。(正常情况配置不配置不影响,debug可以使用。但是你不可以把这两个引脚用于其他复用功能,如果用于其他复用功能,debug就不起作用了。)

 

Step4.串口配置(主要为了在串口调试助手显示测试的时间),因为没有用到中断和DMA所以我们就不过多讲解。

 

 Step5.接下来进行最主要的定时器配置。原理图中按键引脚PA0和定时器2通道1相关,因此我们选用定时器2进行配置。

 

 到这里关于相关参数配置基本已经完成,只需要根据之前文章《STM32Cube HAL:GPIO输入/输出(一)》Step4-Step8,设置相关工程参数和生成代码。

三、添加功能代码

1、我们等会会向串口调试助手发送数据,进行实验结果的验证。 发送数据我们采用printf函数,所有需要重定向c库函数printf到串口。注意使用时需要在keil设置中勾选微库(use mircolib),同时需要添加头文件#include <stdio.h>。重定向代码如下(usart.c)

//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
	/* 发送一个字节数据到串口DEBUG_USART */
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);	
	
	return (ch);
}

//重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{		
	int ch;
	HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);	
	return (ch);
}

 2、定义相关变量,以及使能相关定时器和计数处理代码(main.c)

//全局变量
uint32_t ccr_cnt,period_cnt;//CCR寄存器值,中断次数
uint8_t tri_flag,end_flag;//触发方式标志位,捕获标记位
//局部变量
uint32_t cnt_cl=72000000/72;;//计数器时钟
float time;//按键时间
//使能相关定时器以及计数结果处理代码
                                                      
	__HAL_TIM_CLEAR_FLAG(&htim2,TIM_IT_UPDATE);//清除中断标志位,防止一使能定时器就进入中断
    HAL_TIM_Base_Start_IT(&htim2);//使能定时器及更新中断
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);//使能定时器及捕获中断

	printf("\r\n——————————开始按键测试——————————\r\n");
	
  while (1)
  {
		if(end_flag==1)//结束捕获
		{
			time=(float)(period_cnt*1000+(ccr_cnt+1))/cnt_cl;//结果强制转换为浮点型
			printf( "\r\n测得高电平脉宽时间:%.2fs\r\n",time);//输出结果保留小数点后两位
			end_flag=0;		
		}
  }

 3、中断回调函数(更新中断和捕获中断)(main.c)

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	period_cnt++;//中断计数
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	
	if(tri_flag==0)//上升沿触发时进入(tri_flag  0 上升沿触发 / 1 下降沿触发)
	{
		period_cnt=0;//中断次数清零
		__HAL_TIM_SET_COUNTER(&htim2,0); //计数器清零
		ccr_cnt=0;//存捕获寄存器获取的值的变量清零
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);//改变触发极性-下降沿触发
		tri_flag=1;
	}
	else//下降沿触发时进入
	{
		ccr_cnt=__HAL_TIM_GET_COMPARE(&htim2, TIM_CHANNEL_1);//获取捕获寄存器的值
		//ccr_cnt=HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);//功能同上
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);//改变触发极性-上降沿触发
		tri_flag=0;
		end_flag=1;//捕获完成标志
	}
}

总体来这个实验还算简单,主要的思路是先捕获第一个上升沿,然后将计数器值,中断计数值以及CCR寄存器(存捕获寄存器获取的值的变量)清零,同时变换为下降沿触发,进行第二次捕获,通过第二次的触发获取中断计数值以及CCR寄存器的值来计算出按键按住的时间。

猜你喜欢

转载自blog.csdn.net/qq_29031103/article/details/119894012
今日推荐