stm32高级TIM的常用功能

news/2025/2/22 9:41:43/

介绍 STM32 高级定时器的刹车死区、互补输出、输入捕获 的基本资料。

1. 刹车死区(Brake Dead Time)

高级定时器(如 TIM1TIM8)支持 刹车死区(Brake Dead Time) 功能,通常用于电机控制和其他需要安全保护的应用。广泛用于车载测试以及工控检测.

  • 死区时间:死区时间是控制信号之间的延迟时间,用于避免两个互补输出信号同时切换而导致的短路。
  • 用途:在电机驱动系统中,死区时间可以防止两个互补信号(如正反向驱动信号)发生冲突,从而保护硬件。

2. 互补输出(Complementary Output)

高级定时器支持 互补输出,这是用于控制例如 H 桥电路电机驱动 的功能。互补输出提供两路反向的 PWM 信号,通常用于驱动逆变器或其他电力设备。

  • 工作原理:两个输出信号(如 PWM1PWM2)是互补的,当 PWM1 为高时,PWM2 为低,反之亦然。
  • 优点:互补输出可以有效驱动电机或逆变器系统,同时避免短路或损坏电路。

3. 输入捕获(Input Capture)

输入捕获用于 测量输入信号的时间特性,如频率、脉冲宽度等。它通常用于 PWM 信号的测量外部事件的计时

配置流程

  • 工作原理:当输入信号(如外部触发引脚)发生变化时,定时器会捕获 计数器值,从而记录信号的时间。

    STM32 TIM 输入捕获原理

    输入捕获(Input Capture) 是 STM32 定时器的一个重要功能,用于测量外部信号的时间特性。它允许你捕获输入信号的 边沿(上升沿或下降沿),并记录定时器的 计数值。输入捕获常用于测量 脉冲宽度频率时间间隔

    基本原理

    输入捕获利用定时器的计数器来捕获外部信号发生变化的时间。捕获信号的触发通常发生在 输入引脚(如 TIMx_CH1、TIMx_CH2)电平变化(如从低电平到高电平,或从高电平到低电平)。

  • 计数器和输入信号

    • 当外部输入信号发生边沿变化时,定时器会记录下当前计数器的值。
    • 你可以通过获取两次捕获事件的计数器值来计算外部信号的时间特性,比如 脉冲宽度频率
  • 输入信号的类型

    • 上升沿触发:当输入信号从低电平变为高电平时,触发输入捕获。
    • 下降沿触发:当输入信号从高电平变为低电平时,触发输入捕获。
    • 双边沿触发:捕获信号的上升沿和下降沿,通常用于测量周期。
  • 定时器的工作模式

    • 在捕获模式下,定时器的计数器值将在外部信号的变化时存储到捕获寄存器中。
    • 可以通过读取捕获寄存器的值,得到信号的捕获时间。
  • 应用场景

    • 频率测量:通过捕获连续的两个上升沿(或下降沿),可以计算信号的周期,从而得到频率。
    • 脉冲宽度测量:通过计算捕获的两个信号的时间差,得到脉冲的宽度。
    • 时间间隔测量:计算两个信号之间的时间差,应用于事件计时或延迟分析。
  • 启用定时器和输入捕获功能

    • 配置定时器的 计数器预分频器计数模式
    • 配置 输入引脚,如 GPIO 模式设置为输入浮动。
    • 配置定时器的输入捕获通道,如 TIM1_CH1TIM2_CH2 等。
  • 配置输入捕获参数

    • 设置捕获的 触发边沿(上升沿、下降沿或双边沿)。
    • 设置捕获 分频器滤波器,以便根据需求过滤信号。
  • 读取捕获数据

    • 当信号发生变化时,定时器会将捕获的计数器值存储到捕获寄存器。
    • 可以通过 获取捕获寄存器值,来计算时间间隔或脉冲宽度。
  • 中断和回调函数

    • 可以使能 捕获中断,当捕获事件发生时触发中断,进入回调函数处理捕获的计数器值。
    • 通过 TIM
  • 应用场景
    • 频率测量:通过捕获输入信号的周期,可以计算信号的频率。
    • 脉冲宽度测量:通过测量高电平和低电平的持续时间,计算脉冲宽度。

代码示例

以下是一个使用 STM32 TIM1 高级定时器的示例,展示如何配置刹车死区和互补输出,并实现输入捕获功能。

