STM32 定时器(单脉冲模式)

⚙️ ​一、实现原理

  1. 重复计数器(RCR)的作用

    • RCR 是高级定时器独有的寄存器,用于控制更新事件(Update Event, UEV)​​ 的触发频率。
    • 工作流程​:
      • 每次定时器溢出(上溢或下溢)时,RCR 值自动减 1。
      • 当 RCR 递减至 ​0​ 后,下一次溢出时触发更新事件(UEV),并可能停止定时器。
  2. 脉冲数与 RCR 的关系

    • 关键公式​:输出脉冲数=N=TIM_RepetitionCounter+1
      • 例如:设置 TIM_RepetitionCounter = 9 → 输出 ​10​ 个脉冲后停止。
    • 原因​:
      • 定时器从初始值开始计数,每溢出一次产生一个完整脉冲。
      • RCR 的递减从初始值 N−1 开始,需经过 N 次溢出才能归零并触发停止条件。
  3. 停止机制

    • 若启用单脉冲模式(OPM)​,在 RCR 归零后的更新事件中,定时器自动停止计数并关闭输出。

🔧 ​二、配置步骤(标准库示例)​

1. ​基础定时器配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period                 = 999;                // ARR值(决定PWM周期)
TIM_TimeBaseStruct.TIM_Prescaler              = 71;                 // PSC值(72MHz→1MHz)
TIM_TimeBaseStruct.TIM_CounterMode            = TIM_CounterMode_Up; // 递增模式
TIM_TimeBaseStruct.TIM_ClockDivision          = TIM_CKD_DIV1;
TIM_TimeBaseStruct.TIM_RepetitionCounter      = N-1;                // 输出N个脉冲
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);                        // 初始化定时器
  • 关键点​:
    • TIM_Period 和 TIM_Prescaler 决定单个脉冲的周期(频率)。
2. ​启用单脉冲模式
TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single); // 单脉冲模式:输出完成后停止
  • 作用​:确保输出 N 个脉冲后定时器自动停止。
3. ​配置PWM输出通道
	TIM_OCInitTypeDef TIM_OCStruct;
    TIM_OCStruct.TIM_OCMode 				= TIM_OCMode_PWM1;        // PWM模式1
    TIM_OCStruct.TIM_OutputState 			= TIM_OutputState_Enable;
    TIM_OCStruct.TIM_Pulse 					= 500;                     // 占空比50%(CCR=500)
    TIM_OCStruct.TIM_OCPolarity 			= TIM_OCPolarity_Low;
    TIM_OC2Init(TIM1, &TIM_OCStruct);
  • 说明​:占空比由 TIM_Pulse(CCR值)独立控制,与脉冲数无关。
4. ​启动定时器
TIM_CtrlPWMOutputs(TIM1, ENABLE);  // 高级定时器需使能主输出
TIM_Cmd(TIM1, ENABLE);             // 启动定时器

5. ​完整可用代码

// 引脚定义
#define PWM_PIN         GPIO_Pin_9       // PA9(TIM1_CH21)
#define PWM_PORT        GPIOA

// 定时器配置函数
void TIM1_OPM_Config(uint16_t pulse_count) 
{

    // 1. 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

    // 2. 配置PA8为复用推挽输出
	GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin 							= PWM_PIN;
    GPIO_InitStruct.GPIO_Mode 							= GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed 							= GPIO_Speed_50MHz;
    GPIO_Init(PWM_PORT, &GPIO_InitStruct);

    // 3. 定时器时基配置
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
    TIM_TimeBaseStruct.TIM_Period 						= 999;              // ARR:PWM周期=1000个计数
    TIM_TimeBaseStruct.TIM_Prescaler 					= 71;            	// PSC:72MHz/(71+1)=1MHz → 1us计数
    TIM_TimeBaseStruct.TIM_ClockDivision 				= TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_CounterMode 					= TIM_CounterMode_Up;
    TIM_TimeBaseStruct.TIM_RepetitionCounter 			= pulse_count - 1; // 输出脉冲数=pulse_count
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);

    // 4. 配置单脉冲模式
    TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single);  // 单次脉冲后停止

    // 5. PWM通道配置
	TIM_OCInitTypeDef TIM_OCStruct;
    TIM_OCStruct.TIM_OCMode 							= TIM_OCMode_PWM1;        // PWM模式1
    TIM_OCStruct.TIM_OutputState 						= TIM_OutputState_Enable;
    TIM_OCStruct.TIM_Pulse 								= 500;                     // 占空比50%(CCR=500)
    TIM_OCStruct.TIM_OCPolarity 						= TIM_OCPolarity_Low;
    TIM_OC2Init(TIM1, &TIM_OCStruct);

    // 6. 使能主输出(高级定时器必需)
    TIM_CtrlPWMOutputs(TIM1, ENABLE);                 // 

    // 7. 配置更新中断(可选)
	NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel 					= TIM1_UP_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 	= 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority 			= 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd 					= ENABLE;
    NVIC_Init(&NVIC_InitStruct);
	
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

    // 8. 初始化时禁用定时器
    TIM_Cmd(TIM1, DISABLE);
}

