第十五章 TIM高级定时器(下)

文章详细介绍了STM32F10x微控制器中高级定时器的使用,包括如何实现精确计时,产生PWM波以及配置为互补输出,以及输入捕获功能。通过实验要求、软件设计和下载验证,展示了如何配置定时器参数,初始化GPIO,设置中断服务函数,以及通过不同占空比的PWM波来控制LED和蜂鸣器。此外,还涵盖了输入捕获的应用,用于测量PWM波的频率和占空比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

14.6 使用高级定时器实现精确计时

14.6.1 实验要求

14.6.2 软件设计

14.6.3 下载验证

14.7 TIM高级定时器PWM波互补输出

14.7.1 PWM波是什么

14.7.2 实验要求

14.7.3 软件设计

14.7.4 下载验证

14.8 TIM高级定时器输入捕获

14.6.1 实验要求

14.6.2 软件设计

14.6.3 下载验证


14.6 使用高级定时器实现精确计时

14.6.1 实验要求

        使用高级定时器实现LED灯和蜂鸣器状态1s翻转一次。

14.6.2 软件设计

14.6.2.1 设计思路

        首先对高级定时器的时钟,周期,中断等信息进行宏定义即bsp_AdvanceTim.h文件便于之后对代码的移植,完成后需要对定时器的模式和中断优先级进行配置即bsp_AdvaceTim.c文件,配置完成过后还需要在stm32f10x_it.c文件中编写中断服务函数,以上都完成后就能够在main.c文件中编写我们所需要的功能代码了。

14.6.2.2 代码分析

bsp_AdvanceTim.h

#ifndef _BSP_ADVANCETIM_H
#define _BSP_ADVANCETIM_H

#include "stm32f10x.h"

#define ADVANCE_TIM1	

#ifdef 	ADVANCE_TIM1 	//使用高级定时器1
#define ADVANCE_TIM						TIM1
#define ADVANCE_TIM_APBxClock_FUN		RCC_APB2PeriphClockCmd
#define ADVANCE_TIM_CLK					RCC_APB2Periph_TIM1
#define ADVANCE_TIM_Period				(1000-1)
#define ADVANCE_TIM_Prescaler			71
#define ADVANCE_TIM_IRQ					TIM1_UP_IRQn
#define ADVANCE_TIM_IRQHandler			TIM1_UP_IRQHandler

#else				//使用高级定时器8
#define ADVANCE_TIM						TIM8 
#define ADVANCE_TIM_APBxClock_FUN		RCC_APB2PeriphClockCmd
#define ADVANCE_TIM_CLK					RCC_APB2Periph_TIM8
#define ADVANCE_TIM_Period				(1000-1)
#define ADVANCE_TIM_Prescaler			71
#define ADVANCE_TIM_IRQ					TIM8_UP_IRQn
#define ADVANCE_TIM_IRQHandler			TIM8_UP_IRQHandler

#endif

void ADVANCE_TIM_Init(void);

#endif /*_BSP_ADVANCETIM_H*/

bsp_AdvanceTim.c

#include "bsp_AdvanceTim.h"

static void ADVANCE_TIM_Mode_Config(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	
	//开启定时器时钟,即内部CK_INT = 72M
	ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE);
	
	//自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
	TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_Period;
	
	//时钟分频系数
	TIM_TimeBaseStructure.TIM_Prescaler = ADVANCE_TIM_Prescaler;
	
	//时钟分频因子,基本定时器没有不用管
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
	//计数器的计数模式,基本定时器只能向上计数,没有计数模式的设置
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	//重复计数器的值,基本定时器没有,不用管
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	
	//初始化定时器
	TIM_TimeBaseInit(ADVANCE_TIM,&TIM_TimeBaseStructure);
	
	//清除计数器的中断标志位
	TIM_ClearFlag(ADVANCE_TIM,TIM_FLAG_Update);
	
	//开启计数器中断
	TIM_ITConfig(ADVANCE_TIM,TIM_IT_Update,ENABLE);
	
	//使能计数器
	TIM_Cmd(ADVANCE_TIM,ENABLE);
}

