STM32 HAL库开发——入门篇(2):定时器

这篇具有很好参考价值的文章主要介绍了STM32 HAL库开发——入门篇(2):定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、TIMER定时器概述

1.1 软件定时原理

1.2 定时器定时原理

1.3 STM32定时器分类

1.4 STM32定时器特性表

1.5 STM32基本、通用、高级定时器功能整体的区别

二、基本定时器

2.1 基本定时器简介

2.3 STM32定时器计数模式及溢出条件

2.4 定时器中断实验相关寄存器

2.5 定时器溢出时间计算方法

2.6 定时器中断实验配置步骤

2.7 编程实战:定时器中断实验

三、通用定时器

3.1 通用定时器简介

3.2 通用定时器框图 

3.3 计数器时钟源

3.3.1 外部时钟模式1

3.3.2 外部时钟模式2

3.3.3 内部触发输入 

3.4 通用定时器PWM输出实验

3.4.1 通用定时器输出比较部分框图

3.4.2 通用定时器输出PWM原理

3.4.3 PWM模式

3.4.4 通用定时器PWM输出实验配置步骤

3.4.5 编程实战:通用定时器PWM输出实验

3.5 通用定时器输入捕获实验

3.5.1 通用定时器输入捕获部分框图

3.5.2 通用定时器输入捕获脉宽测量原理

3.5.4  编程实战:通用定时器输入捕获实验

3.6 通用定时器脉冲计数实验

3.6.1 脉冲计数实验原理

3.6.2 通用定时器脉冲计数实验配置步骤

3.6.3 编程实战:通用定时器脉冲计数实验

四、高级定时器

4.1 高级定时器简介

4.2 高级定时器框图

4.3 高级定时器输出指定个数PWM实验

4.3.1 重复计数器特性 

4.3.2 高级定时器输出指定个数PWM个数


使用正点原子stm32f103精英版 

STM32 HAL库开发——入门篇(2):定时器

一、TIMER定时器概述

STM32 HAL库开发——入门篇(2):定时器

1.1 软件定时原理

软件延时过程中,程序就进入延时函数中,无法执行其他程序

下图的72,是因为f103的主频是72MHz,这样调用延时肯定是不精准的

STM32 HAL库开发——入门篇(2):定时器

1.2 定时器定时原理

STM32 HAL库开发——入门篇(2):定时器

1.3 STM32定时器分类

STM32 HAL库开发——入门篇(2):定时器

实时时钟就是 RTC 

1.4 STM32定时器特性表

STM32 HAL库开发——入门篇(2):定时器

1.5 STM32基本、通用、高级定时器功能整体的区别

STM32 HAL库开发——入门篇(2):定时器

二、基本定时器

STM32 HAL库开发——入门篇(2):定时器

2.1 基本定时器简介

STM32 HAL库开发——入门篇(2):定时器

基本定时器的时钟来源只能是内部时钟

STM32 HAL库开发——入门篇(2):定时器       通过程序的方式无法直接访问影子寄存器,但可以通过写入arr自动重载寄存器,它再转移到影子寄存器生效,此时ARR寄存器就起到一个缓冲或缓存的作用

       事件是默认产生;中断和DMA输出是默认不产生,但可以配置产生 

        ARPE位的作用:设置有缓冲作用后,ARR的值要等事件发生后写入影子寄存器;设置没有缓冲作用的话,ARR的值就马上转移到影子寄存器中生效

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器       虽然最大总线的最大时钟频率是72、36MHz,但定时器的最大时钟频率不一定有这么大 

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

       可以看到例程中 APB2 预分频系数是1,所以最大还是72MHz 

       APB1 预分频系数是2,APB1时钟是从AHB 2分频过来的,所以APB1给到定时器的时钟要乘2,定时器时钟就也是72Mhz了

2.3 STM32定时器计数模式及溢出条件

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

2.4 定时器中断实验相关寄存器

STM32 HAL库开发——入门篇(2):定时器如一个例子,控制led亮1s,灭2s

(1)当没有缓冲时,假设先设置arr=99,1s后更新灭,然后重新写入arr=199灭2s,这其中写arr的值也需要时间

(2)而有缓冲时,假设先设置arr=99,1s后更新灭,然后在这1s内写入arr=199,此时因为有缓冲所以arr的值不会立即写入要等更新后写入,所以就节省了写入arr值的时间,减小了误差

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

2.5 定时器溢出时间计算方法

