首页 > 其他分享 >[单片机框架][bsp层][AT32F415][bsp_tim] tim定时器配置和使用

[单片机框架][bsp层][AT32F415][bsp_tim] tim定时器配置和使用

时间:2022-10-31 18:03:28浏览次数:51  
标签:TMR TIM1 AT32F415 bsp tim TMR1 BS


9 定时器(TIMER)

9.1 通用定时器(TMR2到TMR5)
9.1.1 TMRx简介
通用定时器是一个通过可编程预分频器驱动的 16 位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM) 。
使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作,参见 9.2.3.15 节。

9.1.2 TMRx主要功能
通用 TMRx(TMR2、TMR3、TMR4 和 TMR5)定时器功能包括:

  • 16位向上、向下、向上/向下自动装载计数器
    注意: TMR2 和 TMR5 可选 32 位,详见 9.2.4.1 节 TMRx_CTRL1 寄存器
  • 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
  • 4个独立通道:
    ①输入捕获
    ②输出比较
    ③PWM生成(边缘或中间对齐模式)
    ④单脉冲模式输出
  • 使用外部信号控制定时器和定时器互连的同步电路
  • 如下事件发生时产生中断/DMA:
    ① 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触
    发)
    ②触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
    ③输入捕获
    ④输出比较
  • 支持针对定位的增量(正交)编码器和霍尔传感器电路
  • 触发输入作为外部时钟或者按周期的电流管理

    9.1.3 TMRx功能描述
    9.1.3.1 时基单元
    可编程通用定时器的主要部分是一个 16 位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。
    计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。
    时基单元包含:
  • 计数器寄存器(TMRx_CNT)
  • 预分频器寄存器(TMRx_DIV)
  • 自动装载寄存器(TMRx_AR)

自动装载寄存器是预先装载的, 写或读自动重装载寄存器将访问预装载寄存器。 根据在 TMRx_CTRL1寄存器中的自动装载预装载使能位 (ARPEN) 的设置, 预装载寄存器的内容被立即或在每次的更新事件 UEV 时传送到影子寄存器。 当计数器达到溢出条件 (向下计数时的下溢条件) 并当 TMRx_CTRL1寄存器中的 UEVDIS 位等于’0’时,产生更新事件。更新事件也可以由软件产生。随后会详细描述每一种配置下更新事件的产生。

计数器由预分频器的时钟输出 CK_CNT 驱动,仅当设置了计数器 TMRx_CTRL1 寄存器中的计数器使能位(CNTEN)时,CK_CNT 才有效。 (有关计数器使能的细节,请参见控制器的从模式描述) 。

注意: 真正的计数器使能信号 CNT_EN 是在 CNTEN 的一个时钟周期后被设置。

/********************************************************************************
* @file bsp_tim.c
* @author jianqiang.xue
* @version V1.0.0
* @date 2022-02-14
* @brief NULL
********************************************************************************/
/* Includes ----------------------------------------------------------*/
#include <stdio.h>
#include <string.h>

#include "RTE_Components.h"
#include CMSIS_device_header

#include "bsp_gpio.h"
#include "bsp_tim.h"

/* Private Includes ----------------------------------------------------------*/
#include "business_gpio.h"
#include "business_function.h"

/* Private Define ------------------------------------------------------------*/
/* Private Typedef -----------------------------------------------------------*/
#if BS_TIM1_EN
TMR_TimerBaseInitType tim1_handle_t =
{
.TMR_Period = BS_TIM1_PERIOD, // 重装载值
.TMR_DIV = BS_TIM1_PRESCALER, // 预分频
.TMR_ClockDivision = 0, // CKD 时钟分频因子(Clock division)
.TMR_CounterMode = TMR_CounterDIR_Up, // 边沿对齐模式 计数器向上计数
.TMR_RepetitionCounter = 0, // TIM1_RCR 重复计数器的值
};

TMR_OCInitType tim1_oc_init_handle_t =
{
.TMR_OCMode = TMR_OCMode_PWM1, // PWM模式1 TIM1_CCMR1
.TMR_Pulse = BS_TIM1_PERIOD, // CCR 捕获/比较通道
.TMR_OutputState = TMR_OutputState_Enable, // 输出模式
.TMR_OCPolarity = TMR_OCPolarity_High // 高电平有效
};
#endif


void bsp_tim_pwm_init(void)
{
#if BS_TIM1_EN
/* TMR1 clocks enable */
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_TMR1, ENABLE);
/* Set TIMx instance */
TMR_TimeBaseInit(TMR1, &tim1_handle_t);

