STM32——高级定时器输出比较模式实验

这篇具有很好参考价值的文章主要介绍了STM32——高级定时器输出比较模式实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1高级定时器输出比较模式实验

1.1高级定时器输出比较模式实验原理

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

1.2高级定时器输出比较模式实验实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_OC_Init()
2,定时器PWM输出MSP初始化 HAL_TIM_OC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置PWM模式/比较值等 HAL_TIM_OC_ConfigChannel()
4,使能通道预装载 __HAL_TIM_ENABLE_OCxPRELOAD()
5,使能输出、主输出、计数器 HAL_TIM_OC_Start()
6,修改捕获/比较寄存器的值 _HAL_TIM_SET_COMPARE()
STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

1.3 高级定时器输出比较模式实验要求

1)通过定时器8通道1/2/3/4输出相位分别为25%、50%、75%、100%的PWM
2,配置输出比较模式为:翻转
通道输出极性为:高电平有效

2 高级定时器互补输出带死区控制实验

2.1互补输出 死区时间

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

2.3带死区控制的互补输出应用H桥

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

2.4捕获/比较通道的输出部分(通道1至3)

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

2.5死区时间计算

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

2.6 刹车(断路)功能

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机
TIMx_BKIN: IO复用口
BI由BRK(输入信号极性)故障事件决定

2.7高级定时器互补输出带死区控制实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_PWM_Init()
2,定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()
4,配置刹车功能、死区时间等 HAL_TIMEx_ConfigBreakDeadTime()
5,使能输出、主输出、计数器 HAL_TIM_PWM_Start()
6,使能互补输出、主输出、计数器 HAL_TIMEx_PWMN_Start()
STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

2.8刹车死区时间结构体

typedef struct
{
uint32_t OffStateRunMode; /* 运行模式下的关闭状态选择 /
uint32_t OffStateIDLEMode; /
空闲模式下的关闭状态选择 /
uint32_t LockLevel; /
寄存器锁定设置 /
uint32_t DeadTime; /
死区时间设置 /
uint32_t BreakState; /
是否使能刹车功能 /
uint32_t BreakPolarity; /
刹车输入极性 /
uint32_t BreakFilter; /
刹车输入滤波器(F1/F4系列没有) /
uint32_t AutomaticOutput; /
自动恢复输出使能,即使能AOE位 */
} TIM_BreakDeadTimeConfigTypeDef;

2.9 高级定时器输出比较模式实验要求

1)通过定时器1通道1输出频率为1KHz,占空比为70%的PWM,使用PWM模式1
使能互补输出并设置死区时间控制:设置DTG为100(5.56us),进行验证死区时间是否正确
使能刹车功能:刹车输入信号高电平有效,配置输出空闲状态等,最后用示波器验证
2)H桥为例,配置通道输出极性以及互补输出极性
高级定时器输入原理

3 高级定时器输入模式实战

3.1 高级定时器输入模式工作原理

STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机
STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

3.2 高级定时器PWM输入模式实验配置步骤

1,配置定时器基础工作参数 HAL_TIM_IC_Init()
2,定时器捕获输入MSP初始化 HAL_TIM_IC_MspInit() 配置NVIC、CLOCK、GPIO等
3,配置IC1/2映射、捕获边沿等 HAL_TIM_IC_ConfigChannel()
4,配置从模式,触发源等 HAL_TIM_SlaveConfigSynchro()
5,设置优先级,使能中断 HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
6,使能捕获、捕获中断及计数器 HAL_TIM_IC_Start_IT()、 HAL_TIM_IC_Start()
7,编写中断服务函数 TIMx_IRQHandler()等 HAL_TIM_IRQHandler()
8,编写输入捕获回调函数 HAL_TIM_IC_CaptureCallback()
STM32——高级定时器输出比较模式实验,stm32,嵌入式硬件,单片机

3.3 关键结构体

typedef struct
{
uint32_t ICPolarity; /* 输入捕获触发方式选择,比如上升、下降沿捕获 /
uint32_t ICSelection; /
输入捕获选择,用于设置映射关系 /
uint32_t ICPrescaler; /
输入捕获分频系数 /
uint32_t ICFilter; /
输入捕获滤波器设置 */
} TIM_IC_InitTypeDef;

typedef struct
{
uint32_t SlaveMode; /* 从模式选择 /
uint32_t InputTrigger; /
输入触发源选择 /
uint32_t TriggerPolarity; /
输入触发极性 /
uint32_t TriggerPrescaler; /
输入触发预分频 /
uint32_t TriggerFilter; /
输入滤波器设置 */
} TIM_SlaveConfigTypeDef;

3.4 高级定时器PWM输入模式实验要求

通过定时器3通道2(PB5)输出PWM
将PWM输入到定时器8通道1(PC6),测量PWM的频率/周期、占空比等信息文章来源地址https://www.toymoban.com/news/detail-783270.html

2.1 atim.c

/*******************************以下是高级定时器输出比较模式实验程序**************************************/

TIM_HandleTypeDef g_timx_comp_pwm_handle;       /* 定时器x句柄 */

