使用STM32cubemx进行定时器单多路pwm输入捕获

文章目录

  • 前言
  • 一、单通道捕获
    • 1.STM32 CUBEMX 配置
    • (1) 新建STM32 CUBEMX工程
    • (2)时钟配置
    • (3)定时器捕获配置
    • (4)定时器PWM配置
    • (5)串口配置
    • (6)设置代码生成相关
    • 2.Keil配置
    • 二、多通道捕获
    • 1.STM32 CUBEMX 配置
    • 2.Keil配置


前言

本文主要内容是STM32的定时器输入捕获,基于MDK_ARM,STM32 CUBEMX,keil软件和STM32F407VGT6最小系统板,实现PWM的输出与捕获,并通过串口输出捕获信息。


一、单通道捕获

1.STM32 CUBEMX 配置

(1) 新建STM32 CUBEMX工程

选择通过MCU新建项目
使用STM32cubemx进行定时器单多路pwm输入捕获_第1张图片

选择STM32型号,我这里用的是STM32F407VGT6
使用STM32cubemx进行定时器单多路pwm输入捕获_第2张图片

(2)时钟配置

在RCC设置HSE为晶振
使用STM32cubemx进行定时器单多路pwm输入捕获_第3张图片
配置时钟树,我在这里设置使得APB总线时钟频率为84MHz
使用STM32cubemx进行定时器单多路pwm输入捕获_第4张图片

(3)定时器捕获配置

将TIM2 通道1的模式选为输入捕获
使用STM32cubemx进行定时器单多路pwm输入捕获_第5张图片
选择TIM2时钟源为内部时钟源
使用STM32cubemx进行定时器单多路pwm输入捕获_第6张图片
预分频系数设为APB总线频率减一 我这里设置为84-1
使用STM32cubemx进行定时器单多路pwm输入捕获_第7张图片
预装载值设为最大
使用STM32cubemx进行定时器单多路pwm输入捕获_第8张图片
开启预装载
使用STM32cubemx进行定时器单多路pwm输入捕获_第9张图片
开启TIM中断
使用STM32cubemx进行定时器单多路pwm输入捕获_第10张图片
使用STM32cubemx进行定时器单多路pwm输入捕获_第11张图片

(4)定时器PWM配置

这里选择TIM3的通道1生成PWM,占空比,脉宽,周期可以自由设置
使用STM32cubemx进行定时器单多路pwm输入捕获_第12张图片

(5)串口配置

选用串口,我这里选的是串口1
使用STM32cubemx进行定时器单多路pwm输入捕获_第13张图片

(6)设置代码生成相关

使用STM32cubemx进行定时器单多路pwm输入捕获_第14张图片
使用STM32cubemx进行定时器单多路pwm输入捕获_第15张图片

2.Keil配置

在main.c中添加代码 ,根据开头和结尾/* */定位:
自定义变量结构体声明

/* USER CODE BEGIN PV */
uint32_t capture_Buf[3]={0};   //捕获值
uint8_t capture_Cnt=0;  //设置状态标志位
uint8_t overload_Cnt=0; //溢出标志
uint32_t high_time;     //高电平时间
uint32_t low_time;      //低电平时间
double HL_time;
double LL_time;
double fre;
double duty;
/* USER CODE END PV */

添加回调函数

/* USER CODE BEGIN PFP */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance==htim2.Instance)
	{
	switch(capture_Cnt){
		case 0:
			capture_Buf[0]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置下降沿捕获
		capture_Cnt++;
		break;
		
		case 1:
			capture_Buf[1]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);  //设置上升沿捕获
		capture_Cnt++;
		break;
		
		case 2:
			capture_Buf[2]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);  //停止输入捕获
		high_time=capture_Buf[1]-capture_Buf[0]+overload_Cnt*0xFFFFFFFF;  //高电平时间
		low_time=capture_Buf[2]-capture_Buf[1]+overload_Cnt*0xFFFFFFFF;  //低电平时间
		HL_time=high_time*0.001;
		LL_time=low_time*0.001;
		fre=1/(HL_time+LL_time)*1000;
		duty=HL_time/(HL_time+LL_time)*100;
		capture_Cnt=0;  //清空标志位
		overload_Cnt=0;  //清空溢出标志位
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
		HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
		break;
		
	}
	}
}
/* USER CODE END PFP */

开启PWM和捕获

/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);  //设置为下降沿捕获
HAL_TIM_IC_Start_IT(&htim2,	TIM_CHANNEL_1);  //开启输入中断
  /* USER CODE END 2 */

在usart.c中添加代码

/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1000);
	return 0;
}
/* USER CODE END 1 */
/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */

在main.c中设置串口

/* USER CODE END WHILE */
		printf("频率:%7.31fHz,%4.11f%%,高电平时间:%7.31fms,低电平时间:%7.31fms\r\n\r\n",fre,duty,HL_time,LL_time);
		HAL_Delay(2000);
/* USER CODE BEGIN 3 */

