当前位置: 首页 > ai >正文

32单片机——基本定时器

        STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源

1、定时原理

1.1 软件定时原理

使用纯软件(CPU死等)的方式实现定时(延时)功能

void delay_us(uint32_t us) {    

        us *= 72;    

        while(us--);

}

缺点:①延时不精准;②CPU死等(阻塞) 

1.2 定时器定时原理

使用精准的时基,通过硬件的方式,实现定时功能

定时器核心就是计数器

 定时器简易框图

1.3 定时器分类

常规定时器的区别 

1.4 定时器特性表

2、基本定时器

2.1 简介

        STM32F103有两个基本定时器TIM6和TIM7,它们的功能完全相同,资源是完全独立的,可以同时使用
        其主要特性如下:16位自动重载 递增 计数器(计数值:0~65535);16位可编程预分频器(预分频系数:1~65536),用于对计数器时钟频率进行分频;还可以触发DAC的同步电路;在更新事件(计数器溢出)时,产生中断/DMA请求

2.2 框图

2.3 溢出时间计算公式

T_{out}:定时器溢出时间

F_{t}:定时器的时钟源频率,72Mhz

ARR:自动重装载寄存器的值

PSC:预分频寄存器的值

3、定时器中断的配置步骤

3.1 配置定时器基础工作参数

void base_tim_init(uint16_t arr,uint16_t psc);  //自己写的初始化函数

3.2 定时器基础MSP初始化

__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);  //配置NVIC、CLOCK等

3.3 使能更新中断并启动计数器

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);

{
  TIM_TypeDef                        *Instance;         /*  寄存器基地址  */
  TIM_Base_InitTypeDef         Init;                   /*  TIM时基所需参数  */
......

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
......
#endif 
} TIM_HandleTypeDef;

typedef struct
{
  uint32_t Prescaler;                  /*  预分频系数(范围:0x0000~0xFFFF)  */

  uint32_t CounterMode;           /*  计数模式  */

  uint32_t Period;                      /*  自动重装载值(范围:0x0000~0xFFFF)  */

  uint32_t ClockDivision;           /*  预分频因子,高级定时器会用到  */

  uint32_t RepetitionCounter;  

  uint32_t AutoReloadPreload;  /*  自动重装载预装载使能  */
} TIM_Base_InitTypeDef;

CounterMode 如下所示:

#define TIM_COUNTERMODE_UP              0x00000000U   

                                                                                                /*  用作向上计数器的计数器  */
#define TIM_COUNTERMODE_DOWN        TIM_CR1_DIR

                                                                                                /*!< 用作向下计数器的计数器 */
#define TIM_COUNTERMODE_CENTERALIGNED1     TIM_CR1_CMS_0   

                                                                                                                /*  居中对齐模式1  */
#define TIM_COUNTERMODE_CENTERALIGNED2     TIM_CR1_CMS_1                        

                                                                                                                /*  居中对齐模式2  */
#define TIM_COUNTERMODE_CENTERALIGNED3     TIM_CR1_CMS                          

                                                                                                                /*  居中对齐模式3  */

AutoReloadPreload 如下所示:

#define TIM_AUTORELOAD_PRELOAD_DISABLE        0x00000000U              

                                                                                                 /*   TIMx_ARR寄存器未缓冲  */
#define TIM_AUTORELOAD_PRELOAD_ENABLE       TIM_CR1_ARPE              

                                                                                                 /*  TIMx_ARR寄存器已缓冲  */ 

3.4 设置优先级,使能中断

HAL_NVIC_SetPriority();

HAL_NVIC_EnableIRQ();

在32单片机——外部中断_32中断-CSDN博客中有解释

3.5 编写中断服务函数

void TIM6_IRQHandler(void){
    HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);  //中断公共处理函数
}

3.6 编写定时器更新中断回调函数

__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

例子

使用基本定时器TIM6实现精准定时,使LED1每隔500ms翻转一次,在主函数用LED0的翻转来提示程序正在运行
分析:实现500ms定时  psc:7199;arr:4999 