/**
 * @brief       高级定时器TIMX 输出比较模式 初始化函数(使用输出比较模式)
 * @note
 *              配置高级定时器TIMX 4路输出比较模式PWM输出,实现50%占空比,不同相位控制
 *              注意,本例程输出比较模式,每2个计数周期才能完成一个PWM输出,因此输出频率减半
 *              另外,我们还可以开启中断在中断里面修改CCRx,从而实现不同频率/不同相位的控制
 *              但是我们不推荐这么使用,因为这可能导致非常频繁的中断,从而占用大量CPU资源
 *
 *              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此
 *              高级定时器时钟 = 168Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值。
 * @param       psc: 预分频系数
 * @retval      无
 */

//1.声明定时器句柄
TIM_HandleTypeDef  g_timx_com_pwm_handler;
//2.配置通用定时器基本工作参数
void atim_timx_com_pwm_init(uint16_t arr, uint16_t psc)
{
       //4.1定时器输出比较定时器结构体初始化
    TIM_OC_InitTypeDef tim_oc_com_pwm = {0};
    
    //2.1通用定时器PWM输出初始化
    g_timx_com_pwm_handler.Instance = ATIM_TIMX_NPWM;                  //定时器x
    g_timx_com_pwm_handler.Init.Period = arr;
    g_timx_com_pwm_handler.Init.Prescaler = psc;
    g_timx_com_pwm_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
    g_timx_com_pwm_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能TIMx_ARR进行缓冲 */
    HAL_TIM_OC_Init(&g_timx_com_pwm_handler);
    
    
    //5.输出比较配置包,括PWM模式和比较值
    tim_oc_com_pwm.OCMode = TIM_OCMODE_TOGGLE;          //输出比较模式 PWM1
    tim_oc_com_pwm.Pulse = 250-1;                     //设置比较值为自动加载值的一般,则占空比为50%
    tim_oc_com_pwm.OCPolarity = TIM_OCPOLARITY_HIGH;   //设置输出比较的极性为高
    HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_1); //初始化定时器的输出比较通道1
    __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_1);  //通道1 预装载使能
    
    tim_oc_com_pwm.Pulse = 500-1;                     //设置比较值为自动加载值的一般,则占空比为50%
    HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_2); //初始化定时器的输出比较通道1
    __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_2);  //通道1 预装载使能
    
    tim_oc_com_pwm.Pulse = 750-1;                     //设置比较值为自动加载值的一般,则占空比为50%
    HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_3); //初始化定时器的输出比较通道1
    __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_3);  //通道1 预装载使能
    
    tim_oc_com_pwm.Pulse = 1000-1;                     //设置比较值为自动加载值的一般,则占空比为50%
    HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_com_pwm,TIM_CHANNEL_4); //初始化定时器的输出比较通道1
    __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_com_pwm_handler,TIM_CHANNEL_4);  //通道1 预装载使能

    
    //5,开启对应PWM通道使能输出并启动计时器
    HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);
    HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_2);
    HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_3);
    HAL_TIM_OC_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_4);
}

//3.定时器PWM输出底层初始化,定时器时钟、引脚时钟使能,引脚复用配置
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef * htm)
{
    //3.1判断是否是TIM14
    if(htm->Instance ==  ATIM_TIMX_NPWM)
    {
         GPIO_InitTypeDef gpio_init_struct;
     
        //3.3使能PF引脚口时钟
        ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE();
        ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE();
        ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE();
        ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE();
        
        //3.4使能定时器时钟
        ATIM_TIMX_COMP_CLK_ENABLE();
       
       
      //3.2通道y的GPIO初始化
      gpio_init_struct.Pin = ATIM_TIMX_COMP_CH1_GPIO_PIN;      /* 通道1 GPIO口 */
      gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */
      gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
      gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */ 
      gpio_init_struct.Alternate =ATIM_TIMX_NPWM_CHY_GPIO_AF; /* 端口复用到TIM8 */ 
      HAL_GPIO_Init(ATIM_TIMX_COMP_CH1_GPIO_PORT, &gpio_init_struct);  
        
      gpio_init_struct.Pin = ATIM_TIMX_COMP_CH2_GPIO_PIN;      /* 通道2 GPIO口 */
      HAL_GPIO_Init(ATIM_TIMX_COMP_CH2_GPIO_PORT, &gpio_init_struct); 
      
      gpio_init_struct.Pin = ATIM_TIMX_COMP_CH3_GPIO_PIN;      /* 通道3 GPIO口 */
      HAL_GPIO_Init(ATIM_TIMX_COMP_CH3_GPIO_PORT, &gpio_init_struct); 
      
      gpio_init_struct.Pin = ATIM_TIMX_COMP_CH4_GPIO_PIN;      /* 通道4 GPIO口 */
      HAL_GPIO_Init(ATIM_TIMX_COMP_CH4_GPIO_PORT, &gpio_init_struct); 

    }
}


/*******************************以下是高级定时器互补输出带死区时间控制实验程序**************************************/

//1.定义句柄、定义死区时间
TIM_HandleTypeDef g_timx_cplm_pwm_handler;       /* 定时器x句柄 */
TIM_BreakDeadTimeConfigTypeDef  g_break_dead_time_config ={0};
/**
 * @brief       高级定时器TIMX 互补输出 初始化函数(使用PWM模式1)
 * @note
 *              配置高级定时器TIMX 互补输出, 一路OCy 一路OCyN, 并且可以设置死区时间
 *
 *              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此
 *              高级定时器时钟 = 168Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率, 单位 : Mhz
 *
 * @param       arr: 自动重装值。
 * @param       psc: 预分频系数
 * @retval      无
 */