/* USER CODE BEGIN Includes */
#include"stdio.h"
/* USER CODE END Includes */

最后编译下载

二、多通道捕获

tim2 定时器有四个通道,都有输入捕获模式。可以通过设置实现单定时器多通道的PWM捕获

1.STM32 CUBEMX 配置

和单通道捕获的设置相似,我这里选择的是TIM2_CH1 和TIM2_CH2为输入捕获,TIM3_CH1和TIM4_CH1为PWM输出
使用STM32cubemx进行定时器单多路pwm输入捕获_第16张图片

2.Keil配置

因为增加了一路捕获,自定义结构体声明也相应增加。我这里在末尾加1来区分

/* USER CODE BEGIN PV */

uint32_t capture_Buf[6]={0};   //捕获值
uint8_t capture_Cnt=0;  //设置状态标志位
uint8_t overload_Cnt=0; //溢出标志
uint8_t capture_Cnt1=0;  //设置状态标志位
uint8_t overload_Cnt1=0; //溢出标志
uint32_t high_time;     //高电平时间
uint32_t low_time;      //低电平时间
uint32_t high_time1;     //高电平时间
uint32_t low_time1;      //低电平时间
double HL_time;
double LL_time;
double HL_time1;
double LL_time1;
double fre;
double duty;
double fre1;
double duty1;


/* USER CODE END PV */

使用STM32cubemx进行定时器单多路pwm输入捕获_第17张图片
回调函数也相应增加

/* USER CODE BEGIN PFP */

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance==htim2.Instance)
	{
		if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)
			{
	switch(capture_Cnt){
		case 0:
			capture_Buf[0]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置下降沿捕获
		capture_Cnt++;
		break;
		
		case 1:
			capture_Buf[1]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);  //设置上升沿捕获
		capture_Cnt++;
		break;
		
		case 2:
			capture_Buf[2]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);  //得到捕获值
		HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);  //停止输入捕获
		high_time=capture_Buf[1]-capture_Buf[0]+overload_Cnt*0xFFFFFFFF;  //高电平时间
		low_time=capture_Buf[2]-capture_Buf[1]+overload_Cnt*0xFFFFFFFF;  //低电平时间
		HL_time=high_time*0.001;
		LL_time=low_time*0.001;
		fre=1/(HL_time+LL_time)*1000;
		duty=HL_time/(HL_time+LL_time)*100;
		capture_Cnt=0;  //清空标志位
		overload_Cnt=0;  //清空溢出标志位
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
		HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
		break;
	}
}
 if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2){
		switch(capture_Cnt1){
			case 0:
			capture_Buf[3]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);  //设置下降沿捕获
		capture_Cnt1++;
		break;
		
		case 1:
			capture_Buf[4]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);  //得到捕获值
		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);  //设置上升沿捕获
		capture_Cnt1++;
		break;
		
		case 2:
			capture_Buf[5]=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);  //得到捕获值
		HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_2);  //停止输入捕获
		high_time1=capture_Buf[4]-capture_Buf[3]+overload_Cnt1*0xFFFFFFFF;  //高电平时间
		low_time1=capture_Buf[5]-capture_Buf[4]+overload_Cnt1*0xFFFFFFFF;  //低电平时间
		HL_time1=high_time1*0.001;
		LL_time1=low_time1*0.001;
		fre1=1/(HL_time1+LL_time1)*1000;
		duty1=HL_time1/(HL_time1+LL_time1)*100;
		capture_Cnt1=0;  //清空标志位
		overload_Cnt1=0;  //清空溢出标志位
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_RISING);
		HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
		break;

	}
	
}
}
	}


/* USER CODE END PFP */

其中

if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)

if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)

分别表示进入TIM2_CH1和TIM2_CH2

相应地开启新加入的定时器通道

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);  //设置为下降沿捕获
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_RISING);  //设置为下降沿捕获
HAL_TIM_IC_Start_IT(&htim2,	TIM_CHANNEL_1);  //开启输入中断
HAL_TIM_IC_Start_IT(&htim2,	TIM_CHANNEL_2);  //开启输入中断

  /* USER CODE END 2 */

添加TIM2_CH2的printf

  /* USER CODE BEGIN 3 */
  printf("频率:%7.31fHz,%4.11f%%,高电平时间:%7.31fms,低电平时间:%7.31fms\r\n\r\n",fre,duty,HL_time,LL_time);
		HAL_Delay(2000);
 printf("频率1:%7.31fHz,%4.11f%%,高电平时间1:%7.31fms,低电平时间1:%7.31fms\r\n\r\n",fre1,duty1,HL_time1,LL_time1);
		HAL_Delay(2000);
	}
	
  /* USER CODE END 3 */

最后编译运行
使用STM32cubemx进行定时器单多路pwm输入捕获_第18张图片
通过串口调试助手可以看到捕获的两路PWM信息

你可能感兴趣的:(笔记,stm32,单片机,嵌入式,keil,mdk)