STM32学习笔记(5)--- 定时器定时中断


前言

本章主要介绍STM32中的定时器外设,因为我个人写文章的主要目的是为了充当笔记的用途,所以我决定减少介绍的比例。(主要参考视频为《STM32入门教程-2023持续更新中》 作者:江协科技)


一、定时器(TIM)

1.1 介绍

定时器可以对输入的时钟进行计数,并在到达计数值时触发中断。

1.2 时基单元

时基单元是定时器的重要组成部分,其主要有以下部分组成:

  1. 16位计数器:简单来讲就是介绍中计数的部分,每来一个时钟都会使计数器加1,最大为2的16次方,即65536。
  2. 预分频器:即将输入的时钟进行分频,如果设置的为二分频而时钟为72MHz那么会被分频为36MHz。
  3. 自动重装寄存器:简单来讲就是存放目标值的寄存器,最大也同样为2的16次方。

1.3 定时器的种类

根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
在这里插入图片描述

PS:我使用的STM32F103C8T6定时器资源仅有TIM1、TIM2、TIM3、TIM4。

二、通用定时器

在这里插入图片描述
在这里插入图片描述
上图看上去非常复杂,但是基本可以分为三大块
在这里插入图片描述

  1. 主要是由之前介绍的时基单元组成。
  2. 主要是内外时钟源的选择和主从触发模式的结构,第一个外部时钟是TIMx_ETR引脚的外部时钟,其复用在了PA0的位置,也就是在PA0接上一个外部方波时钟,然后配置内部极性选择、边沿检测和预分频电路,在配置滤波电路就可以在ETRF进入触发控制器,第二个外部时钟是TRGI即让定时器充当其他定时器的从模式。
    在这里插入图片描述
  3. 主要是输入捕获功能和输出比较功能的结构,该内容会在之后进行详细的介绍。

三、定时中断基本结构

在这里插入图片描述

PS:在写代码时主要参考该结构图。

四、代码部分

1.1 接线图

在这里插入图片描述

1.2 初始化定时器

我们首先根据定时器中断结构来初始化定时器。
在这里插入图片描述

  1. RCC开启时钟
  2. 时钟源选择内部时钟模式
  3. 配置时基单元
  4. 配置输出控制
  5. 配置NVIC
  6. 运行控制

1.3 了解定时器库函数

  1. TIM_DeInit ---- 将TIMx外设寄存器初始化为其默认重置值
  2. TIM_TimeBaseInit ---- 配置时基单元
  3. TIM_TimeBaseStructInit ---- 赋予结构体变量默认值
  4. TIM_Cmd ---- 使能计数器(对应上图的运行控制)
  5. TIM_ITConfig ---- 对应中断输出控制
  6. TIM_InternalClockConfig ---- 对应时钟源选择中的内部时钟
  7. TIM_ITRxExternalClockConfig ---- 对应时钟源选择中的其他定时器
  8. TIM_TIxExternalClockConfig ---- 对应时钟源选择中的捕获通道
  9. TIM_ETRClockMode1Config ---- 对应时钟源选择中的外部时钟1
  10. TIM_ETRClockMode2Config ---- 对应时钟源选择中的外部时钟2
  11. TIM_ETRConfig ---- 配置ETR引脚的参数
  12. TIM_PrescalerConfig ---- 单独写入预分频值
  13. TIM_SetCounter ---- 单独给计数器写入值
  14. TIM_SetAutoreload ---- 单独写入自动重装寄存器的值
  15. TIM_GetCounter ---- 获取当前计数器的值
  16. TIM_GetPrescaler ---- 获取当前预分频器的值

1.4 初始化定时器代码部分

#include "stm32f10x.h"                  // Device header

extern uint16_t Num;

void Timer_init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);	//开启时钟
	
	TIM_InternalClockConfig(TIM2);	//选择内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBasestructure;
	TIM_TimeBasestructure.TIM_ClockDivision = TIM_CKD_DIV1;	//选择不分频
	TIM_TimeBasestructure.TIM_CounterMode = TIM_CounterMode_Up;	//选择向上计数
	TIM_TimeBasestructure.TIM_Period = 10000 - 1;	//ARR
	TIM_TimeBasestructure.TIM_Prescaler = 7200 - 1;	//PSC
	//      72MHz/(ARR+1)/(PSC+1) 此处定时1s即1Hz 
	TIM_TimeBasestructure.TIM_RepetitionCounter = 0;	//重复计数器
	TIM_TimeBaseInit(TIM2,&TIM_TimeBasestructure);
	
	TIM_ClearFlag(TIM2,TIM_IT_Update);	//清楚标志位
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);	
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//NVIC分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;	
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
}

1.5 主函数部分

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
#include "Timer.h"

uint16_t Num;

int main(void)
{
	OLED_Init();
	Timer_init();
	
	OLED_ShowString(1,1,"Num:");
	while(1)
	{
		OLED_ShowNum(1,5,Num,5);
	}
}

void TIM2_IRQHandler(void)	//定时器2中断函数(在startup_stm32f10x_md.s中寻找)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)	//获取中断标志位
	{
		Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);	//清楚标志位
	}
}

五、实验现象

实验结果:每过1s中OLED屏幕中Num+1
在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为您解答关于STM32系统滴答定时器(systick)应用的问题。 系统滴答定时器(systick)是STM32中一个非常重要的计时器,它是一个24位的递减计数器,每当计数器减为0时,会触发一个中断。它通常用于操作系统的时间片轮转、延时函数的实现等。 在STM32中,我们可以通过如下代码使能系统滴答定时器: ```c // 使能系统滴答定时器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; ``` 然后,我们可以通过如下代码设置系统滴答定时器的时钟源和计数器值: ```c // 设置系统滴答定时器的时钟源和计数器值 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk; // 使用处理器时钟作为时钟源 SysTick->LOAD = SystemCoreClock / 1000 - 1; // 设置计数器值为1ms ``` 在这段代码中,我们将系统滴答定时器的时钟源设置为处理器时钟,每次计数器减1代表1个处理器时钟周期的时间。然后我们将计数器的初值设置为`SystemCoreClock / 1000 - 1`,这里的`1000`代表我们希望系统滴答定时器每1ms中断一次。 最后,我们需要在中断服务函数中处理系统滴答定时器中断: ```c void SysTick_Handler(void) { // 处理系统滴答定时器中断 } ``` 在中断服务函数中,我们可以编写自己的代码来处理系统滴答定时器中断。例如,可以实现一个简单的延时函数: ```c void delay_ms(uint32_t ms) { uint32_t i; for (i = 0; i < ms; i++) { while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数器减为0 } } ``` 这个函数可以让程序在执行到它的时候暂停一段时间,等待系统滴答定时器中断触发一定次数后再继续执行。 希望这些代码可以帮助您更好地理解STM32系统滴答定时器的应用。如果您还有其他问题,请随时提出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值