//2,配置定时器基础工作参数 
void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc)
{
    //3.1GPIO结构体初始化
    GPIO_InitTypeDef gpio_init_struct = {0};
    
    //3.2定时器时钟使能、通道对应IO口时钟使能
    ATIM_TIMX_CPLM_CHY_CLK_ENABLE();             /* TIMx 时钟使能 */
    
    ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE();        /* 通道X对应IO口时钟使能 */
    ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE();       /* 通道X互补通道对应IO口时钟使能 */
    ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE();       /* 通道X刹车输入对应IO口时钟使能 */
    
    
    //4.1定时器输出结构体初始化
    TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};
    
    
    //2.1通用定时器PWM输出初始化
    g_timx_cplm_pwm_handler.Instance = ATIM_TIMX_CPLM;                  //定时器x
    g_timx_cplm_pwm_handler.Init.Period = arr;
    g_timx_cplm_pwm_handler.Init.Prescaler = psc;
    g_timx_cplm_pwm_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
    g_timx_cplm_pwm_handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;  //CKD[1:0]= 10,tDTS =4 * tCK_INT =Ft/4 =42Mhz
    g_timx_cplm_pwm_handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能影子寄存器TIMx_ARR进行缓冲 */
    HAL_TIM_OC_Init(&g_timx_com_pwm_handler);
    
    //3 PE8/PE9/PE15引脚复用设置以及通道对应IO时钟使能与时钟使能
    gpio_init_struct.Pin = ATIM_TIMX_CPLM_BKIN_GPIO_PIN;    /*刹车输入引脚*/ 
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */ 
    gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    gpio_init_struct.Alternate =ATIM_TIMX_CPLM_CHY_GPIO_AF; /* 端口复用到TIM1 */   
    HAL_GPIO_Init(ATIM_TIMX_CPLM_BKIN_GPIO_PORT, &gpio_init_struct);
    
    gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHY_GPIO_PIN;    /*输出通道引脚*/ 
    HAL_GPIO_Init(ATIM_TIMX_CPLM_CHY_GPIO_PORT, &gpio_init_struct);
    
    gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHYN_GPIO_PIN;    /*互补通道引脚*/ 
    HAL_GPIO_Init(ATIM_TIMX_CPLM_CHYN_GPIO_PORT, &gpio_init_struct);
    
    //4.配置PWM模式/比较值等
    tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;            //输出比较模式 PWM1
    tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_HIGH;    //OCy高电平有效
    tim_oc_cplm_pwm.OCNPolarity = TIM_OCPOLARITY_HIGH;   //OCy高电平有效
    tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_SET;   //当前MOE = 0,OCx=0
    tim_oc_cplm_pwm.OCNIdleState = TIM_OCIDLESTATE_SET;   //当前MOE = 0,OCxN=0
    HAL_TIM_PWM_ConfigChannel(&g_timx_com_pwm_handler,&tim_oc_cplm_pwm,ATIM_TIMX_CPLM_CHY); //初始化定时器的输出比较通道1
    
    //5.配置刹车功能、死区参数,开启死区中断
    g_break_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE;   //运行模式关闭输出状态
    g_break_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;  //空闲模式关闭输出状态
    g_break_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;        //不用寄存器锁功能
    g_break_dead_time_config.BreakState = TIM_BREAK_ENABLE;        //使能刹车输入
    g_break_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH; //刹车输入有效信号为高
    g_break_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;//使能AOE位,允许刹车结束后自动恢复输出 
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_com_pwm_handler,&g_break_dead_time_config); //初始化刹车死区时间
    
   //6,开启对应PWM通道使能输出并启动计时器
    HAL_TIM_PWM_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);    //OCy 输出使能
    HAL_TIMEx_PWMN_Start(&g_timx_com_pwm_handler,TIM_CHANNEL_1);    //OCyN 输出使能
}
/**
 * @brief       定时器TIMX 设置输出比较值 & 死区时间
 * @param       ccr: 输出比较值
 * @param       dtg: 死区时间
 *   @arg       dtg[7:5]=0xx时, 死区时间 = dtg[7:0] * tDTS
 *   @arg       dtg[7:5]=10x时, 死区时间 = (64 + dtg[6:0]) * 2  * tDTS
 *   @arg       dtg[7:5]=110时, 死区时间 = (32 + dtg[5:0]) * 8  * tDTS
 *   @arg       dtg[7:5]=111时, 死区时间 = (32 + dtg[5:0]) * 16 * tDTS
 *   @note      tDTS = 1 / (Ft /  CKD[1:0]) = 1 / 42M = 23.8ns
 * @retval      无
 */

//7 设置输出比较值与死区时间
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg)
{
    g_break_dead_time_config.DeadTime = dtg;
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_com_pwm_handler,&g_break_dead_time_config); //重设死区时间
    __HAL_TIM_MOE_ENABLE(&g_timx_com_pwm_handler);                                    //MOE等于1,使能主输出
    ATIM_TIMX_CPLM_CHY_CCRX = ccr;                                                    //设置比较寄存器
}

/*******************************高级定时器PWM输入模式程序**************************************/

TIM_HandleTypeDef g_timx_pwmin_chy_handler;   /* 定时器x句柄 */

/* PWM输入状态(g_timxchy_cap_sta)
 * 0,没有成功捕获.
 * 1,已经成功捕获了
 */
