STM32的HAL库开发---高级定时器PWM输入模式实验

一、PWM输入模式工作原理

通过PWM输入模式,可以测量PWM的周期、频率、占空比。

时钟源选择内部时钟源,然后设置PSC预分频系数。F1系列内部时钟为72M的,PSC分频系数设置为0,也就是不分频。可以计算出计数器计一个数的时间,也就是量器的精度。

具体配置:例如PWM从通道1输入,配置TI1的两个信号TI1FP1和TI1FP2分别映射到IC1和IC2上面。然后设置IC1为上升沿触发,IC2为下降沿触发。然后当上升沿来的时候,让计数器的值变为0。这个可以通过配置定时器的从模式为复位模式,通过配置TRGI为TI1FP1触发,当TI1FP1信号来的时候,计数器自动清零。由于通道3和通道4没有信号可以触发定时器的从模式,所以只能用通道1和通道2。

二、PWM输入模式时序

首先PWM上升沿来的时候,计数器的值会被清0 ,等待下降沿到来。下降沿来时,计数器的值会转移到CCR2里边,然后上升沿再次来时,计数器的值会被转移到CCR1里边,同时计数器的值再次清零。

三、PWM输入模式配置步骤

1、HAL_TIM_IC_init()函数,配置定时器基础工作参数。,与base_init()函数一样

2、HAL_TIM_IC_MspInit()函数,配置NVIC、CLOCK、GPIO等。

3、HAL_TIM_IC_ConfigChannel()函数,配置输入通道1/2映射、捕获边沿等。

4、HAL_TIM_SlaveConfigSynchro()函数,设置从模式触发源

5、HAL_NVIC_SetPriority()、HAL_NVIC_EnablelRQ()函数,设置优先级,使能中断。

6、HAL_TIM_IC_Start_IT()函数,使能捕获、捕获中断及计数器。

7、TIMx_IROHandler()中断服务函数。

8、HAL_TIM_IC_CaptureCallback()函数,输入捕获中断回调函数。

四、PWM输入模式实验

1、寄存器版本

#include "./BSP/TIMER/atim.h"

//配置定时器1的通道1 和 通道1互补输出  PE8 PE9
void Advanced_TIM_Init(void)
{
	//开启定时器1时钟
	RCC->APB2ENR |= (1 << 11);
	
	//设置ARR寄存器缓冲功能
	TIM1->CR1 |= (1 << 7);
	
	//设置计数器向上计数
	TIM1->CR1 &= ~(1 << 4);
	
	//TS 设置从模式触发为TI1FP1
	TIM1->SMCR |= (1 << 6);
	TIM1->SMCR |= (1 << 4);
	TIM1->SMCR &= ~(1 << 5);
	
	//SMS为复位模式
	TIM1->SMCR |= (1 << 2);
	
	//CC1S 配置IC1到TI1上
	TIM1->CCMR1 |= (1 << 0);
	
	//CC2S 配置IC2到TI1上
	TIM1->CCMR1 |= (1 << 9);
	
	//设置IC1上升沿捕获
	TIM1->CCER &= ~(1 << 1);
	
	//CC1E 使能通道1捕获
	TIM1->CCER |= (1 << 0);
	
	//设置IC2下升沿捕获
	TIM1->CCER |= (1 << 5);
	
	//CC2E 使能通道2捕获
	TIM1->CCER |= (1 << 4);
	
	//CC1IE 使能捕获1中断	
	TIM1->DIER |= (1 << 1);
	
	//CC2IE 使能捕获2中断
	TIM1->DIER |= (1 << 2);
		
	//设置预分频系数为0
	TIM1->PSC = 0;
	
	//设置预装载值为65535
	TIM1->ARR = 65535;

	TIM1->EGR |= (1 << 0);
	
	//开启GPIOE1时钟
	RCC->APB2ENR |= (1 << 6);
	
	//设置PE9为输入
	GPIOE->CRH &= ~(0X03 << 4);
	//GPIOE->CRH |= (1 << 7);
	//GPIOE->CRH &= ~(1 << 6);
	
	//使能AFIO时钟
	RCC->APB2ENR |= (1 << 0);
	
	//设置TIM1完全重映射 将CH1映射到PE9
	AFIO->MAPR |= (0x03 << 6);
	
	//开启TIM1 CC中断
	HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
	
	//设置中断优先级
	HAL_NVIC_SetPriority(TIM1_CC_IRQn, 2, 2);
	
	//使能计数器
	TIM1->CR1 |= (1 << 0);
}

uint16_t CNT1 = 0;
uint16_t CNT2 = 0;
void TIM1_CC_IRQHandler(void)
{
	//CC1中断
	if(TIM1->SR & (1 << 1))
	{
		CNT1 = TIM1->CCR1;
	}
	
	if(TIM1->SR & (1 << 2))
	{
		CNT2 = TIM1->CCR2;
	}
	TIM1->SR &= ~(1 << 1);
	TIM1->SR &= ~(1 << 2);
}

这个程序是使用TIM8的通道1 PE9测量外部输入PWM信号

2、库函数版本

atim.h头文件

#ifndef __ATIM_H
#define __ATIM_H

#include "stm32f1xx.h"
void Advanced_TIM_Init(void);
#endif

atim.c源文件

#include "./BSP/TIMER/atim.h"