base_time.h

#ifndef _BASE_TIME_H
#define _BASE_TIME_H
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"

//定时器初始化
void base_tim_init(uint16_t arr,uint16_t psc);

#endif


 

base_time.c

#include "./BSP/TIMER/base_tim.h"
TIM_HandleTypeDef base_tim_handle;  //定时器句柄
void base_tim_init(uint16_t arr,uint16_t psc){
    base_tim_handle.Instance=TIM6;  //寄存器基地址
    base_tim_handle.Init.Prescaler=psc;  //预分频系数
    base_tim_handle.Init.Period=arr;  //自动重装载值
    base_tim_handle.Init.CounterMode=TIM_COUNTERMODE_UP;  //计数模式
    base_tim_handle.Init.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE;  //自动重装载预装载使能
    //base_tim_handle.Init.ClockDivision=  //预分频因子,高级定时器会用到
    HAL_TIM_Base_Init(&base_tim_handle);
    
    //开启定时器
    HAL_TIM_Base_Start_IT(&base_tim_handle);
}
//定时器Msp回调函数
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim){
    if(htim->Instance==TIM6){
        //CLOCK
        __HAL_RCC_TIM6_CLK_ENABLE();
        //设置优先级
        HAL_NVIC_SetPriority(TIM6_IRQn,0,0);
        HAL_NVIC_EnableIRQ(TIM6_IRQn);
    }
}
//中断服务函数
void TIM6_IRQHandler(void){
    HAL_TIM_IRQHandler(&base_tim_handle);  //中断公共处理函数
}
//定时器更新中断回调函数  定时500ms

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if(htim->Instance==TIM6){
        HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
    }
}

main.c

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

int main(void){
    uint8_t i=0;
    HAL_Init();
    sys_stm32_clock_init(RCC_PLL_MUL9);  //设置系统时钟
    delay_init(72);
    
    led_init();
    base_tim_init(4999,7199);
    
    while (1){
        i++;
        if(i>20){
            i=20;
            delay_ms(100);
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);  //LED0闪烁,指示程序正常运行
        }
  }
}


 

http://www.xdnf.cn/news/12295.html

相关文章:

  • NVIDIA Dynamo:数据中心规模的分布式推理服务框架深度解析
  • 深入了解JavaScript当中如何确定值的类型
  • 第二十八章 RTC——实时时钟
  • 使用 Ansible 在 Windows 服务器上安装 SSL 证书
  • Neo4j 集群管理:原理、技术与最佳实践深度解析
  • 基于J2EE架构的在线考试系统设计与实现【源码+文档】
  • Keepalived双主模式的高可用性解决方案!
  • caliper config.yaml 文件配置,解释了每个配置项的作用和注意事项
  • 越狱蒸馏-可再生安全基准测试
  • 七、数据库的完整性
  • mysql+keepalived
  • 李沐《动手学深度学习》d2l安装教程
  • pikachu靶场通关笔记17 CSRF关卡03-CSRF(Token)
  • Java持久层技术对比:Hibernate、MyBatis与JPA的选择与应用
  • 重构城市应急指挥布控策略 ——无人机智能视频监控的破局之道
  • 【HarmonyOS 5】教育开发实践详解以及详细代码案例
  • 抽象工厂模式深度解析:从原理到与应用实战
  • ​​高频通信与航天电子的材料革命:猎板PCB高端压合基材技术解析​​
  • CentOS 7 如何安装llvm-project-10.0.0?
  • Matlab实现任意伪彩色图像可视化显示
  • 机器学习KNN算法全解析:从原理到实战
  • rk3588 区分两个相同的usb相机
  • 数据库管理与高可用-MySQL主从复制与读写分离
  • Redux 实践与中间件应用
  • 分布式Session处理的五大主流方案解析
  • Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(八):异步处理逻辑详解
  • Copilot for Xcode (iOS的 AI辅助编程)
  • ubuntu 22 安装milvus
  • 【QT面试题】(二)
  • RocketMQ入门5.3.2版本(基于java、SpringBoot操作)