1. TIM1 互补输出与死区时间配置
#include "stm32f10x.h"void TIM1_PWM_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM_BDTRInitTypeDef TIM_BDTRInitStructure;// 启用 TIM1 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// 配置 PWM 引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置定时器基础设置TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;  // 设置预分频TIM_TimeBaseStructure.TIM_Period = 1000 - 1;  // 设置周期TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);// 配置 PWM 输出TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC1Init(TIM1, &TIM_OCInitStructure);TIM_OC2Init(TIM1, &TIM_OCInitStructure);// 配置刹车死区时间TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;TIM_BDTRInitStructure.TIM_LockLevel = TIM_LockLevel_OFF;TIM_BDTRInitStructure.TIM_DeadTime = 10;  // 设置死区时间TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);// 启动定时器TIM_Cmd(TIM1, ENABLE);TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
2. 输入捕获配置
void TIM1_InputCapture_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;TIM_ICInitTypeDef TIM_ICInitStructure;// 启用 TIM1 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// 配置输入引脚(例如 PA8)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置定时器输入捕获TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  // 上升沿捕获TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  // 不分频TIM_ICInitStructure.TIM_ICFilter = 0x00;TIM_ICInit(TIM1, &TIM_ICInitStructure);// 启动定时器TIM_Cmd(TIM1, ENABLE);TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);  // 启用中断
}

总结

  • 刹车死区:用于保护电机驱动系统,防止互补输出信号同时高电平导致短路。
  • 互补输出:主要用于驱动 H 桥电路或电机控制系统,输出互补的 PWM 信号。
  • 输入捕获:用于测量输入信号的时间特性,如频率、脉冲宽度等。

项目:

1利用pwm输出互补波形,同时配置刹车死区功能,在TIM1_KBKIN引脚接低电平时,示波器显示pwm输出互补波形,在TIM1_BKIN引脚接高电平时抑制pwm输出,示波器不输出波形

操作:

1配置pwm原波形输出引脚GPIO以及pwm互补波形输出引脚以及刹车死区引脚(采用推挽输出)

2配置TIM基本结构体

3配置pwm互补输出以及原输出通道,初始化,调用预装载值使能输出函数

4配置刹车死区结构体并初始化

5使能TIM定时器

#include "stm32f10x.h"                  // Device header
#include "pwmplus.h"TIM_ICUserValue   TIM_CaptureSturt;
void pwmplus_GPIO_Config()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef   pwmplus_GPIO_Initsturt;//TIM1的输出通道CH1的   PA8pwmplus_GPIO_Initsturt.GPIO_Mode = GPIO_Mode_AF_PP;pwmplus_GPIO_Initsturt.GPIO_Pin =GPIO_Pin_8;pwmplus_GPIO_Initsturt.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &pwmplus_GPIO_Initsturt);//输出互补通道TIM1-CH1N   PB13pwmplus_GPIO_Initsturt.GPIO_Mode = GPIO_Mode_AF_PP;pwmplus_GPIO_Initsturt.GPIO_Pin =GPIO_Pin_13;pwmplus_GPIO_Initsturt.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &pwmplus_GPIO_Initsturt);//配置刹车通道 TIM1-BKIN   PB12pwmplus_GPIO_Initsturt.GPIO_Mode = GPIO_Mode_AF_PP;pwmplus_GPIO_Initsturt.GPIO_Pin =GPIO_Pin_12;pwmplus_GPIO_Initsturt.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &pwmplus_GPIO_Initsturt);GPIO_ResetBits(GPIOB,GPIO_Pin_12);}void pwmplus_Config()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//配置TIM1的基本结构体TIM_TimeBaseInitTypeDef  TIM1_Initsturt;TIM1_Initsturt.TIM_ClockDivision =TIM_CKD_DIV1;TIM1_Initsturt.TIM_CounterMode =TIM_CounterMode_Up;TIM1_Initsturt.TIM_Period =7;TIM1_Initsturt.TIM_Prescaler =8;TIM1_Initsturt.TIM_RepetitionCounter =0;TIM_TimeBaseInit(TIM1, &TIM1_Initsturt);//输出比较通道TIM1-CH1及其互补TIM_OCInitTypeDef   pwmplus_OCInitsturt;pwmplus_OCInitsturt.TIM_OCMode =TIM_OCMode_PWM1 ;pwmplus_OCInitsturt.TIM_OutputState = TIM_OutputState_Enable;pwmplus_OCInitsturt.TIM_OutputNState = TIM_OutputNState_Enable;pwmplus_OCInitsturt.TIM_Pulse =4;pwmplus_OCInitsturt.TIM_OCIdleState = TIM_OCIdleState_Set   ;pwmplus_OCInitsturt.TIM_OCNIdleState =  TIM_OCNIdleState_Reset ;  pwmplus_OCInitsturt.TIM_OCNPolarity = TIM_OCNPolarity_High ;pwmplus_OCInitsturt.TIM_OCPolarity = TIM_OCPolarity_High ;TIM_OC1Init(TIM1,&pwmplus_OCInitsturt);TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //预装载值输出使能//初始化刹车和死区的结构体TIM_BDTRInitTypeDef  pwm_BTR_Initsturt;pwm_BTR_Initsturt.TIM_AutomaticOutput =TIM_AutomaticOutput_Enable ;pwm_BTR_Initsturt.TIM_Break =TIM_Break_Enable ; //当BINK引脚检测到高电平时,输出信号被禁止,好像刹车一样pwm_BTR_Initsturt.TIM_BreakPolarity =TIM_BreakPolarity_High;pwm_BTR_Initsturt.TIM_DeadTime =11;  //死区时间设置为152nspwm_BTR_Initsturt.TIM_LOCKLevel =TIM_LOCKLevel_1 ;pwm_BTR_Initsturt.TIM_OSSIState =TIM_OSSIState_Enable ;pwm_BTR_Initsturt.TIM_OSSRState = TIM_OSSRState_Enable  ;TIM_BDTRConfig(TIM1, &	pwm_BTR_Initsturt);//使能计数器TIM_Cmd(TIM1,ENABLE);//主输出使能,用于高级定时器TIM_CtrlPWMOutputs(TIM1,ENABLE);}