uint8_t g_timxchy_pwmin_sta  = 0;   /* PWM输入状态 */
uint16_t g_timxchy_pwmin_psc  = 0;  /* PWM输入分频系数 */
uint32_t g_timxchy_pwmin_hval = 0;  /* PWM的高电平脉宽 */
uint32_t g_timxchy_pwmin_cval = 0;  /* PWM的周期宽度 */

/**
 * @brief       定时器TIMX 通道Y PWM输入模式 初始化函数
 * @note
 *              高级定时器的时钟来自APB2, 而PCLK2 = 168Mhz, 我们设置PPRE2不分频, 因此
 *              高级定时器时钟 = 168Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       无
 * @retval      无
 */
 //2,配置定时器基础工作参数 
void atim_timx_pwmin_chy_init(void)                        /* 高级定时器 PWM输入模式初始化 */
{
     //3.1GPIO结构体初始化
    GPIO_InitTypeDef gpio_init_struct = {0};
    
    //从模式初始化配置
    TIM_SlaveConfigTypeDef slave_config = {0};
    
    //4.1输入初始化配置
    TIM_IC_InitTypeDef tim_ic_pwmin_chy = {0};
    
    //3.2定时器时钟使能、通道对应IO口时钟使能
    ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE();        /* IO口时钟使能 */
    ATIM_TIMX_PWMIN_CHY_CLK_ENABLE();           /* TIM8 时钟使能 */

    
    
    
    //2.1通用定时器PWM输出初始化
    g_timx_pwmin_chy_handler.Instance = ATIM_TIMX_PWMIN;                  //定时器8
    g_timx_pwmin_chy_handler.Init.Period = 65535;
    g_timx_pwmin_chy_handler.Init.Prescaler = 0;
    g_timx_pwmin_chy_handler.Init.CounterMode = TIM_COUNTERMODE_UP;
    HAL_TIM_IC_Init(&g_timx_pwmin_chy_handler);
    
    //3 PC6引脚复用设置以及通道对应IO时钟使能与时钟使能
    gpio_init_struct.Pin = ATIM_TIMX_PWMIN_CHY_GPIO_PIN;    /*输出引脚*/ 
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                /* 复用推挽输出 */ 
    gpio_init_struct.Pull = GPIO_PULLDOWN;                  /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    gpio_init_struct.Alternate =ATIM_TIMX_PWMIN_CHY_GPIO_AF; /* 端口复用到TIM8 */   
    HAL_GPIO_Init(ATIM_TIMX_PWMIN_CHY_GPIO_PORT, &gpio_init_struct);
    
        /* 从模式配置,IT1触发更新 */
    slave_config.SlaveMode = TIM_SLAVEMODE_RESET;                   /* 从模式:复位模式 */
    //4.IC1捕获:上升沿触发TI1FP1
    tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_RISING;      //上升沿检测
    tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_DIRECTTI;  //选择输入端IC1映射到TI1
    tim_ic_pwmin_chy.ICPrescaler = TIM_ICPSC_DIV1;            //不分频
    tim_ic_pwmin_chy.ICFilter = 0;                            //选择输入端IC1映射到TI1
    HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handler, &tim_ic_pwmin_chy, ATIM_TIMX_PWMIN_CHY);
    
    //5.IC2捕获:上升沿触发TI1FP2
    tim_ic_pwmin_chy.ICPolarity = TIM_ICPOLARITY_FALLING;      //上升沿检测
    tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_INDIRECTTI;  //选择输入端IC2映射到TI1
    HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handler, &tim_ic_pwmin_chy, TIM_CHANNEL_2);
    
    HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_IRQn, 1, 3);               /* 设置中断优先级,抢占优先级1,子优先级3 */
    HAL_NVIC_EnableIRQ( ATIM_TIMX_PWMIN_IRQn );                     /* 开启TIMx中断 */
    
        /* TIM1/TIM8有独立的输入捕获中断服务函数 */
    if ( ATIM_TIMX_PWMIN == TIM1 || ATIM_TIMX_PWMIN == TIM8)
    {
        HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_CC_IRQn, 1, 3);        /* 设置中断优先级,抢占优先级1,子优先级3 */
        HAL_NVIC_EnableIRQ(ATIM_TIMX_PWMIN_CC_IRQn);                /* 开启TIMx中断 */
    }
    
   //6,开启对应PWM通道使能输入并启动计时器
   __HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler, TIM_IT_UPDATE);
    HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handler, TIM_CHANNEL_1);
    HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handler, TIM_CHANNEL_2);
}
//7重启PWM输入模式
void atim_timx_pwmin_chy_restart(void)                     /* 高级定时器 重启PWM输入模式检测 */
{
    //7.1 关闭中断
    sys_intx_disable();              //关闭中断
    
    //7.2状态和分频系数清零
    g_timxchy_pwmin_sta = 0;         //清零状态
    g_timxchy_pwmin_psc = 0;         //分频系数清零
    
    //7.2设置最大计数频率,得到最好的精度,计数器值清零
    __HAL_TIM_SET_PRESCALER(&g_timx_pwmin_chy_handler,0); //以最大的计数频率采集,以得到最好的精度 
    __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler,0);   //计数器清零
    
    //7.3 使能通道1捕获中断、使能溢出中断、使能定时器
    __HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC1);    //使能通道1捕获中断
    __HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_UPDATE); //使能溢出中断
    __HAL_TIM_ENABLE(&g_timx_pwmin_chy_handler);                  //使能定时器
    
    //7.4清零捕获/比较中断标志、更新中断标志
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC1);  //清零捕获/比较1中断标志
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC2);  //清零捕获/比较2中断标志
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_UPDATE);//清零更新中断标志
    
    //7.5打开中断
    sys_intx_enable();
    
}