STM32 HAL库开发——入门篇(2):定时器ARR也是同理,寄存器最小值为0,我从0数到3,你不能说我就数了3个数吧,当然是3+1=4个数 

2.6 定时器中断实验配置步骤

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器基地址:

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器基本定时器技术模式固定递增,无分频因子

重复计数器寄存器只有高级定时器才有 

自动重载预装载使能就是CR1寄存器的位7:APRE

STM32 HAL库开发——入门篇(2):定时器

基本定时器只有更新中断 

STM32 HAL库开发——入门篇(2):定时器

2.7 编程实战:定时器中断实验

       更新中断产生的方式:

       (1)定时器溢出时伴随更新时间和更新中断的产生

       (2)通过软件设置UG位产生软件的更新时间从而产生更新中断

       这里使用定时器溢出的方式 

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

#include "./BSP/TIMER/timer.h"
#include "./BSP/LED/led.h"

TIM_HandleTypeDef g_timx_handle;

/* 定时器中断初始化函数 */
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{
    g_timx_handle.Instance = TIM6;
    g_timx_handle.Init.Prescaler = psc;
    g_timx_handle.Init.Period = arr;
    HAL_TIM_Base_Init(&g_timx_handle);
    
    HAL_TIM_Base_Start_IT(&g_timx_handle);

}



/* 定时器基础MSP初始化函数 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)
    {
        __HAL_RCC_TIM6_CLK_ENABLE();
        HAL_NVIC_SetPriority(TIM6_IRQn, 2, 3);
        HAL_NVIC_EnableIRQ(TIM6_IRQn);
    
    }

}



/* 定时器6中断服务函数 */
void TIM6_IRQHandler()
{
    HAL_TIM_IRQHandler(&g_timx_handle);
}



/* 定时器溢出中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)  /* 判断是定时器6,否则多个定时器进来会混乱 */
    {
        LED0_TOGGLE();
    
    }


}

三、通用定时器

STM32 HAL库开发——入门篇(2):定时器

3.1 通用定时器简介

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器       通用定时器时钟来自RCC内部时钟,有4类:

       (1)APB总线上的时钟

       (2)ITR0-4内部触发输入时钟部分

       (3)可以复用为ETR引脚的IO口

STM32 HAL库开发——入门篇(2):定时器

       (4)定时器的通道1、通道2

STM32 HAL库开发——入门篇(2):定时器

如:STM32 HAL库开发——入门篇(2):定时器

3.2 通用定时器框图 

STM32 HAL库开发——入门篇(2):定时器 

3.3 计数器时钟源

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

3.3.1 外部时钟模式1

TI1_ED 来自通道1,双边沿

TI1FP1、TI2FP2来自通道1、2,单边沿 

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

3.3.2 外部时钟模式2

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

3.3.3 内部触发输入 

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器只有通用和高级定时器才可以参与

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

3.4 通用定时器PWM输出实验

STM32 HAL库开发——入门篇(2):定时器

3.4.1 通用定时器输出比较部分框图

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

3.4.2 通用定时器输出PWM原理

STM32 HAL库开发——入门篇(2):定时器

3.4.3 PWM模式

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

3.4.4 通用定时器PWM输出实验配置步骤

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

3.4.5 编程实战:通用定时器PWM输出实验

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

#include "./BSP/TIMER/gtim.h"

TIM_HandleTypeDef g_timx_pwm_chy_handle;


/* 通用定时器PWM输出初始化函数 */
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc)
{
    TIM_OC_InitTypeDef timx_oc_pwm_chy;
    
    g_timx_pwm_chy_handle.Instance = TIM3;
    g_timx_pwm_chy_handle.Init.Prescaler = psc;
    g_timx_pwm_chy_handle.Init.Period = arr;
    g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; // 计数模式
    HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);
    
    timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;
    timx_oc_pwm_chy.Pulse = arr / 2;  // 比较值,就是CCRx的值
    timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW; // 输出极性为低,低电平有效
    HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_2);
    
    HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2);


}

/* 定时器输出PWM MSP初始化函数 */
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM3)
    {
        GPIO_InitTypeDef gpio_init_struct;
        __HAL_RCC_GPIOB_CLK_ENABLE();                                 /* LED0时钟使能 */
        __HAL_RCC_TIM3_CLK_ENABLE();                                 /* LED1时钟使能 */

        gpio_init_struct.Pin = GPIO_PIN_5;                   /* LED0引脚 */
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;            /* 复用推挽输出 */
        gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
        HAL_GPIO_Init(GPIOB, &gpio_init_struct);       /* 初始化LED0引脚 */

        /* 重映射 */
        __HAL_RCC_AFIO_CLK_ENABLE();
        __HAL_AFIO_REMAP_TIM3_PARTIAL();
    
    }

}



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