项目二: 配置输入捕获按键按下产生的脉冲信号,并将信号转换成高电平持续的时间通过串口显示在上位机上

操作:

1//配置输入捕获脉冲频率引脚  PA0

2配置TIM基本结构体

3输入捕获结构体初始化

4启动更新时间函数中断(更新中断,以及捕获第一次上升沿中断)

5编写中断服务函数(检测第一次捕获的上升沿的计数值,同时转换成下降沿进行捕获)

6在主函数里面计算捕获值换算成时间

//配置输入捕获脉冲频率引脚  PA0
void General_TIM_Mode_GPIO()
{RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );GPIO_InitTypeDef  GPIO_TIM_Initsturt;GPIO_TIM_Initsturt.GPIO_Mode = GPIO_Mode_IN_FLOATING ;GPIO_TIM_Initsturt.GPIO_Pin =GPIO_Pin_0 ;GPIO_Init(GPIOB, &GPIO_TIM_Initsturt);}void General_TIM_Config()//TIM5
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);TIM_TimeBaseInitTypeDef    TIM_InitConfig;TIM_InitConfig.TIM_ClockDivision =TIM_CKD_DIV1;TIM_InitConfig.TIM_CounterMode =TIM_CounterMode_Up ;TIM_InitConfig.TIM_Period =0xFFFF;TIM_InitConfig.TIM_Prescaler = 72-1;TIM_InitConfig.TIM_RepetitionCounter =0;TIM_TimeBaseInit( TIM5, &TIM_InitConfig);//输入捕获结构体初始化TIM_ICInitTypeDef  TIM_IcInitsturt;TIM_IcInitsturt.TIM_Channel = TIM_Channel_1;//选择通道1TIM_IcInitsturt.TIM_ICFilter =0;TIM_IcInitsturt.TIM_ICPolarity =TIM_ICPolarity_Rising;//采用上升沿的方式TIM_IcInitsturt.TIM_ICPrescaler =TIM_ICPSC_DIV1 ;TIM_IcInitsturt.TIM_ICSelection =TIM_ICSelection_DirectTI;//选择直连的方式TIM_ICInit( TIM5, &	TIM_IcInitsturt);TIM_ClearFlag(TIM5,TIM_FLAG_Update|TIM_FLAG_CC1);//清楚更新和捕获中断标志位TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1, ENABLE );TIM_Cmd( TIM5, ENABLE );//配置TIM5输入捕获中断NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitTypeDef  nvic_Initsturt;nvic_Initsturt.NVIC_IRQChannel = TIM5_IRQn;nvic_Initsturt.NVIC_IRQChannelCmd =ENABLE  ;nvic_Initsturt.NVIC_IRQChannelPreemptionPriority =0;nvic_Initsturt.NVIC_IRQChannelSubPriority =0;NVIC_Init(&nvic_Initsturt);}void   TIM5_IRQHandler ()
{if(TIM_GetITStatus(TIM5,  TIM_IT_Update)==SET){
//当捕获信号的周期大于定时器的最长定长时,就会溢出产生更新中断,这时需要把最长定时时间周期加到捕获信号的时间里面去TIM_CaptureSturt.Capture_Period ++;TIM_ClearITPendingBit(TIM5, TIM_IT_Update);}//上升捕获中断if(TIM_GetITStatus(TIM5, TIM_IT_CC1 )==SET){//第一次捕获if(TIM_CaptureSturt.Capture_StartFlag ==0){//计数清零TIM_SetCounter( TIM5,0);//自动重装寄存器更新标志请0TIM_CaptureSturt .Capture_Period =0;//存放捕获比较寄存器的变量清0TIM_CaptureSturt .Capture_CorValue =0;//当第一次捕获到上升沿时就把捕获边沿配置为下降沿TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_Low);//标志位置为1TIM_CaptureSturt .Capture_StartFlag =1;}//下降沿捕获else{//第二次捕获//获取捕获比较器的值,这个值就是捕获到的高电平时间的值TIM_CaptureSturt .Capture_CorValue =TIM_GetCapture1(TIM5);//当第二次捕获到下降沿后,就把捕获边沿配置为上升沿,开启新的一轮捕获TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_High);//开始捕获标志清0TIM_CaptureSturt .Capture_StartFlag =0;//捕获完成标志置1TIM_CaptureSturt .Capture_FinishFlag =1;}TIM_ClearITPendingBit(TIM5,TIM_IT_CC1 );}}
 uint32_t time;uint32_t TIM_pscCLK  =72000000/9;usart_Config();usart_GPIO_Config();General_TIM_Config( );General_TIM_Mode_GPIO( );printf("\r\n野火 STM32 输入捕获实验\r\n");printf ("\r\n按下K1,测试K1的按下时间\r\n");
//	while(1){if(TIM_CaptureSturt .Capture_FinishFlag ==1){//计算高电平时间的计数值time=  TIM_CaptureSturt .Capture_Period *(7+1)+(TIM_CaptureSturt .Capture_CorValue +1);//打印高电平脉宽时间printf ("\r\n测得高电平时间:%d.%d  s\r\n",time/TIM_pscCLK,time%TIM_pscCLK);TIM_CaptureSturt .Capture_FinishFlag =0;}}
}


http://www.ppmy.cn/news/1574121.html

相关文章

Spring全面讲解(无比详细)

1、Spring框架体系 2、 IOC 2.1 什么是IOC 2.3 基于 配置文件的di实现 2.3.1 什么是di 2.3.2 入门案例 2.3.3 环境搭建 2.3.4 案例总结 2.3.5 简单类型属性的赋值(set注入) 2.3.6 非简单类型属性的赋值(set注入) 2.3.7 构造注入 …

Springboot中分析SQL性能的两种方式

SQL性能分析的两种方式: 功能介绍 记录 SQL 执行时间,超过阈值会进行警告打印完整的 SQL 语句,便于调试和优化适用于开发和测试环境,生产环境建议关闭 实现方式: 方式一:使用 MyBatis-Plus 性能分析插件 首先需要在MyBatis-Plus配置类中配…

在mfc中使用自定义三维向量类和计算多个三维向量的平均值

先添加一个普通类, Vector3.h, // Vector3.h: interface for the Vector3 class. // //#if !defined(AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_) #define AFX_VECTOR3_H__53D34D26_95FF_4377_BD54_57F4271918A4__INCLUDED_#if _MSC_VER > 1000 #p…

【多模态大模型】端侧语音大模型minicpm-o:手机上的 GPT-4o 级多模态大模型

MiniCPM-o ,它是一款 开源、轻量级 的多模态大语言模型,目标是在手机等资源受限的环境中实现 GPT-4o 级别的多模态能力! 1. MiniCPM-o:小身材,大能量! MiniCPM-o 的名字已经暗示了它的核心特点&#xff…

人工智能之自动驾驶技术体系

自动驾驶技术体系 自动驾驶技术是人工智能在交通领域的重要应用,旨在通过计算机视觉、传感器融合、路径规划等技术实现车辆的自主驾驶。自动驾驶不仅能够提高交通效率,还能减少交通事故和环境污染。本文将深入探讨自动驾驶的技术体系,包括感…

C++ 多态详解

文章目录 1. 什么是多态1.1 静态多态和动态多态 2. 动态多态2.1 动态多态的实现2.2 虚函数2.2.1 虚函数的重写2.2.2 虚函数协变2.2.3 析构函数的重写2.2.4 override和final 3. 动态多态原理解析3.1 _vfptr3.2 动态绑定与静态绑定3.3 虚函数表详解 4. 纯虚函数和抽象类5. 重载、…

二级公共基础之数据结构与算法篇(八)排序技术

目录 前言 一、交换类排序 1.冒泡排序法 1. 冒泡排序的思想 2. 冒泡排序的实现步骤 3. 示例 4. 冒泡排序的特点 2.快速排序 1. 快速排序的核心思想 2. 快速排序的实现步骤 3. 示例代码(C语言) 4. 快速排序的特点 二、插入类排序 1. 简单插入排序 1.简单插入排…

质因数分解

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 Nancy喜欢博弈! Johnson和Nancy得到了一个神奇的多重集合,仅包含一个正整数n,两个人轮流进行操作。 一次操作可以将集合中一个数字分解为它的任意…