/**
 * @brief       定时器TIMX 通道Y PWM输入模式 中断处理函数
 * @note
 *              因为TIM1/TIM8等有多个中断服务函数,而TIM2~5/TIM12/TIM15等普通定时器只有1个中断服务
 *              函数,为了更好的兼容,我们对中断处理统一放到atim_timx_pwin_chy_process函数里面进行处理
 *
 * @param       无
 * @retval      无
 */
//10 统一中断处理函数
static void atim_timx_pwmin_chy_process(void)
{
    //10.1启动入口检测
    static uint8_t sflag = 0;
    //10.2 检测PWM输入状态
    if(g_timxchy_pwmin_sta)               //若已输入
    {
        //分屏系数清零,清零捕获/比较标志,清零更新中断标志,计数器清零
        g_timxchy_pwmin_psc = 0;
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */
        __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler, 0);                     /* 计数器清零 */
        return;
    
    }
    //10.3检测是否发生溢出中断
    if(__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_UPDATE))  //若发生溢出中断
    {
        //清除溢出中断标志
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零溢出中断标志 */
        //检测是否发生周期性捕获中断
        if(__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler,TIM_FLAG_CC1)== 0) //若没有发生周期性捕获中断,且捕获未完成
        {
            //PWM输入检测标志置0
            sflag= 0;
            if(g_timxchy_pwmin_psc == 0)  //从0到1
            {
                g_timxchy_pwmin_psc++;
            }
            else
            {
                if(g_timxchy_pwmin_psc == 65535)               /* 已经最大了,可能是无输入状态 */
                {
                    g_timxchy_pwmin_psc = 0;                    /* 重新恢复不分频 */
                }  
                else if (g_timxchy_pwmin_psc > 32767)           /* 不能倍增了 */
                {
                    g_timxchy_pwmin_psc = 65535;                /* 直接等于最大分频系数 */
                }
                else
                {
                    g_timxchy_pwmin_psc += g_timxchy_pwmin_psc; /* 倍增 */
                }                
            }
            __HAL_TIM_SET_PRESCALER(&g_timx_pwmin_chy_handler, g_timxchy_pwmin_psc); /* 设置定时器预分频系数 */
            __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handler, 0);                     /* 计数器清零 */
            __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */
            __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */
            __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */
            return ;
            
        }
    
    }
    //10.4检测到是采集到更新捕获中断
    if(sflag == 0)      //第一次采集到更新捕获中断
    {
         if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1))   /* 检测到了第一次周期捕获中断 */
        { 
            sflag = 1;              /* 标记第一次周期已经捕获, 第二次周期捕获可以开始了 */
        }
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);           /* 清零捕获/比较1中断标志 */
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);           /* 清零捕获/比较2中断标志 */
        __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);        /* 清零更新中断标志 */
        return;
    
    }
    //10.5 如果还没有成功捕获
    if(g_timxchy_pwmin_sta == 0)
    {
        if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1))   /* 检测到了周期捕获中断 */
        { 
             g_timxchy_pwmin_hval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handler, TIM_CHANNEL_2) + 1;  /* PWM的高电平脉宽捕获值 */
             g_timxchy_pwmin_cval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handler, TIM_CHANNEL_1) + 1;  /* PWM的周期宽度捕获值 */
            if(g_timxchy_pwmin_hval<g_timxchy_pwmin_cval)         //高电平款比小于周期性宽
            {
                g_timxchy_pwmin_sta =1;                           //标记捕获成功
                g_timxchy_pwmin_psc = ATIM_TIMX_PWMIN->PSC;       //获取PWM输入分频系数
               if (g_timxchy_pwmin_psc == 0)                   /* 分频系数为0的时候, 修正读取数据 */
                {
                    g_timxchy_pwmin_hval++;                     /* 修正系数为1, 加1 */
                    g_timxchy_pwmin_cval++;                     /* 修正系数为1, 加1 */
                }

                sflag = 0;
                
                //每次捕获成功后停止捕获,避免频繁中断影响系统正常运行
                ATIM_TIMX_PWMIN->CR1 &= ~(1<< 0);                //关闭定时器TIMX
                __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC1);      //失能通道1捕获中断
                __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_CC2);      //失能通道2捕获中断
                __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handler,TIM_IT_UPDATE);   //使能溢出中断
                
               __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);    /* 清零捕获/比较1中断标志 */
               __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);    /* 清零捕获/比较2中断标志 */
               __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE); /* 清零更新中断标志 */
            }
            else
            {
                atim_timx_pwmin_chy_restart();
            }
        }
    }
        /* 清除捕获/比较1中断标志\捕获/比较2中断标志/更新中断标志 */
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC1);
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_CC2);
    __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handler, TIM_FLAG_UPDATE);
}
/**
 * @brief       定时器TIMX 更新/溢出 中断服务函数
 *   @note      TIM1/TIM8的这个函数仅用于更新/溢出中断服务,捕获在另外一个函数!
 *              其他普通定时器则更新/溢出/捕获,都在这个函数里面处理!
 * @param       无
 * @retval      无
 */