//配置定时器1的通道1 PE9  测量信号PWM输入频率  周期
TIM_HandleTypeDef htim;
void Advanced_TIM_Init(void)
{
	htim.Instance = TIM1;
	
	htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
	htim.Init.CounterMode = TIM_COUNTERMODE_UP;
	htim.Init.Period = 65535;
	htim.Init.Prescaler = 0;
	
	HAL_TIM_IC_Init(&htim);
	
	TIM_IC_InitTypeDef sConfig = {0};
	
	//配置IC1 连接到CH1上 上升沿捕获
	sConfig.ICFilter = 0;
	sConfig.ICPolarity = TIM_ICPOLARITY_RISING;
	sConfig.ICPrescaler = TIM_ICPSC_DIV1;
	sConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
	HAL_TIM_IC_ConfigChannel(&htim, &sConfig, TIM_CHANNEL_1);
	
	//配置IC2 连接通道1上 下降沿捕获
	sConfig.ICFilter = 0;
	sConfig.ICPolarity = TIM_ICPOLARITY_FALLING;
	sConfig.ICPrescaler = TIM_ICPSC_DIV1;
	sConfig.ICSelection = TIM_ICSELECTION_INDIRECTTI;
	HAL_TIM_IC_ConfigChannel(&htim, &sConfig, TIM_CHANNEL_2);
	
	//配置从模式为复位模式
	TIM_SlaveConfigTypeDef sSlaveConfig = {0};
	sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
	sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
	//sSlaveConfig.TriggerFilter = ;
	sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
	//sSlaveConfig.TriggerPrescaler = ;
	HAL_TIM_SlaveConfigSynchro(&htim, &sSlaveConfig);
	
	//启动输入捕获通道1中断
	HAL_TIM_IC_Start_IT(&htim, TIM_CHANNEL_1);
	
	//启动输入捕获通道2中断
	//HAL_TIM_IC_Start_IT(&htim, TIM_CHANNEL_2);
	HAL_TIM_IC_Start(&htim, TIM_CHANNEL_2);
}

void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
	//使能定时器1时钟
	__HAL_RCC_TIM1_CLK_ENABLE();
	
	//使能AFIO时钟
	__HAL_RCC_AFIO_CLK_ENABLE();
	
	//开启TIM1重映射
	__HAL_AFIO_REMAP_TIM1_ENABLE();
	
	//使能GPIOE时钟
	__HAL_RCC_GPIOE_CLK_ENABLE();
	
	GPIO_InitTypeDef GPIO_Init;
	
	GPIO_Init.Mode = GPIO_MODE_INPUT;
	GPIO_Init.Pin = GPIO_PIN_9;
	GPIO_Init.Pull = GPIO_NOPULL;
	
	//设置PE9 CH1为输入模式
	HAL_GPIO_Init(GPIOE, &GPIO_Init);
	
	HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
	
	HAL_NVIC_SetPriority(TIM1_CC_IRQn,2,2);
}

uint16_t CNT1 = 0;
uint16_t CNT2 = 0;
void TIM1_CC_IRQHandler(void)
{
	//HAL_TIM_IRQHandler(&htim);
	if(__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_CC1))
	{
		CNT1 = HAL_TIM_ReadCapturedValue(&htim, TIM_CHANNEL_1);
		//CNT1 = __HAL_TIM_GET_COMPARE(&htim, TIM_CHANNEL_1);
		//CNT1 = TIM1->CCR1;
		__HAL_TIM_CLEAR_FLAG(&htim, TIM_FLAG_CC1);
	}
	if(__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_CC2))
	{
		CNT2 = __HAL_TIM_GET_COMPARE(&htim, TIM_FLAG_CC2);
		__HAL_TIM_CLEAR_FLAG(&htim, TIM_CHANNEL_2);
	}
}


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM1)
	{
		if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1))
		{
			CNT1 = __HAL_TIM_GET_COMPARE(htim, TIM_FLAG_CC1);
		}
		if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2))
		{
			CNT2 = __HAL_TIM_GET_COMPARE(htim, TIM_FLAG_CC2);
		}
	}
}

main.c主函数

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/atim.h"
#include "./BSP/TIMER/pwm.h"
#define t 1/72000000
extern uint16_t CNT1;
extern uint16_t CNT2;
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
	sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    led_Init();                         /* LED初始化 */
	usart_init(115200);
	TIM_PWM_Init();
	Advanced_TIM_Init();
	int fre = 0;
	double duty = 0;
	
    while(1)
    { 
		LED0(1);
		LED1(0);
		delay_ms(500);
		
		LED0(0);
		LED1(1);
		delay_ms(500);
		duty = (((double)CNT2 + 1 )) * 100 / ( CNT1 + 1 );
		fre = 72000000 / (CNT1 + 1 ); 
		printf("频率为%d,占空比为%f\r\n",fre,duty);
    }
}
相关推荐
零下273°4 小时前
51单片机蜂鸣器铃声代码
单片机·嵌入式硬件·51单片机
聪聪06065 小时前
使用STM32F103C8T6和ESP8266链接阿里云
stm32·嵌入式硬件·阿里云
鹿屿二向箔5 小时前
单片机上SPI和IIC的区别
单片机·嵌入式硬件
weixin_580382066 小时前
STC51 P0 口 与P1 口输出
单片机·嵌入式硬件
爱吃奶酪的松鼠丶7 小时前
51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤
嵌入式硬件·51单片机·接口隔离原则
一只搬砖的猹8 小时前
PCA9685舵机控制板使用
stm32·单片机·嵌入式硬件·mcu·pwm·舵机·舵机驱动
零下273°9 小时前
51单片机俄罗斯方块开机动画
单片机·嵌入式硬件·51单片机
浅陌pa9 小时前
04:定时器
c语言·单片机·嵌入式硬件·51单片机
╰⋛⋋⊱⋋翅膀⋌⊰⋌⋚╯9 小时前
STM32-启动文件
stm32·单片机