STM32的定时器

/*自己一直记不住的几个知识点整理,所以脚踩西瓜皮写到哪里是哪里,没有系统的学习价值*/

1.STM32常规定时器资源概览

①系统滴答计时器    systick

②看门狗定时器       watchdog

③实时时钟              rtc

④基本定时器          TIMx(x为几请自行查阅芯片手册)

⑤通用定时器          TIMx(同上)

⑥高级定时器          TIMx(同上)

注意:SysTick是集成在cortex-m内核中的,并不属于单片机的外设(peripheral),主要作用是给各类RTOS提供时钟节拍做时间基准。HAL库中的HAL_Delay()函数也是以它为基准,因此我们在给单片机移植RTOS时应该尽量避免使用HAL_Delay()函数。

定时器基本用途:输出比较、输入捕获、PWM生成、单脉冲模式输出等。

2.通用定时器介绍

通用定时器由一个可编程预分频器(Prescaler✖16)驱动的16位自动重装载主计数器(counter period)构成,可以对内部时钟或触发源以及外部时钟或触发源进行计数。

基本原理:①定时器时钟信号送入16位可编程预分频器,该预分频器系数∈[0,65535];

②等待预分频器溢出后,会向16位的空计数器发出一个脉冲信号。

总结:预分频器本质上是一个加法计数器,预分频系数实际上就是加计数的溢出值。cortex内核单片机内部有两根时钟总线,APB1与APB2,通用计数器挂载在APB1上,高级计时器挂载在APB2上。如图1所示假设我们的内核需要一个10000ms的周期计时,那么我们可以使能外部高速时钟给石英晶体振荡器加上一个电场,由于石英晶体具有各向异性它会周期地进行简谐振动。接下来令初始时钟信号是1k Hz,即让时钟信号线上存在一个周期位1ms的方波信号,然后把预分频系数设为10,即预分频器接受十个方波上升沿(0~9)之后输出一个周期为10ms的方波信号传入主计数器,主计数器计数值设置为1000,同样地再接受完1000个(0~999)上升沿之后主计数器会输出一个周期为10000ms的方波信号。(如果还想了解分频、倍频原理的话就自己翻翻模电书吧这里不细讲了。)这里机制也还没介绍完,还有影子寄存器、自动重装载寄存器啥的,大家感兴趣可以去看B站Keysking的视频动画讲解的,或者自己动手翻翻数据手册。

dfc10dd8969c49bcbb1caeec2389434c.png

 图1(有谁能在评论区教教我CSDN怎么画框图么😀)

这里再贴一下CubeMX里的时钟树方便理解记忆。

ebb274249b8944c29d15c9e505766dcd.png

 图2 将F429时钟树APB时钟线信号设置为90M Hz

3.定时器发生中断的计算方法

定时时间=(Prescaler+1)*(Counter Period+1)/定时器时钟频率

4.应用场景举例

HAL库函数实现us级别延时:

/* 个人代码库
 *
 * 基于TIM的us级别延时函数与ms级别延时函数 
 * Cubemx里面勾选Internal Clock,并且设置一个通用计时器的Prescaler的数值设置为x
 * x是时钟树上计时器频率的“M数” 减一
 * 适用于一般的通信协议
 *
 * 修改历史      版本号           作者        修改内容
 *-----------------------------------------------------
 * 2023.12.14     v1.0          Jumayusi      创建文件
 *-----------------------------------------------------
 */

#include "delay.h"

//延时nus
//nus:要延时的us数
void delay_us(uint32_t us)
{		
	uint16_t differ = 0xffff-us-5;                
	__HAL_TIM_SET_COUNTER(&htim5,differ);    
	HAL_TIM_Base_Start(&htim5);         
	
	while(differ < 0xffff-5){    
			differ = __HAL_TIM_GET_COUNTER(&htim5);        
	}
	HAL_TIM_Base_Stop(&htim5);
}

//延时nms
//nms:要延时的ms数
void delay_ms(uint16_t nms)
{
	uint32_t i;
	for(i=0;i<nms;i++) 
	{
	 delay_us(1000);
	}
}

#ifndef _DELAY_H
#define _DELAY_H

#include "main.h"
#include "tim.h"

void delay_us(uint32_t nus);
void delay_ms(uint16_t nms);

#endif

  /*有不对的地方还请各位大佬斧正,拜谢。*/

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值