extern TIM_HandleTypeDef g_timx_pwm_chy_handle;

int main(void)
{
    uint16_t ledpwm = 0;
    uint8_t dir = 1;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    usart_init(115200);
    gtim_timx_pwm_chy_init(499, 71);   // 2KHz
    
    
    
    while(1)
    {
        
        delay_ms(10);
        
        if(dir) ledpwm++;
        else ledpwm--;
        
        if(ledpwm > 300) dir = 0;
        if(ledpwm == 0) dir = 1;
        
        __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_2, ledpwm);
    }
}

3.5 通用定时器输入捕获实验

STM32 HAL库开发——入门篇(2):定时器

3.5.1 通用定时器输入捕获部分框图

STM32 HAL库开发——入门篇(2):定时器只要 CC1S 不是00就是输入模式 

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器CCR1读操作完成后,影子寄存器的值才会被转移到预装载寄存器中  

3.5.2 通用定时器输入捕获脉宽测量原理

       t1 处产生一个捕获事件,将计数器的计数值转移到CCR1中 ,此时将计数器的值清零,将上升沿检测改为下降沿检测,

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器输入捕获分频系数:捕获几个上升沿触发 

Polarity

STM32 HAL库开发——入门篇(2):定时器

Selection 

STM32 HAL库开发——入门篇(2):定时器Prescaler 

STM32 HAL库开发——入门篇(2):定时器Filter

STM32 HAL库开发——入门篇(2):定时器

3.5.4  编程实战:通用定时器输入捕获实验

STM32 HAL库开发——入门篇(2):定时器

72Mhz / 72 =1MHz 就是1us(1微秒)计数一次

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

#include "./BSP/TIMER/gtim.h"



TIM_HandleTypeDef g_timx_cap_chy_handle;

void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc)
{
    TIM_IC_InitTypeDef timx_ic_cap_chy = {0};                       /* 初始化结构体变量建议给个初值0 */
    
    g_timx_cap_chy_handle.Instance = TIM5;                          /* 定时器5 */
    g_timx_cap_chy_handle.Init.Prescaler = psc;                     /* 定时器分频 */
    g_timx_cap_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 递增计数模式 */
    g_timx_cap_chy_handle.Init.Period = arr;                        /* 自动重装载值 */
    HAL_TIM_IC_Init(&g_timx_cap_chy_handle);
    
    timx_ic_cap_chy.ICPolarity = TIM_ICPOLARITY_RISING;             /* 上升沿捕获 */
    timx_ic_cap_chy.ICSelection = TIM_ICSELECTION_DIRECTTI;         /* 映射到TI1 */
    timx_ic_cap_chy.ICPrescaler = TIM_ICPSC_DIV1;                   /* 配置输入分频 */
    timx_ic_cap_chy.ICFilter = 0;                                   /* 配置输入滤波器 */
    HAL_TIM_IC_ConfigChannel(&g_timx_cap_chy_handle, &timx_ic_cap_chy, TIM_CHANNEL_1);

    __HAL_TIM_ENABLE_IT(&g_timx_cap_chy_handle, TIM_IT_UPDATE);     /* 使能更新中断 */
    HAL_TIM_IC_Start_IT(&g_timx_cap_chy_handle, TIM_CHANNEL_1);     /* 开始捕获TIM5的通道1,捕获中断使能 */

}


void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        GPIO_InitTypeDef gpio_init_struct;
        __HAL_RCC_TIM5_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        
        gpio_init_struct.Pin = GPIO_PIN_0;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP; // 复用功能是可以读取io的电平情况的,输出也能读值
        gpio_init_struct.Pull = GPIO_PULLDOWN;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
        
        HAL_NVIC_SetPriority(TIM5_IRQn, 1, 3);
        HAL_NVIC_EnableIRQ(TIM5_IRQn);
       
    }
}    

