首页 > 其他分享 >5.APM32-TMR-基本定时器定时

5.APM32-TMR-基本定时器定时

时间:2024-11-16 10:15:42浏览次数:3  
标签:count TMR 定时器 timer BASE APM32 TMRX

效果展示

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="MJsKzV7C-1731566505079" src="https://live.csdn.net/v/embed/432499"></iframe>

TMR-基本定时器定时


使用基本定时器进行定时,使LED按 1 Hz的频率闪烁

硬件原理图

LED模块

我们这次只用到PA8引脚,其他几个引脚不看

源代码

关于LED的代码就不贴出了,LED相关代码可以在流水灯文章中找到。

定时器部分

#ifndef __BSP_BASE_TMR_H__
#define __BSP_BASE_TMR_H__
/* 包含头文件 ----------------------------------------------------------------*/
#include "apm32f10x.h"
#include "apm32f10x_tmr.h"
#include "apm32f10x_rcm.h"
#include "apm32f10x_misc.h"

// 如果使用TIM7,注释掉这个宏即可
#define USE_TMR6

#ifdef USE_TMR6 // 使用基本定时器TIM6

#define BASE_TMRX TMR6
#define BASE_TMRX_CLOCK RCM_APB1_PERIPH_TMR6
#define BASE_TMRX_IRQn TMR6_IRQn

#else // 使用基本定时器TIM7

#define BASE_TMRX TMR7
#define BASE_TMRX_CLOCK RCM_APB1_PERIPH_TMR7
#define BASE_TMRX_IRQn TMR7_IRQn

#endif
/* 函数声明 ------------------------------------------------------------------*/

void Base_TMRx_Config(void);

#endif

#include "bsp_base_tmr.h"

/**
 * @brief 配置基本定时器
 * @param 无
 * @attention TMR_BaseConfig_T结构体里面有5个成员,TMR6和TMR7的寄存器里面只有
 *            division和period,所以使用TMR6和TMR7的时候只需初始化这两个成员即可,
 *            另外三个成员是通用定时器和高级定时器才有.
 */
void Base_TMRx_Config(void)
{
    TMR_BaseConfig_T TMR_BaseConfigStruct;

    // 开始定时器时钟,基本定时器只有内部时钟
    RCM_EnableAPB1PeriphClock(BASE_TMRX_CLOCK);
    // 配置优先级分组
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);
    // 中断周期为 = 1/(72MHZ /(71+1)) * 1000 = 1ms
    TMR_BaseConfigStruct.division = 71;
    TMR_BaseConfigStruct.period = 999;
    TMR_ConfigTimeBase(BASE_TMRX, &TMR_BaseConfigStruct);
    // 清除计数器中断标志位
    TMR_ClearIntFlag(BASE_TMRX, TMR_INT_UPDATE);
    // 开启定时器更新中断
    TMR_EnableInterrupt(BASE_TMRX, TMR_INT_UPDATE);
    // 配置定时器中断优先级
    NVIC_EnableIRQRequest(BASE_TMRX_IRQn, 3, 0);
    // 使能定时器
    TMR_Enable(BASE_TMRX);
}

主程序部分

/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp_led.h"
#include "bsp_base_tmr.h"
/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
__IO uint16_t timer_count = 0;

/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/

/**
 * @brief 主函数
 * @return 无
 */
int main(void)
{
    // 初始化板载LED灯
    LED_GPIO_Config();
    // 基本定时器初始化:1ms中断一次
    Base_TMRx_Config();

    while (1)
    {
        if (timer_count == 1000)
        {
            timer_count = 0;
            LED1_TOGGLE;
        }
    }
}

中断部分

/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp_led.h"
#include "bsp_base_tmr.h"
/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
__IO uint16_t timer_count = 0;

/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/

/**
 * @brief 主函数
 * @return 无
 */
int main(void)
{
    // 初始化板载LED灯
    LED_GPIO_Config();
    // 基本定时器初始化:1ms中断一次
    Base_TMRx_Config();

    while (1)
    {
        if (timer_count == 1000)
        {
            timer_count = 0;
            LED1_TOGGLE;
        }
    }
}
 

代码分析

bsp_base_tmr.h该文件里都是各种宏定义我们就不看了,我们主要来看bsp_base_tmr.c文件中的内容