#if BS_PWM0_EN
/* Enable the Clock */
bsp_gpio_set_clk(GPIO_APBx, BS_TIM1_CH1_GPIO_CLK, true);
bsp_gpio_init_tim(BS_TIM1_CH1_GPIO_PORT, BS_TIM1_CH1_PIN, 0);
TMR_OC1Init(TMR1, &tim1_oc_init_handle_t);
TMR_OC1PreloadConfig(TMR1, TMR_OCPreload_Enable); //CH1预装载使能
#endif

#if BS_PWM1_EN
/* Enable the Clock */
bsp_gpio_set_clk(GPIO_APBx, BS_TIM1_CH2_GPIO_CLK, true);
bsp_gpio_init_tim(BS_TIM1_CH2_GPIO_PORT, BS_TIM1_CH2_PIN, 0);
TMR_OC2Init(TMR1, &tim1_oc_init_handle_t);
TMR_OC2PreloadConfig(TMR1, TMR_OCPreload_Enable); //CH2预装载使能
#endif

#if BS_PWM2_EN
/* Enable the Clock */
bsp_gpio_set_clk(GPIO_APBx, BS_TIM1_CH3_GPIO_CLK, true);
bsp_gpio_init_tim(BS_TIM1_CH3_GPIO_PORT, BS_TIM1_CH3_PIN, 0);
TMR_OC3Init(TMR1, &tim1_oc_init_handle_t);
TMR_OC3PreloadConfig(TMR1, TMR_OCPreload_Enable); //CH3预装载使能
#endif

#if BS_PWM3_EN
/* Enable the Clock */
bsp_gpio_set_clk(GPIO_APBx, BS_TIM1_CH4_GPIO_CLK, true);
bsp_gpio_init_tim(BS_TIM1_CH4_GPIO_PORT, BS_TIM1_CH4_PIN, 0);
TMR_OC4Init(TMR1, &tim1_oc_init_handle_t);
TMR_OC4PreloadConfig(TMR1, TMR_OCPreload_Enable); //CH4预装载使能
#endif

/* TMR1 Main Output Enable
普通定时器在完成以上设置了之后, 就可以输出 PWM 了,
但是高级定时器,我们还需要使能刹车和死区寄存器( TIM1_BDTR)的 MOE 位,以使能整个 OCx(即 PWM)输出。
*/
TMR_CtrlPWMOutputs(TMR1, ENABLE);
//使能TIMx在ARR上的预装载寄存器
TMR_ARPreloadConfig(TMR1, ENABLE);
/* TMR1 counter enable */
TMR_Cmd(TMR1, ENABLE);
#endif
}

void bsp_tim_pwm_deinit(void)
{
#if BS_TIM1_EN
#if BS_PWM0_EN
bsp_gpio_deinit(BS_TIM1_CH1_GPIO_PORT, BS_TIM1_CH1_PIN);
#endif
#if BS_PWM1_EN
bsp_gpio_deinit(BS_TIM1_CH2_GPIO_PORT, BS_TIM1_CH2_PIN);
#endif
#if BS_PWM2_EN
bsp_gpio_deinit(BS_TIM1_CH3_GPIO_PORT, BS_TIM1_CH3_PIN);
#endif
#if BS_PWM3_EN
bsp_gpio_deinit(BS_TIM1_CH4_GPIO_PORT, BS_TIM1_CH4_PIN);
#endif
TMR_Reset(TMR1);
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_TMR1, DISABLE);
#endif
}

void bsp_tim_set_period(bsp_tim_t tim_id, uint16_t period)
{
if (tim_id == BSP_TIM_0)
{
}
else if (tim_id == BSP_TIM_1)
{
TMR_SetAutoreload(TMR1, period);
}
}
/********************************************************************************
* @file bsp_tim.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2021-04-19
* @brief NULL
********************************************************************************/

#ifndef __BSP_TIM_H
#define __BSP_TIM_H

#include <stdint.h>

/* Includes ------------------------------------------------------------------*/
typedef enum
{
BSP_TIM_0 = 0,
BSP_TIM_1
} bsp_tim_t;

/* Public Function Prototypes ------------------------------------------------*/

void bsp_tim_pwm_init(void);
void bsp_tim_pwm_deinit(void);
void bsp_tim_set_period(bsp_tim_t tim_id, uint16_t period);
#endif


标签:TMR,TIM1,AT32F415,bsp,tim,TMR1,BS
From: https://blog.51cto.com/xuejianqiang/5810730

相关文章