//8.更新/溢出中断服务
void ATIM_TIMX_PWMIN_IRQHandler(void)
{
    atim_timx_pwmin_chy_process();
}
/**
 * @brief       定时器TIMX 输入捕获 中断服务函数
 *   @note      仅TIM1/TIM8有这个函数,其他普通定时器没有这个中断服务函数!
 * @param       无
 * @retval      无
 */
//9.捕获中断服务
void ATIM_TIMX_PWMIN_CC_IRQHandler(void)
{
    atim_timx_pwmin_chy_process();
}

2.2 atim.h

#ifndef __ATIM_H
#define __ATIM_H

#include "./SYSTEM/sys/sys.h"

/* TIMX 输出比较模式 定义 
 * 这里通过TIM8的输出比较模式,控制PC6,PC7,PC8,PC9输出4路PWM,占空比50%,并且每一路PWM之间的相位差为25%
 * 修改CCRx可以修改相位.
 * 默认是针对TIM8
 * 注意: 通过修改这些宏定义,可以支持TIM1/TIM8任意一个定时器,任意一个IO口使用输出比较模式,输出PWM
 */
#define ATIM_TIMX_COMP_CH1_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH1_GPIO_PIN             GPIO_PIN_6
#define ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */

#define ATIM_TIMX_COMP_CH2_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH2_GPIO_PIN             GPIO_PIN_7
#define ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */

#define ATIM_TIMX_COMP_CH3_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH3_GPIO_PIN             GPIO_PIN_8
#define ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */

#define ATIM_TIMX_COMP_CH4_GPIO_PORT            GPIOC
#define ATIM_TIMX_COMP_CH4_GPIO_PIN             GPIO_PIN_9
#define ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */

#define ATIM_TIMX_COMP                          TIM8
#define ATIM_TIMX_COMP_CH1_CCRX                 TIM8->CCR1                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH2_CCRX                 TIM8->CCR2                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH3_CCRX                 TIM8->CCR3                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CH4_CCRX                 TIM8->CCR4                                  /* 通道1的输出比较寄存器 */
#define ATIM_TIMX_COMP_CLK_ENABLE()             do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)  /* TIM8 时钟使能 */

void atim_timx_com_pwm_init(uint16_t arr, uint16_t psc);   /* 高级定时器 输出比较模式输出PWM 初始化函数 */


/* TIMX 互补输出模式 定义 
 * 这里设置互补输出相关硬件配置, CHY即正常输出, CHYN即互补输出
 * 修改CCRx可以修改占空比.
 * 默认是针对TIM1
 * 注意: 通过修改这些宏定义,可以支持TIM1/TIM8定时器, 任意一个IO口输出互补PWM(前提是必须有互补输出功能)
 */

/* 输出通道引脚 */
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_CHY_GPIO_PIN             GPIO_PIN_9
#define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

/* 互补通道引脚 */
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_CHYN_GPIO_PIN             GPIO_PIN_8
#define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

/* 刹车输入引脚 */
#define ATIM_TIMX_CPLM_BKIN_GPIO_PORT            GPIOE
#define ATIM_TIMX_CPLM_BKIN_GPIO_PIN             GPIO_PIN_15
#define ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

/* TIMX REMAP设置
 * 因为PE8/PE9/PE15, 默认并不是TIM1的复用功能脚, 必须开启完全重映射, 才可以将: TIM1_CH1->PE9; TIM1_CH1N->PE8; TIM1_BKIN->PE15;
 * 这样, PE8/PE9/PE15, 才能用作TIM1的CH1N/CH1/BKIN功能.
 * 因此, 必须实现ATIM_TIMX_CPLM_CHYN_GPIO_AF, 
 * 如果我们使用默认的复用功能输出, 则不用设置重映射, 是可以不需要该函数的! 根据具体需要来实现.
 */
#define ATIM_TIMX_CPLM_CHY_GPIO_AF               GPIO_AF1_TIM1

/*互补输出使用定时器*/
#define ATIM_TIMX_CPLM                          TIM1
#define ATIM_TIMX_CPLM_CHY                      TIM_CHANNEL_1                               /* 通道Y,  1<= Y <=4 */
#define ATIM_TIMX_CPLM_CHY_CCRX                 ATIM_TIMX_CPLM->CCR1                        /* 通道Y的输出比较寄存器 */
#define ATIM_TIMX_CPLM_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)  /* TIM1 时钟使能 */

void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc);   /* 高级定时器 互补输出 初始化函数 */
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg);   /* 高级定时器 互补输出 设置比较值、死区时间 */

/* TIMX PWM输入模式 定义 
 * 这里的输入捕获使用定时器TIM1_CH1,捕获WK_UP按键的输入
 * 默认是针对TIM1/TIM8等高级定时器
 * 注意: 通过修改这几个宏定义,可以支持TIM1~TIM8任意一个定时器的通道1/通道2
 */
#define ATIM_TIMX_PWMIN_CHY_GPIO_PORT           GPIOC
#define ATIM_TIMX_PWMIN_CHY_GPIO_PIN            GPIO_PIN_6
#define ATIM_TIMX_PWMIN_CHY_GPIO_AF             GPIO_AF3_TIM8
#define ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* PC口时钟使能 */