static void ADVANCE_TIM_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	//设置中断优先级分组位0
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
	//设置中断源
	NVIC_InitStruct.NVIC_IRQChannel = ADVANCE_TIM_IRQ;
	
	//设置主优先级为0
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	 
	//设置抢占优先级为3
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
	
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&NVIC_InitStruct);
}

void ADVANCE_TIM_Init(void)
{
	ADVANCE_TIM_NVIC_Config();
	ADVANCE_TIM_Mode_Config();
}

中断服务函数

#include "stm32f10x_it.h"
#include "bsp_AdvanceTim.h"

extern volatile uint32_t time;
void ADVANCE_TIM_IRQHandler(void)
{
	if ( TIM_GetITStatus(ADVANCE_TIM, TIM_IT_Update) != RESET ) 
	{	
		time++;
		TIM_ClearITPendingBit(ADVANCE_TIM, TIM_FLAG_Update);  		 
	}
}

main.c

#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_buzzer.h"
#include "bsp_AdvanceTim.h"

volatile uint32_t time = 0;		//ms计时变量

int main(void)
{
	LED_GPIO_Config();
	
	ADVANCE_TIM_Init();
	
	BUZZER_GPIO_Config();
	
	while(1)
	{
		//1000 * 1ms = 1s
		if(time == 1000)
		{
			time = 0;
			
			LED2_Toggle;
			BUZZER_Toggle;
		}
	}
}

14.6.3 下载验证

        编译下载到开发板中能够观察到板载的LED灯和蜂鸣器亮,响一秒,反复循环此状态。

14.7 TIM高级定时器PWM波互补输出

14.7.1 PWM波是什么

        PWM波(Pulse Width Modulation),即脉宽调制,是一种用于控制电子元件(如开关、电机、LED等)的技术。它通过改变脉冲的宽度和周期来控制电流或电压的大小,从而实现对目标设备的精确控制。

        PWM波可以通过快速切换电源开关来产生,其中一段时间为高电平,另一段时间为低电平。这样产生的信号被称为矩形波形。改变矩形波形的频率,可以改变PWM波信号所控制器件的响应速度。当频率高于人耳能听到的范围时,人们无法感知。

        通常情况下,PWM波信号被用于控制DC电机、步进电机、LED灯等。以LED为例,当PWM波信号中高电平占空比较大时,即高电平时间长且低电平时间短时,LED会发出较亮的光芒。反之,则发出弱光。因此,通过控制PWM波信号的占空比来调节LED灯的亮度。

        总之,PWM波作为一种常见的控制技术,在工业生产中有着广泛应用,并得到了很好的实践效果。

14.7.2 实验要求

        实现频率为1MHz占空比50%的PWM波并使用KingstLA1010逻辑分析仪或者使用Keil5自带的仿真器观察输出的波形。

14.7.3 软件设计

14.7.3.1 设计思路

        首先对定时器用到的 GPIO 初始化,定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化,定时器输出比较结构体 TIM_OCInitTypeDef 初始化,定时器刹车和死区结构体 TIM_BDTRInitTypeDef 初始化。

14.7.3.2 代码分析

bsp_AdvanceTim.h

#ifndef _BSP_ADVANCETIM_H
#define _BSP_ADVANCETIM_H

#include "stm32f10x.h"

#define ADVANCE_TIM                   TIM1
#define ADVANCE_TIM_APBxClock_FUN     RCC_APB2PeriphClockCmd
#define ADVANCE_TIM_CLK               RCC_APB2Periph_TIM1

// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}
#define ADVANCE_TIM_PERIOD            (8-1)
#define ADVANCE_TIM_PSC               (100-1)
#define ADVANCE_TIM_PULSE             4