bsp_base_tmr.c

主要来讲下基本定时器的配置如何配置,之前说过标准库使用套路,套路如下:

  1. 声明定时器配置结构体
  2. 开启定时器对应时钟
  3. 配置结构体
  4. 将结构体填入初始化函数中
  5. 使能定时器

我们来具体看看结构体怎么配

/**
 * @brief    TMR Base Configure structure definition
 */
typedef struct
{
    TMR_COUNTER_MODE_T     countMode;
    TMR_CLOCK_DIV_T        clockDivision;
    uint16_t               period;            /*!< This must between 0x0000 and 0xFFFF */
    uint16_t               division;          /*!< This must between 0x0000 and 0xFFFF */
    uint8_t                repetitionCounter; /*!< This must between 0x00 and 0xFF, only for TMR1 and TMR8. */
} TMR_BaseConfig_T; ;
  • countMode计数模式:TMR_COUNTER_MODE_UP向上计数、TMR_COUNTER_MODE_DOWN向下计数、TMR_COUNTER_MODE_CENTERALIGNED1中心对齐模式1、TMR_COUNTER_MODE_CENTERALIGNED2中心对齐模式2、TMR_COUNTER_MODE_CENTERALIGNED3中心对齐模式3

  • clockDivision时钟分频系数:TMR_CLOCK_DIV_11分频也就是不分频、TMR_CLOCK_DIV_2二分频,TMR_CLOCK_DIV_4四分频

  • period周期:0-65535

  • division预分频系数周期:0-65535

  • repetitionCounter重复计数:0-255

    在讲这些参数怎么选之前我们先来看下基本定时器的结构框图,参考手册197页,结构框图如下

    在这里插入图片描述

    基本定时器的时钟源只有内部时钟,内部时钟经过clockDivision变成CK_INT,CK_INT经过控制器和division(预分频器)变成CK_CNT。

    • countMode在基本定时器(TMR6和7)配置中只能选TMR_COUNTER_MODE_UP,因为基本定时器只有向上计数模式

    • clockDivision,我们内部时钟频率为72MHz,设置成TMR_CLOCK_DIV_1,分频后频率为72MHz

    • division,我们设置成71,实际分频(71+1),经过分频后,计数频率变为1MHz,至于这里为什么要加1?芯片就是这样设计的,可以看参考手册202页17.6.7

    • repetitionCounter高级定时器中的,我们用不到

    • period,我们设置成999,周期
      T = 1 72  MHz 71 + 1 × 1000 = 1  ms T = \frac{1}{\frac{72 \text{ MHz}}{71+1}} \times 1000 = 1 \text{ ms} T=71+172 MHz​1​×1000=1 ms
      这里设置成999,计数周期为什么是1000?可以这样理解,计数到999时还要再计数一次才会溢出所以是1000。

      我们的程序里还开启了定时器更新中断TMR_EnableInterrupt(BASE_TMRX, TMR_INT_UPDATE);,开启中断后还要配置下NVIC,NVIC_EnableIRQRequest(BASE_TMRX_IRQn, 3, 0);,因为所有的中断都是由NVIC管理的。

    apm32f10x_it.c

    void TMR6_IRQHandler(void)
    {
        extern __IO uint16_t timer_count;
        if (TMR_ReadIntFlag(BASE_TMRX, TMR_INT_UPDATE) != RESET)
        {
            TMR_ClearIntFlag(BASE_TMRX, TMR_INT_UPDATE); // 清除更新中断标志位
            timer_count++;
        }
    }
    
    

    timer_count在main.c文件中声明__IO uint16_t timer_count = 0;,该中断服务函数主要功能就是计数,没进一次中断timer_count加1。

    main.c

    /**
     * @brief 主函数
     * @return 无
     */
    int main(void)
    {
        
        // 初始化板载LED灯
        LED_GPIO_Config();
        // 基本定时器初始化:1ms中断一次
        Base_TMRx_Config();
    
        while (1)
        {
            if (timer_count == 1000)
            {
                timer_count = 0;
                LED1_TOGGLE;
            }
        }
    }
    

    main程序中主要功能是翻转LED,当中断中timer_count到1000就翻转LED的状态。