#define ATIM_TIMX_PWMIN                          TIM8
#define ATIM_TIMX_PWMIN_IRQn                     TIM8_UP_TIM13_IRQn
#define ATIM_TIMX_PWMIN_IRQHandler               TIM8_UP_TIM13_IRQHandler
#define ATIM_TIMX_PWMIN_CHY                      TIM_CHANNEL_1                                /* 通道Y,1<=Y<=2 */
#define ATIM_TIMX_PWMIN_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM8_CLK_ENABLE(); }while(0)   /* TIM8 时钟使能 */

 /* TIM1 / TIM8 有独立的捕获中断服务函数,需要单独定义,对于TIM2~5等,则不需要以下定义 */
#define ATIM_TIMX_PWMIN_CC_IRQn                     TIM8_CC_IRQn
#define ATIM_TIMX_PWMIN_CC_IRQHandler               TIM8_CC_IRQHandler

void atim_timx_pwmin_chy_init(void);                        /* 高级定时器 PWM输入模式初始化 */
void atim_timx_pwmin_chy_restart(void);                     /* 高级定时器 重启PWM输入模式检测 */

#endif

2.3main.c


#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/atim.h"
#include "./BSP/TIMER/gtim.h"


int main01(void)
{
    uint8_t key = 0;
    uint8_t t = 0;
    GPIO_InitTypeDef gpio_init_struct;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化按键 */
    
    /* 将 LED1 引脚设置为输入模式, 避免和PC6冲突 */
    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 设置为输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速模式 */
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */
    
    atim_timx_npwm_chy_init(10000 - 1, 8400 - 1);           /* 20Khz的计数频率,2Hz的PWM频率. */

    ATIM_TIMX_NPWM_CHY_CCRX = 5000; /* 设置PWM占空比,50%,这样可以控制每一个PWM周期,LED1(GREEN)
                                     * 有一半时间是亮的,一半时间是灭的,LED1亮灭一次,表示一个PWM波
                                     */
    atim_timx_npwm_chy_set(5);      /* 输出5个PWM波(控制LED1(GREEN)闪烁5次) */
    
    while (1)
    {
       key = key_scan(0);

        if (key == KEY0_PRES)           /* KEY0按下 */
        {
            atim_timx_npwm_chy_set(5);  /* 输出5个PWM波(控制TIM8_CH1, 即PC6输出5个脉冲) */
        }

        t++;
        delay_ms(10);

        if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */
        {
            t = 0;
            LED0_TOGGLE();
        }
    }
}

int main02(void)
{
    uint8_t t = 0;
    GPIO_InitTypeDef gpio_init_struct;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化按键 */
    
    /* 将 LED1 引脚设置为输入模式, 避免和PC6冲突 */
    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                /* 设置为输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     /* 高速模式 */
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */
    
    atim_timx_npwm_chy_init(10000- 1, 168 - 1);           /* 1Mhz的计数频率,1Khz的PWM周期. */

    ATIM_TIMX_COMP_CH1_CCRX = 250-1;  /* 通道1 相位25%*/
    ATIM_TIMX_COMP_CH2_CCRX = 500-1;  /* 通道1 相位50%*/
    ATIM_TIMX_COMP_CH3_CCRX = 750-1;  /* 通道1 相位75%*/
    ATIM_TIMX_COMP_CH4_CCRX = 1000-1; /* 通道1 相位100%*/
                                    

    while (1)
    {

        t++;
        delay_ms(10);

        if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */
        {
            t = 0;
            LED0_TOGGLE();
        }
    }
}
int main03(void)
{
    uint8_t t = 0;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */

    atim_timx_cplm_pwm_init(1000- 1, 168 - 1);  /* 1Mhz的计数频率,1Khz波形输出. */
    atim_timx_cplm_pwm_set(300,250);            /*占空比为7:3,死区时间  100*tDTS*/
                                    

    while (1)
    {

        t++;
        delay_ms(10);

        if (t > 50)                     /* 控制LED0闪烁, 提示程序运行状态 */
        {
            t = 0;
            LED0_TOGGLE();
        }
    }
}

extern uint16_t g_timxchy_pwmin_psc;    /* PWM输入状态 */
extern uint16_t g_timxchy_pwmin_sta;    /* PWM输入状态 */
extern uint32_t g_timxchy_pwmin_hval;   /* PWM的高电平脉宽 */
extern uint32_t g_timxchy_pwmin_cval;   /* PWM的周期宽度 */

int main04(void)
{
    uint8_t t = 0;
    double ht,ct,f,tpsc;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(115200);                         /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */

    gtim_timx_pwm_chy_init(10- 1, 84 - 1);       /* 1Mhz的计数频率,100Khz波形输出. */
    atim_timx_pwmin_chy_init();                  /* 初始化PWM输入捕获 */
    
    GTIM_TIMX_PWM_CHY_CCRX = 2;                 /* 低电平宽度20,高电平宽度80 */

    while (1)
    {

        t++;
        delay_ms(10);

        if (t > 20)                     /* 控制LED0闪烁, 提示程序运行状态 */
        {
            if(g_timxchy_pwmin_sta)
            {
               printf("\r\n");                                     /* 输出空,另起一行 */
                printf("PWM PSC  :%d\r\n", g_timxchy_pwmin_psc);    /* 打印分频系数 */
                printf("PWM Hight:%d\r\n", g_timxchy_pwmin_hval);   /* 打印高电平脉宽 */
                printf("PWM Cycle:%d\r\n", g_timxchy_pwmin_cval);   /* 打印周期 */
                tpsc = ((double)g_timxchy_pwmin_psc + 1) / 168;     /* 得到PWM采样时钟周期时间 */
                ht = g_timxchy_pwmin_hval * tpsc;                   /* 计算高电平时间 */
                ct = g_timxchy_pwmin_cval * tpsc;                   /* 计算周期长度 */
                f = (1 / ct) * 1000000;                             /* 计算频率 */
                printf("PWM Hight time:%.3fus\r\n", ht);            /* 打印高电平脉宽长度 */
                printf("PWM Cycle time:%.3fus\r\n", ct);            /* 打印周期时间长度 */
                printf("PWM Frequency :%.3fHz\r\n", f);             /* 打印频率 */
                atim_timx_pwmin_chy_restart();                      /* 重启PWM输入检测 */
            }
            t = 0;
            LED0_TOGGLE();
        }
    }
}