/* 输入捕获状态(g_timxchy_cap_sta)
 * [7]  :0,没有成功的捕获;1,成功捕获1次
 * [6]  :0,还没捕获到高电平;1,已经捕获到高电平
 * [5:0]:捕获高电平后溢出的次数,最多溢出63次,所以最长捕获值 = 63*65536 + 65535 = 4194303
 *        注意:为了通用,我们默认ARR和CCRy都是16位寄存器,对于32位的定时器(如TIM5),也只按16位计算
 *        F1系列定时器都是16位,把g_timxchy_cap_sta定义为uint16_t,还可以测的时间更长
 *        按1us的计数频率,最长溢时间为:4194303 us,约4.19s
 *
 *        说明一下:正常32位的定时器来说,1us计数器加1,溢出时间为4294秒,2^32 = 4294967296
 *
 */

uint8_t g_timxchy_cap_sta = 0;  /* 输入捕获状态 */
uint16_t g_timxchy_cap_val = 0; /* 输入捕获值 */

/* 定时器5中断服务函数 */
void TIM5_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_cap_chy_handle);
}

/* 定时器输入捕获中断回调函数 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        if((g_timxchy_cap_sta & 0x80) == 0) // 还没有成功捕获
        {
            if(g_timxchy_cap_sta & 0x40)    // 捕获下降沿
            {
                g_timxchy_cap_sta |= 0x80;   // 标记捕获到一次高电平
                g_timxchy_cap_val = HAL_TIM_ReadCapturedValue(&g_timx_cap_chy_handle, TIM_CHANNEL_1);
                TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1);  // 清除原来的设置
                TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);// 开启新一次捕获上升沿
            }
            else /* 还未开始,第一次捕获上升沿 */
            {
                g_timxchy_cap_sta = 0;
                g_timxchy_cap_val = 0;
                g_timxchy_cap_sta |= 0x40;   // 标记捕获到了上升沿
                __HAL_TIM_DISABLE(&g_timx_cap_chy_handle);              // 关闭定时器5
                __HAL_TIM_SET_COUNTER(&g_timx_cap_chy_handle, 0);       // 定时器5计数器清零
                TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1);// 清除原来的设置
                TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); // 捕获下降沿
                __HAL_TIM_ENABLE(&g_timx_cap_chy_handle);               // 使能定时器5
            }
        }
    }
}

/* 定时器更新中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        if((g_timxchy_cap_sta & 0x80) == 0) // 还没有成功捕获
        {
            if(g_timxchy_cap_sta & 0x40)    // 捕获下降沿
            {
                if((g_timxchy_cap_sta & 0x3F) == 0x3F) /* 高电平太长了 */
                {
                    TIM_RESET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1);// 清除原来的设置
                    TIM_SET_CAPTUREPOLARITY(&g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); // 设置捕获上升沿
                    g_timxchy_cap_sta |= 0X80;
                    g_timxchy_cap_val = 0XFFFF;
                }
                else   /* 累计定时器溢出次数 */
                {
                    g_timxchy_cap_sta++;
                }
            }
        }
    }

}


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

extern uint8_t g_timxchy_cap_sta;  /* 输入捕获状态 */
extern uint16_t g_timxchy_cap_val; /* 输入捕获值 */

int main(void)
{
    uint32_t temp = 0;
    uint8_t t = 0;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    usart_init(115200);
    gtim_timx_cap_chy_init(65535, 71);
    
    while(1)
    {
        if(g_timxchy_cap_sta & 0x80) // 还没有成功捕获
        {
            temp = g_timxchy_cap_sta & 0x3F;
            temp *= 65536;               /* 溢出时间总和 */
            temp += g_timxchy_cap_val;   /* 总的高电平时间 */
            printf("HIGH:%d us\r\n", temp);
            g_timxchy_cap_sta = 0;       /* 开启下一次捕获 */
        }
        
        t++;
        
        if(t > 20)                       /* 200ms进入一次 */
        {
            t = 0;
            LED0_TOGGLE();               /* LED0闪烁,提是程序在运行 */
        }
        delay_ms(10);
    }
}

3.6 通用定时器脉冲计数实验

STM32 HAL库开发——入门篇(2):定时器4个时钟源:(1)内部时钟;(2)外部触发1:由CH1、CH2;(3)外部触发2:由IO的ETR;(4)内部触发输入:一般用于级联 

STM32 HAL库开发——入门篇(2):定时器

3.6.1 脉冲计数实验原理

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

3.6.2 通用定时器脉冲计数实验配置步骤

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

SlaveMode:

STM32 HAL库开发——入门篇(2):定时器
 (1)DISABLE:不使用从模式就是使用内部时钟

 (2)RESET:复位 

 (3)GATED:门电路

 (4)TRIGGER:触发模式 

 (5)EXTERNAL1:外部时钟模式1