// 触发一次脉冲序列
void TIM1_TriggerPulse(void) 
{
    TIM_Cmd(TIM1, DISABLE);           					// 先停止定时器
    TIM_SetCounter(TIM1, 0);          					// 计数器归零
    TIM_GenerateEvent(TIM1, TIM_EventSource_Update); 	// 强制更新事件
    TIM_Cmd(TIM1, ENABLE);            					// 启动定时器
}

// 中断服务函数
volatile uint8_t pulse_complete = 0;
void TIM1_UP_IRQHandler(void) 
{
    if (TIM_GetITStatus(TIM1, TIM_IT_Update)) 
	{
        TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
        pulse_complete = 1;  // 标记脉冲完成
        // 此处可添加脉冲结束后的处理代码
    }
}


int main(void) 
{
    // 初始化系统时钟(根据实际晶振配置)

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
	Key_GPIO_Config();
    // 配置输出10个脉冲
    TIM1_OPM_Config(5); 

    while (1) {
        // 示例:按键触发脉冲
        if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON) 
		{
//            pulse_complete = 0;
            TIM1_TriggerPulse();
            
            // 等待脉冲完成(可选)
//            while(!pulse_complete);
        }
    }
}



⚡️ ​三、工作流程

  1. 计数阶段

    • 定时器从 0 开始递增,每达到 ARR 值(周期结束)产生一个完整脉冲,同时 RCR 减 1。
    • 示例​(N=10):
      • 第 1 个脉冲 → RCR 值从 9 减至 8
      • 第 9 个脉冲 → RCR 值从 1 减至 0
      • 第 10 个脉冲 → 溢出时触发更新事件(RCR=0)。
  2. 停止阶段

    • 当 RCR 归零后的下一次溢出时:
      • 触发更新事件(UEV)。
      • 单脉冲模式生效,定时器停止计数,PWM 输出关闭。

🔌 四GPIO_Mode_AF_PP:复用推挽输出模式

作用与原理​:
在用户代码中,引脚配置为GPIO_Mode_AF_PP(复用推挽输出)是为了将PA9(TIM1_CH2)​​ 作为定时器的PWM输出引脚。以下是关键原因:

  1. 硬件自动控制

    • 复用模式(Alternate Function)表示引脚由外设(如TIM1)直接控制电平,而非CPU软件控制。
    • 推挽输出(Push-Pull)结构由P-MOS和N-MOS管组成,可主动输出高/低电平,驱动能力强(如驱动LED、电机驱动器)。
  2. 适用场景

    • PWM输出​:如定时器的PWM信号(TIM1_CH2),需硬件自动生成精确波形,无需CPU干预。
    • 高速信号​:推挽结构支持高电平切换速度(50MHz),适合PWM等时序敏感应用。
  3. 配置要点

    • 复用功能映射​:必须调用GPIO_PinAFConfig()(用户代码未显式调用,但HAL库可能内部处理)。
    • 速度配置​:GPIO_Speed_50MHz确保PWM边沿陡峭,减少信号失真。

✅ ​为何不用普通推挽输出(GPIO_Mode_Out_PP)?​
普通推挽需CPU写寄存器控制电平,而PWM要求硬件自动生成精确波形,CPU无法实时响应。

⚡ ​五TIM_GenerateEvent(TIM1, TIM_EventSource_Update):强制更新事件

作用与原理​:
TIM1_TriggerPulse()函数中,此操作通过软件触发更新事件(Update Event)​,实现寄存器值的立即生效:

  1. 更新事件的功能

    • 将预装载寄存器(ARR、PSC、CCR)的值同步到影子寄存器(实际生效的寄存器)。
    • 复位计数器(CNT)为0,并清除状态标志。
  2. 为何需要强制触发?​

    • 单脉冲模式要求​:
      • 用户配置了TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single),表示定时器在输出指定脉冲数后自动停止。
      • 每次启动新脉冲序列前,需复位计数器(CNT)并重载参数(如TIM_RepetitionCounter = pulse_count - 1)。
    • 避免首次脉冲异常​:
      若不强制更新,首次脉冲的周期可能使用旧参数(影子寄存器未更新)。

⚠️ ​六、注意事项

  1. 仅支持高级定时器

    • RCR 功能仅限 ​TIM1/TIM8​(STM32F1/F4系列),通用定时器需用中断或主从模式替代。
  2. RCR 取值范围

    • RCR 值通常为 ​0~255​(具体取决于型号),超出范围可能导致行为异常。
  3. 与中断的配合

    • 若需在脉冲结束后执行任务(如关闭外设),可启用更新中断:
      TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); // 使能更新中断
      • 中断中检测 RCR 状态并处理后续逻辑。
  4. 频率与脉冲数的平衡

    • 高频率 PWM 时,RCR 值不宜过大(避免计数器溢出)。
    • 最大脉冲数​ = (ARR+1)×(RCRmax​+1),受限于定时器位数。

💎 ​总结

通过 ​TIM_RepetitionCounter = N-1 实现固定脉冲输出的核心是:

  • 硬件自动递减​:RCR 在每次溢出时减 1,零值触发更新事件。
  • 单脉冲模式​:更新事件中自动停止定时器,确保精确输出 N 个脉冲。
  • 完全硬件控制​:规避了软件中断的延迟误差,适用于步进电机驱动、精密脉冲发生器等高精度场景。

配置时需严格匹配单脉冲模式与 RCR 值,并验证目标定时器是否支持该功能。实测可通过示波器观察输出脉冲数量及占空比稳定性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值