到了这里,关于STM32——高级定时器输出比较模式实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32笔记——定时器输出比较功能(产生PWM波)

    目录 一、概述 二、PWM简单介绍  三、通用定时器输出比较 3.1 输出比较简介 3.2 输出比较通道 3.3 产生PWM的过程 四、实验硬件介绍及PWM模块程序 4.1 舵机简介 4.2 直流电机及驱动芯片TB6612  4.3 PWM模块驱动程序         主要介绍通用定时器输出比较功能,在GPIO口输出PWM来控

    2024年02月13日
    浏览(48)
  • STM32CubeMX教程8 TIM 通用定时器 - 输出比较

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 逻辑分析仪nanoDLA 使用STM32CubeMX软件配置STM32F407 通用定时器的输出比较通道 ,并将其输出到四个LED灯引脚实现LED灯流水灯效果 STM32F407的定时器通道均可以实现输出比较功能, 输出比较功

    2024年02月03日
    浏览(79)
  • HAL库STM32常用外设教程(五)—— 定时器 输出比较

    有关于定时器 输出PWM功能 不了解的可以看这篇文章 :HAL库STM32常用外设教程(一)—— 定时器 输出PWM 有关于定时器 定时功能 不了解的可以看这篇文章 :HAL库STM32常用外设教程(四)—— 定时器 基本定时 1、STM32F407ZGT6 2、STM32CubeMx软件 3、keil5 内容简述: 通篇文章将涉及以

    2024年03月27日
    浏览(63)
  • STM32使用高级定时器输出互补pwm波

    最近做的一个项目用到stm32,网上查了很多资料,也踩了很多坑,这里记录一下配置的步骤和说明 硬件使用的是stm32h750vbt6; 软件用到了stm32cubemx和keil5; 打开Debug模式方便调试,可以忽略,不影响代码运行 在用cube配置时钟源时,有下面三个选项 Disable(禁用) BYPASS Clock Sou

    2024年02月16日
    浏览(74)
  • STM32高级定时器输出指定数量PWM(STM32CubeMx配置)

    高级定时器中有一个重复计数器,本实验输出指定个数PWM就是利用了重复计数器的特性,先来看看重复计数器的特性是什么: 计数器每次上溢或下溢都能使重复计数器减1,减到0时,再发生一次溢出就会产生更新事件 这是什么意思呢,这里举个例子比如说我设定重复计数器的

    2024年02月02日
    浏览(88)
  • STM32实战-高级定时器带死区的互补PWM输出

    前言: 平时我们设计点击驱动电路时,一般会采用npn和pnp三极管,来控制电机的导通和关闭,但是三级管内部自带电容,断电后不会立马断掉,会经过很小的一段时间才会放电完毕,这时候要留有死区给电容放电,这就有了互补pwm波。   同时,当电机出现故障,如果利用软

    2024年02月08日
    浏览(50)
  • STM32单片机(六)TIM定时器 -> 第三节:TIM输出比较

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月09日
    浏览(65)
  • STM32——高级定时器输出指定个数PWM波原理及实战

    相比于通用定时器特性: 1)重复计数器 2)死区时间带可编程的互补输出 3)断路输入,用于将定时器的输出信号置于用户可选的安全配置中 1,配置定时器基础工作参数 HAL_TIM_PWM_Init() 2,定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置NVIC、CLOCK、GPIO等 3,配置PWM模式/比较值等

    2024年01月16日
    浏览(60)
  • STM32外设之TIM定时器使用及输出比较模式PWM生成,PWM频率和占空比计算,文末有固件库TIM驱动文件的函数讲解

    过来人的经验分享: TIM定时器在我们学习STM32的过程中是一个重要且稍微有点难度的外设了,就拿从学校里做的项目来说用到的也是一些基本的外设配置和传感器等等。TIM作为外设中稍微有点难度的外设相当关键,学好TIM,对以后学习单片机开发也有很大帮助。 定时器是stm3

    2024年02月07日
    浏览(47)
  • STM32学习笔记(4) 高级定时器-两路互补的PWM输出(带死区和刹车控制)

    目录 1.实验目的 2.实验效果 3.理论部分 3.1时钟源 3.2时基单元 3.3输入捕获 4.程序流程 4.1GPIO初始化结构体 4.2时基初始化结构体 4.3输出比较结构体 4.4刹车和死区结构体的初始化 5.程序源码 使用高级定时器,输出两路互补的PWM输出,需要有带死区和不带死区两种情况 图1:不带

    2024年02月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包