STM32 基本定时器实验

1、基本定时器简介

在这里插入图片描述

  1. 时钟源
    时钟挂载在APB1总线下,中间有一个倍频器,sys_stm32_clock_init时钟已经设置APB1总线时钟频率为36M,预分频器分频系数为2,所以挂载在APB1总线的定时器时钟频率为72Mhz,图中对应的时钟信号为CK_INT。
  2. 控制器
    能够控制定时器复位、使能、计数,还能触发DAC转换。
  3. 时基单元
    时基单元包括:计数器寄存器、预分频寄存器、自动重载寄存器。预分频寄存器的输入来源于CK_PSC,也就是CK_INT,输出为CK_CNT,CK_CNT是通过预分频器分频后的信号。预分频寄存器和自动重载寄存器都有影子寄存器,影子寄存器就是当写入新的值的时候,这个值不会直接写进影子寄存器,会在寄存器中缓冲,在下一个更新事件出现的时候,才会写入,区别在于自动重载寄存器是否有缓冲作用还受到ARPE位控制。
  4. 更新事件
    一由软件产生,将TIMx_EGR寄存器的位UG置1,产生更新事件后,硬件会自动将UG位清零。
    二由硬件产生,当计数器的值等于自动重装载寄存器影子寄存器的值时。

2、寄存器

  • 控制寄存器(TIMx_CR1)

在这里插入图片描述

  • DMA/中断使能寄存器(TIMx_DIER) 位0控制使能或者禁止更新中断
  • 状态寄存器(TIMx_SR) 位0是中断更新的标志位,需要软件清零
  • 计数器寄存器(TIMx_CNT) [15:0]计数器的实时计数值
  • 预分频寄存器(TIMx_PSC) [15:0]预分频数值
  • 自动重载寄存器(TIMx_ARR) [15:0]自动重载数值

3、硬件

(1)功能
LED0用来指示程序运行,每200ms翻转一次。我们在更新中断中,将LED1的状态取反。 LED1用于指示定时器发生更新事件的频率,500ms取反一次
(2)资源
LED0-PB5
LED1-PE5
定时器

4、程序设计

定时器中断配置步骤
1)定时器时钟使能
__HAL_RCC_TIMx_CLK_ENABLE()
2) 初始化定时器参数,设置自动重装值,分频系数,计数方式
使用HAL_TIM_Base_Init(),传入TIM_HandleTypeDef类型结构体
3)使能定时器更新中断,开启定时器计数,配置定时器中断优先级
通过HAL_TIM_Base_Start_IT函数使能定时器更新中断和开启定时器计数
在HAL_TIM_Base_Init()函数中的HAL_TIM_Base_MspInit()函数中通过HAL_NVIC_EnableIRQ函数使能定时器中断,通过HAL_NVIC_SetPriority函数设置中断优先级
4)编写终端服务函数
编写BTIM_TIMX_INT_IRQHandler函数,调用公共接口HAL_TIM_IRQHandler,再编写回调函数,实现LED1翻转功能。

TIM_HandleTypeDef g_timx_handle;  /* 定时器句柄 */
//初始化基本定时器
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{
    g_timx_handle.Instance = BTIM_TIMX_INT;                      /* 通用定时器X */
    g_timx_handle.Init.Prescaler = psc;                          /* 设置预分频系数 */
    g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */
    g_timx_handle.Init.Period = arr;                             /* 自动装载值 */
    HAL_TIM_Base_Init(&g_timx_handle);         /*这个函数里会调用HAL_TIM_Base_MspInit*/

    HAL_TIM_Base_Start_IT(&g_timx_handle);    /* 使能定时器x及其更新中断 */
}
//初始化定时器底层驱动
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        BTIM_TIMX_INT_CLK_ENABLE();                     /* 使能TIM时钟 */
        HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 1, 3); /* 抢占1,子优先级3,组2 */
        HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn);         /* 开启ITM3中断 */
    }
}
//定时器中断服务函数
void BTIM_TIMX_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_handle); /* 定时器中断公共处理函数 */
}
//这个函数将会被定时器中断公共处理函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        LED1_TOGGLE(); /* LED1反转 */
    }
}

完成驱动文件后,main函数如下

int main(void)
{
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    delay_init(72);                         /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    btim_timx_int_init(5000 - 1, 7200 - 1); /* 10Khz的计数频率,计数5K次为500ms */

    while (1)
    {
        LED0_TOGGLE();            /*LED灯翻转*/
        delay_ms(200);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值