#define ADVANCE_TIM_IRQ               TIM1_UP_IRQn
#define ADVANCE_TIM_IRQHandler        TIM1_UP_IRQHandler

// TIM1 输出比较通道
#define ADVANCE_TIM_CH1_GPIO_CLK      RCC_APB2Periph_GPIOA
#define ADVANCE_TIM_CH1_PORT          GPIOA
#define ADVANCE_TIM_CH1_PIN           GPIO_Pin_8
 
// TIM1 输出比较通道的互补通道
#define ADVANCE_TIM_CH1N_GPIO_CLK      RCC_APB2Periph_GPIOB
#define ADVANCE_TIM_CH1N_PORT          GPIOB
#define ADVANCE_TIM_CH1N_PIN           GPIO_Pin_13

// TIM1 输出比较通道的刹车通道
#define ADVANCE_TIM_BKIN_GPIO_CLK      RCC_APB2Periph_GPIOB
#define ADVANCE_TIM_BKIN_PORT          GPIOB
#define ADVANCE_TIM_BKIN_PIN           GPIO_Pin_12

void ADVANCE_TIM_Init(void);

#endif /*_BSP_ADVANCETIM_H*/

bsp_AdvanceTim.c

#include "bsp_AdvanceTim.h"

static void ADVANCE_TIM_GPIO_Config(void) 
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//输出比较通道GPIO端口初始化
	RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPI
### STM32F1 高级定时器 CHIN PWM 配置方法 #### 定义PWM频率 PWM信号的频率决定了PWM完成一个周期的速度,在STM32中,通过设置预分频器和自动重装载寄存器可以调整PWM频率。对于STM32F1系列微控制器而言,MDK编译器支持多种工作频率的选择,例如5MHz, 10MHz, 20MHz以及50MHz[^1]。 #### 使用TIM1_CH1N配置反相PWM输出 针对STM32F1系列中的高级定时器TIM1,其具备多个通道用于生成PWM波形。特别是当涉及到互补(即极性相反)PWM输出时,比如TIM1_CH1N连接到PB14引脚上,该引脚能够作为SPI2_MISO或TIM1_CH2N功能复用;同样地,PB15也可以被配置成TIM1_CH3N来实现类似的PWM输出效果,这两个引脚所发出的PWM脉冲与对应的正向通道相比具有相反的电平状态[^2]。 #### 示例代码展示如何初始化并启动基于TIM1_CH1N的PWM输出 下面是利用标准外设库编写的一个简单例子,展示了怎样配置TIM1的第一个互补通道(CH1N),并通过指定GPIO端口(PB14)发送PWM信号: ```c #include "stm32f1xx.h" void TIM_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Enable the TIM1 and GPIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOB, ENABLE); // Configure PB14 as alternate function push-pull output (TIM1_CH1N) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // Time base configuration TIM_DeInit(TIM1); TIM_InternalClockConfig(TIM1); TIM_TimeBaseStructure.TIM_Period = 999; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); // Channel N Configuration TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMODE_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 499; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_OC1Init(TIM1,&TIM_OCInitStructure); // Complementary channel enable TIM_BDTRInitStruct.TIM_OSSRState=TIM_OSSR_Disable; TIM_BDTRInitStruct.TIM_LOCKLevel=TIM_LOCKLevel_OFF; TIM_BDTRInitStruct.TIMDeadTime=0x0; TIM_BDTRInitStruct.TIM_Break=TIM_Break_Disable; TIM_BDTRInitStruct.TIM_BreakPolarity=TIM_BreakPolarity_High; TIM_BDTRInitStruct.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1,&TIM_BDTRInitStruct); } int main(){ TIM_Config(); TIM_Cmd(TIM1,ENABLE); } ``` 此段程序实现了对STM32F1芯片上的TIM1计数器进行初始化,并设置了它的第一个互补通道(CH1N)为PWM模式,最终使得PB14引脚能按照设定参数输出PWM方波.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

KermanXin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值