标签:count,TMR,定时器,timer,BASE,APM32,TMRX
From: https://blog.csdn.net/showgu/article/details/143770951

相关文章

  • 4.APM32-USART-串口接发
    效果展示USART-串口接发硬件原理图我们使用的开发板上没有USB转串口的芯片,如果要连接到电脑上还需要使用USB转串口的模块或者jlink自带的虚拟串口。开发板的PA9(TX)引脚接USB转串口模块的RX引脚,开发板的PA10(RX)引脚接USB转串口模块的TX引脚,同时双方的GND还要连起......
  • APM32实现printf串口打印
    Keil环境在Keil环境中使用printf,首先需要打开UseMicroLib,这个库是keil专门为嵌入式设备定制的,比C语言自带的库如stdio、string等占用空间更小,效率更高。首先要点击Keil的魔术棒,如下图把UseMicroLib打上勾,如下图还要包含头文件#include<stdio.h>,在Keil中串口重定向......
  • Flutter进阶(4):定时器使用(Timer)
    一、Timer简介Flutter的Timer类是Dart语言中的一个内置类,用于创建定时器。定时器可以用于在一段时间后执行代码,或者以固定的时间间隔重复执行代码。Timer类提供了一种简单的方式来管理这些时间相关的任务。二、Timer类的详细介绍2.1导入dart:async包要使用Timer类,首......
  • 关于定时器周期、频率等相关计算
    1、定时器作为计数器,时钟频率计算如下图: 2、定时器产生一次更新中断时间计算,如下:当定时器设置为边沿对齐模式和向上计数模式时,定时器计数到重装载值(arr)产生一次中断,产生一次中断的时间为: 其中:T为定时器周期,也为此处产生一次中断的时间;      arr为重装载值,即定......
  • qt定时器
    首先测试以下qt定时器的精确度运行结果:timer:5999*10mselapsed:59996结论:1min的延迟后,误差在6ms内如果你在Timeout槽函数中执行耗时操作,这将会影响定时器的精确性和响应性。具体来说,Qt的事件循环是基于单线程模型的,所有事件处理(包括定时器超时事件)都在主线程中进行。......
  • 分享一个select+定时器的一个代码
    问题1:下面代码输出什么packagemainimport( "fmt" "time")funcmain(){ //创建两个定时器,一个间隔为1秒,另一个间隔为2秒 ticker1:=time.NewTicker(1*time.Second) ticker2:=time.NewTicker(2*time.Second) //在一个新的goroutine中运行监听逻辑 gofun......
  • STM32CubeMX:使用DAC输出正弦波的三种方法(while,定时器中断,DMA)
    1.DAC概念简介:DAC的工作原理是根据数字输入信号的数值,生成相应的模拟输出电压或电流。它通常接收一个二进制数字输入,该数字代表了一个特定的数值范围。DAC通过将这个数字值转换为模拟信号的电压或电流水平来输出。(功能与ADC相反)2.正弦波输出方式1:简单粗暴while循环输出Cub......
  • 用Javafx开发定时器
    选中小时分钟秒代码附上:packagecom.example.javafx03;importjavafx.application.Application;importjavafx.fxml.FXMLLoader;importjavafx.scene.Parent;importjavafx.scene.Scene;importjavafx.scene.image.Image;importjavafx.stage.Stage;importjav......
  • 如何实现Delay_us和Delay_ms延时(SysTick定时器)
    SysTick定时器(SystemTickTimer)是ARMCortex-M内核中自带的一个24位递减计数器,通常用于产生系统节拍中断,为操作系统提供时基或用于一般性定时功能。它具有以下特点和用途:一、SysTick的介绍1.SysTick的主要用途(计时)操作系统心跳时基:在实时操作系统(RTOS)中,SysTick通常用于产......
  • STM32(hal库)中的定时器从模式TIM_SlaveConfigTypeDef结构体中的含义,以及可选参数的含义
            在STM32的HAL库中,定时器从模式配置结构体TIM_SlaveConfigTypeDef用于配置定时器作为从定时器时的相关参数。该结构体及其可选参数的含义对于理解和配置STM32定时器的从模式至关重要。以下是对该结构体及其参数的详细解释:TIM_SlaveConfigTypeDef结构体该结构......