触发源: 

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器 

边沿检测器: 

STM32 HAL库开发——入门篇(2):定时器边沿检测器有2个, 上2个是上面的检测器,下3个是下面的检测器

STM32 HAL库开发——入门篇(2):定时器BOTHEDGE用处暂不明

分频器:

STM32 HAL库开发——入门篇(2):定时器外2会用到分频器,外1没用到 

滤波器:

STM32 HAL库开发——入门篇(2):定时器滤波器外1和外2都用到了,实验里没用

3.6.3 编程实战:通用定时器脉冲计数实验

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

#include "./BSP/TIMER/gtim.h"

TIM_HandleTypeDef g_timx_cap_chy_handle;

void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc)
{
    TIM_SlaveConfigTypeDef tim_slave_config = {0};
    
    g_timx_cap_chy_handle.Instance = TIM2;                          /* 定时器5 */
    g_timx_cap_chy_handle.Init.Prescaler = psc;                     /* 定时器分频 */
    g_timx_cap_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 递增计数模式 */
    g_timx_cap_chy_handle.Init.Period = arr;                        /* 自动重装载值 */
    HAL_TIM_IC_Init(&g_timx_cap_chy_handle);
    
    tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
    tim_slave_config.InputTrigger = TIM_TS_TI1FP1;
    tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
    tim_slave_config.TriggerFilter = 0;
    HAL_TIM_SlaveConfigSynchro(&g_timx_cap_chy_handle, &tim_slave_config);
    
    HAL_TIM_IC_Start(&g_timx_cap_chy_handle, TIM_CHANNEL_1);

}

void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM2)
    {
        GPIO_InitTypeDef gpio_init_struct;
        __HAL_RCC_TIM2_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        
        gpio_init_struct.Pin = GPIO_PIN_0;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP; // 复用功能是可以读取io的电平情况的,输出也能读值
        gpio_init_struct.Pull = GPIO_PULLDOWN;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; // 输入可以不设置速度
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
       
    }
}  
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/gtim.h"
#include "./BSP/KEY/key.h"

extern TIM_HandleTypeDef g_timx_cap_chy_handle;

int main(void)
{
    uint16_t curcnt;
    uint16_t oldcnt;
    uint8_t key;
    uint8_t t = 0;
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    usart_init(115200);
    gtim_timx_cap_chy_init(65535, 0);
    key_init();
    
    while(1)
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            __HAL_TIM_SET_COUNTER(&g_timx_cap_chy_handle, 0);
        }            
        
        curcnt = __HAL_TIM_GET_COUNTER(&g_timx_cap_chy_handle);
        if(oldcnt != curcnt)
        {
            oldcnt = curcnt;
            printf("CNT:%d\r\n", oldcnt);
        }
        t ++;
        
        if(t > 20)
        {
            t = 0;
            LED0_TOGGLE();
        }
        delay_ms(10);
    }
}

       此时定时器计数cnt == arr 的时候会溢出,因为设置了 arr = 65535,所以最大计数值即最大捕获数量就是 65535,如果要增大计数量,可以添加定时器更新中断

四、高级定时器

STM32 HAL库开发——入门篇(2):定时器

4.1 高级定时器简介

STM32 HAL库开发——入门篇(2):定时器STM32 HAL库开发——入门篇(2):定时器重复计数器,对REP寄存器写一个值,每次溢出就减1,指导减为0后,就产生更新事件

4.2 高级定时器框图

STM32 HAL库开发——入门篇(2):定时器通道1、2、3都有CHxN就是互补通道 

4.3 高级定时器输出指定个数PWM实验

STM32 HAL库开发——入门篇(2):定时器

4.3.1 重复计数器特性 

STM32 HAL库开发——入门篇(2):定时器

       再同步就是软件手动产生更新事件后,RCR寄存器的值会再缓冲到它的影子寄存器中,影子寄存器就被重置了

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

  

4.3.2 高级定时器输出指定个数PWM个数

STM32 HAL库开发——入门篇(2):定时器

STM32 HAL库开发——入门篇(2):定时器

 p105  5:43文章来源地址https://www.toymoban.com/news/detail-496647.html

