STM32F429通用定时器(TIM)

目录

一、通用定时器是什么?

1.计数模式

2.工作过程​编辑

3.内部时钟选择

二、通用定时器HAL库函数流程

三、小实验程序要求

四、代码实现

1.TIM.h

2.TIM.c

3.main.c


一、通用定时器是什么?

        通用定时器包含一个 16 位或 32 位自动重载计数器( CNT),该计数器由可编程预分频器( PSC) 驱动。 STM32F429 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32F429 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

1.计数模式

        通用定时器可以向上计数,向下计数、向上向下双向计数模式。

        ①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

        ②向下计数模式:计数器从自动加载值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

        ③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

STM32F429通用定时器(TIM)_第1张图片

2.工作过程STM32F429通用定时器(TIM)_第2张图片

        红色框作用就是产生CK_PSC时钟,之后经过CK_PSC预分频器,到CNT计数器,可以通过触发控制器里的从模式控制器来使CNT复位、使能、递增/递减等等。

        四种来源产生CK_PSC时钟(计数器时钟可以由以下时钟源提供):

        1.内部时钟(CK_INT);

        2.TIMx_ETR(外部时钟来源);

        3.ITR0-ITR4(定时器级联:输出的定时器可以作为输入)(内部触发输入口)经过选择器选择哪一路,一路到触发控制器;

        4.通过外部通道引脚TIMx_CH1和TIMx_CH2,经过Tl1FP1和Tl2FP2选择器到达触发控制器。   

3.内部时钟选择

        STM32F429通用定时器(TIM)_第3张图片

        如果APB1分频系数是1,则CK_INT就是×1倍,就该是多是是多少;如果APB1分频系数是2或者4或者其他的系数,则CK_INT就得×2倍。

        对于F407,配置系统时钟为:

        SYSCLK = 168M;        AHB时钟 = 168M;        APB1时钟 = 42M;

        APB1分频系数 = AHB / APB1 = 4,所以通用定时器CK_INT = 2 * 42M = 48

二、通用定时器HAL库函数流程

        1.TIMx时钟使能(x:2~5)        拿TIM3为例

        HAL_RCC_TIM3_CLK_ENABLE();        // 使能TIM3时钟

        2.初始化定时器参数,设置自动重装值,分频系数,计数方式等

        HAL_TIM_Base_Init();

        3.使能定时器更新中断,使能定时器

        HAL_TIM_Base_Start_IT;        // 使能句柄指定的定时器更新中断

        HAL_TIM_Base_Start;           // 使能句柄指定的定时器

       

        4.TIM3中断优先级设置

        HAL_NVIC_SetPriority(TIM3_IRQn, x, x);

        HAL_NVIC_EnableIRQ(TIM3_IRQn);

       

        5.编写中断服务函数(也要编写中断回调函数)

        void HAL_TIM_IRQHandler();        // 中断服务函数

        HAL_TIM_IRQHandler();                // 中断处理入口函数

        void HAL_TIM_PeriodElapseCallback();        // 定时器更新中断回调函数

三、小实验程序要求

        通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED1实现LED1状态取反。LED0在主函数利用delay_ms实现1s一次反转。

                                公式:Tout(溢出时间) = (ARR + 1)(PSC + 1) / Tclk

例如500ms:

        ARR + 1 = 5000        PSC + 1 = 9000        Tclk = 90M(STM32F429)

        Tout = 500ms

四、代码实现

1.TIM.h

#ifndef __TIM3_H
#define __TIM3_H

#include "sys.h"

void TIM3_Init(void);
#endif

2.TIM.c

#include "TIM3.h"
#include "led.h"

TIM_HandleTypeDef TIM3_Handler;                         // TIM句柄

void TIM3_Init(void)
{

    TIM3_Handler.Instance = TIM3;
    TIM3_Handler.Init.Period = 4999;                    // 自动装载值,公式中会自动加1                         
    TIM3_Handler.Init.Prescaler = 8999;                 // 预分频器,公式中会自动加1                     
    TIM3_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;

    HAL_TIM_Base_Init(&TIM3_Handler);                   // TIM初始化

    HAL_TIM_Base_Start_IT(&TIM3_Handler);               // 使能定时器3,并且开启更新中断

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)      // Init回调函数
{

    if (htim->Instance == TIM3)                          // 定时器中得判断是否为TIM3,也可也用else if来判断其他的定时器
    {

        __HAL_RCC_TIM3_CLK_ENABLE();                    // 时钟使能
    
        HAL_NVIC_EnableIRQ(TIM3_IRQn);                      // 使能TIM3中断
        HAL_NVIC_SetPriority(TIM3_IRQn, 2, 3);              // 中断优先级

    }
    
}

void TIM3_IRQHandler(void)         // 中断服务函数
{

    HAL_TIM_IRQHandler(&TIM3_Handler);                  // 中断处理入口函数

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)     // 中断回调函数
{

    if (htim->Instance == TIM3)                         
    {

        LED1 = !LED1;                                       // LED1反转

    }
    
}

3.main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "TIM3.h"

int main()
{

    HAL_Init();
    Stm32_Clock_Init(360, 25, 2, 8);
    delay_init(180);
    uart_init(115200);
    led_Init();  
    TIM3_Init();

    while (1)
    {
         LED0 = !LED0;
         delay_ms(1000);
    }
    

}

你可能感兴趣的:(stm32,单片机,arm,嵌入式硬件)