到了这里,关于STM32 HAL库开发——入门篇(2):定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于STM32的定时器--定时中断(HAL库)

    本文旨在介绍如何使用STM32CubeMX配置+KEIL 5开发一个每10us定时器中断触发一次的项目。帮助初学者入门STM32的定时器使用。 定时器是STM32微控制器中非常重要的功能模块之一,用于计时、生成精确的时间延迟、触发事件等。STM32微控制器通常具有多个定时器模块,包括通用定时

    2024年02月14日
    浏览(24)
  • STM32 HAL库-定时器中断

    关闭或开启所有中断;代码如下: STM32F407 有众多的定时器,其中包括 2 个基本定时器(TIM6 和 TIM7)、10 个通用定时 器(TIM2 ~ TIM5、TIM9 ~TIM14)、2 个高级控制定时器(TIM1 和 TIM8),这些定时器彼此完 全独立,不共享任何资源。 选择定时器,配置时钟源,设置预分频系数,计

    2024年01月25日
    浏览(35)
  • stm32——hal库学习笔记(定时器)

    使用纯软件(CPU死等)的方式实现定时(延时)功能 使用精准的时基,通过硬件的方式,实现定时功能 递增计数模式实例说明 中心对齐模式实例说明 TIM6 和TIM7 控制寄存器 1(TIMx_CR1) TIM6 和TIM7 DMA/中断使能寄存器(TIMx_DIER) TIM6 和TIM7 状态寄存器(TIMx_SR) TIM6 和TIM7 计数器(TIMx_CNT)

    2024年02月21日
    浏览(29)
  • # HAL库STM32常用外设教程(四)—— 定时器 基本定时

    1、STM32F407ZGT6 2、STM32CubeMx软件 3、keil5 内容简述: 通篇文章将涉及以下内容,如有错误,欢迎指出 : 1、基础定时器特性 2、基础定时器的结构和功能 3、基础定时器HAL库驱动程序 (1)CubeMx配置 (2)TIM驱动程序   STM32F407有2个高级控制定时器(TIM1、TIM8)、8个通用定时器和

    2024年02月02日
    浏览(38)
  • STM32 HAL库 STM32CubeMX -- TIM(定时器中断)

    STM32F1 系列中,除了一些特殊的型号,大部分F1有8 个定时器,分为 基本定时器,通用定时器和高级定时器 。 基本定时器TIM6 和TIM7 是一个16 位的只能向上计数的定时器,只能定时,没有外部IO。 通用定时器TIM2/3/4/5 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出

    2024年02月16日
    浏览(38)
  • 【STM32】HAL库-系统滴答定时器SysTick

    SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3、CM4内核芯片,都有Systick定时器。Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。 Systick定时器就是系统滴答定时器,一个 24 位的倒计数定时器 ,计到0 时,将从

    2023年04月08日
    浏览(19)
  • STM32 hal库编程定时器计数清零

    1、stm32定时器是有重装载功能的,所以定时器中断不关的话,就不需要计数清零 2、主要是应对单次计时使用,可能因为没有清零导致程序再次运行到相同位置时,中断立即出发,没有完成计时的功能。 顺便加一个读取定时器计数值得函数

    2024年02月03日
    浏览(32)
  • STM32 HAL库 STM32CubeMX -- TIM(定时器输入捕获)

    输入捕获可以对 输入的信号的上升沿、下降沿或者双边沿进行捕获 ,常用的有 测量输入信号的脉宽 和 测量PWM 输入信号的频率 和 占空比 这两种。 输入捕获的原理 就是,当捕获到信号的跳变沿的时候,把计数器CNT 的值锁存到捕获寄存器CCR 中,把前后两次捕获到的CCR 寄存

    2023年04月14日
    浏览(69)
  • 【STM32】【HAL库】定时器编码器模式测速

    目录 概述 HAL设置  定时器的编码器模式 定时器设置  常用函数 代码 电机AB相增量型编码器的介绍和解码方法在这里介绍过了 电机编码器 https://blog.csdn.net/m0_57585228/article/details/125791283 测速可以使用外部中断进行脉冲计数 很多型号的单片机中有专门的电路来计算脉冲的速度和

    2023年04月18日
    浏览(35)
  • # HAL库STM32常用外设教程(四)—— 基础定时器

    1、STM32F407ZGT6 2、STM32CubeMx软件 3、keil5 内容简述: 通篇文章将涉及以下内容,如有错误,欢迎指出 : 1、基础定时器特性 2、基础定时器的结构和功能 3、基础定时器HAL库驱动程序 (1)CubeMx配置 (2)TIM驱动程序   STM32F407有2个高级控制定时器(TIM1、TIM8)、8个通用定时器和

    2024年02月04日
    浏览(26)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包