STM32 F103C8T6学习笔记4:时钟树、滴答计时器、定时器定时中断

2023-11-04

今日理解一下STM32F103 C8T6的时钟与时钟系统、滴答计时器、定时器计时中断的配置,文章提供原理,代码,测试工程下载。

目录

时钟树与时钟系统:

滴答计时器:

定时器计时中断:

测试结果:

测试工程下载:


时钟树与时钟系统:

该系统介绍在 STM32F10x-中文参考手册 P56页开始

微控制器的时钟系统包括以下几个主要的时钟源:

1. HSE(High-Speed External): 外部高速晶振,可接入外部晶振作为系统时钟源。
2. HSI(High-Speed Internal):   内部高速振荡器,提供内部时钟源。
3. PLL(Phase Locked Loop):   锁相环,可以通过将外部时钟源或内部时钟源倍频得到更高的系统时钟频率。

时钟系统的配置和选择可以通过对系统寄存器 RCC(Reset and Clock Control)的相应位进行配置。根据配置的不同,时钟系统可分为以下几个模式:

1. HSI模式:使用HSI作为系统时钟源。
2. HSE模式:使用HSE作为系统时钟源。
3. PLL模式:通过PLL倍频方式产生高频时钟。

1、单片机内部的RC振荡器是8Mhz
2、通过单片机引脚(OSC_IN OSC_OUT)接外部的晶振,这里就对外部的晶振有要求了,要求外部晶振输入频率范围是4Mhz~32Mhz
3、是通过单片机引脚接外部的低速32.768Khz晶振,这个是单独的给内部的实时时钟模块(RTC)使用
4、是内部的低速RC振荡器40K,可以给RTC用,也可以给IWDG看门狗模块用
5、是时钟信号从MCO这个引脚上输出,这个输出可以作为测试,看看内部的时钟配置是否正确,也可以用作和其他硬件进行时钟同步用

如上5种不同类型的时钟,供给不同的需求,内置的RC振荡器受到温度影响会大一些;
这几个外部时钟晶振接口,根据需求使用;也可选择不用,空着,或者接其他电路也可以;
时钟信号进来,还要操作一些相关寄存器 分频/倍频后,才成为"系统时钟SYSCLK"、HSI时钟、HSE时钟等等之类的,应用于单片机各个模块(比如定时器、ADC、USART、APB perpherials、I2C… )

滴答计时器:

#include "SysTick.h"

static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数


//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟的1/8
//SYSCLK:系统时钟频率
void SysTick_Init(u8 SYSCLK)
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
	fac_us=SYSCLK/8;					
	fac_ms=(u16)fac_us*1000;				   
}								    


//延时nus
//nus为要延时的us数.		    								   
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					//时间加载	  		 
	SysTick->VAL=0x00;        					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数	  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;      					 //清空计数器	 
}

//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;				//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;							//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;       					//清空计数器	  	    
} 

定时器计时中断:

查表可知,TIM2/3/4是适合作通用定时器的:

 此处我以初始化定时器4为通用定时器举例:

计数器溢出频率:   

CK CNT_OV= CK CNT   /    (ARR+1)

                     =  CK PSC  /    (PSC +1)  /  (ARR +1) 

这里的计数器溢出频率单位是赫兹,计数器溢出频率的倒数就是定时器触发的时间周期,一般我们计算用的是下面一个等于号的式子,这里的符号表示如下:

CK_PSC 一般为72Mhz(72 000 000)

ARR 自动重装 对应变量TIM_Period 范围0~65535

PSC 分频  对应变量 TIM_Prescaler 范围0~65535

1. 定时器时钟分频(TIMx_PSC)

是用来将系统时钟(通常为主频)分频为定时器的时钟频率。例如,如果系统时钟为72MHz,定时器时钟分频设置为72-1,则定时器时钟频率为1MHz。定时器时钟分频越大,定时器的时钟频率越低。

2. 预分频(TIMx_ARR)

是用来设置定时器溢出时间(自动重装载寄存器值)的参数。当定时器计数器达到预分频值时,定时器将溢出,并产生中断或其他相关事件。预分频的值决定了定时器溢出时间的长度。例如,如果预分频值为1000,定时器时钟频率为1MHz,则定时器溢出时间为1ms。

以下为初始化定时器  2  作定时中断,周期为1ms :

每次进入定时中断都会通过串口1 打印一次进入中断的总次数T:

#include "TIMER_init.h"

//初始化定时器2用作计时中断定时器:
void Timer2_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;	
	NVIC_InitTypeDef NVIC_InitStructure;
	
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	TIM_InternalClockConfig(TIM2);//选择哪个中断就写哪个
	
	
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //修改分频,对实际情况影响不大,可以不修改,这里是不分频(可选1~72)
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上对齐模式,同时还有向下对齐,中央对齐模式
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;							  //计数器周期。该参数决定了计数器计数溢出前的最大值。
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;							//分频器预分频系数。该参数决定了计数器时钟频率的变化程度。
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //高级计数器需要,不需要用到的直接给0就好
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);                           //用于解决一复位时就先进一次中断的情况
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	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);
	
}

定时中断服务函数:

#include "TIMER_init.h"

uint16_t T;

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		printf("T=%d",T);
		T++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中断寄存器标志位,用于退出中断
	}
}

测试结果:

测试工程下载:
https://download.csdn.net/download/qq_64257614/88202750?spm=1001.2014.3001.5503

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 F103C8T6学习笔记4:时钟树、滴答计时器、定时器定时中断 的相关文章

随机推荐

  • 自学STM32---GPIO

    1 STM32有5组GPIO引脚 分别是GPIOA GPIOB GPIOC GPIOD GPIOE 每组GPIO有16个引脚 2 每个引脚都有4个位来配置其端口 可以配置出不同的输入 输出模式 表1配置IO口输出方式 配置模式 CNF1 C
  • linux连接交换机命令,linux服务器查看网卡连接的交换机IP和PORT

    cdpr命令 安装 yum y install cdpr 安装epel库 21 53 07 root localhost cdpr h cdpr Cisco Discovery Protocol Reporter Version 2 4 C
  • 常见分类模型:决策树、随机森林、GBDT、XGB

    涉及到的指标 信息熵 其中是一件事情发生的概率 发生的概率越大信息量越小 对于2个独立事件 发生概率是 二者的信息量是 因为 具有可加性的性质 因此一般用来衡量某件事的信息量 负号是因为信息量与概率成反比 信息量度量的是一个具体事件发生了所
  • mysql断线重连_Yii2实现Mysql断线重连

    缘由 大家都知道我们做一个客服系统 是基于websocket长连接服务的 在这些长连接服务进程中 会对数据库有些操作 建议尽量在这些长连接服务中 少查询数据 能用缓存都用缓存 我们都知道数据库服务保持连接是有时间限制的 过了时间在操作数据库
  • cxf的web service服务,包含client端、service端

    1 下载需要的客户端 服务端Jar 客户端jar包链接 https github com zhangliqingyun jarlist tree master webserviceclient 服务端jar包链接 https github
  • MySQL 存储过程查询远程数据库的方法

    这几天有个任务 需要在存储过程中读取远程数据库一个表的数据存到本地表 然后进行计算 在网上查找了资料 Oracle和SQL Server查询远程数据库是比较方便的 MySQL麻烦一些 需要在本地建立一个需要查询的远程的表结构完全一样的表 并
  • Java单链表中的元素互换位置_java实现单链表及倒置单链表中的元素

    单链表的结构比较简单 图示如下 单链表有很多个节点构成 每个节点由指针域和数值域构成 指针指向下一个节点的数值域 最后一个节点的指针指向的是NULL java实现单链表的一些基本的操作 package test import javax x
  • RabbitMQ系列(二)VirtualHost作用及角色权限管理实战

    VirtualHost 作用及用法 Virtual Hosts的使用场景 多租户的使用场景 比如主机资源紧缺情况下开发和测试共用一个RabbitMQ 可以使用Virtual Hosts将开发和测试隔离开 1 管理界面 2 VirtualHo
  • rust学习网站

    https photino gitbooks io rust notes content programming paradigms html rutst学习网站 https kaisery gitbooks io rust book ch
  • 线性表定义--线性表的顺序存储结构+链式存储结构+循环链表+双向链表

    线性表 一 线性表定义 1 线性表的定义 通过一个例子来体验什么是线性表的定义 小朋友出游排队 谁在谁的前面 谁在谁的后面 保证不会有人丢失 定义 线性表 List 零个或多个数据元素的有限序列 注意 1 线性表是一个序列 也就是说 线性表
  • 【自然语言处理】关系抽取 —— SimpleRE 讲解

    SimpleRE 论文信息 标题 An Embarrassingly Simple Model for Dialogue Relation Extraction 作者 Fuzhao Xue 期刊 ICASSP 2022 发布时间与更新时间
  • 【Ubuntu】安装免费版Typora

    下载deb包 wget https file babudiu com f yXCL Typora Linux 0 11 18 amd64 deb 安装 sudo dpkg i Typora Linux 0 11 18 amd64 deb 参
  • 【蓝桥杯题解】特殊日期(判断合法日期模板)

    对于一个日期 我们可以计算出年份的各个数位上的数字之和 也可以分别计算月和日的各位数字之和 请问从 19001900 年 11 月 11 日至 99999999 年 1212 月 3131 日 总共有多少天 年份的数位数字之和等于月的数位数
  • centos 卸载程序

    1 查询软件列表 rpm qa grep 软件名 2 卸载软件 sudo yum remove 软件名
  • SQLite安装配置详细教程2023版

    前言 SQLite 是一款轻型的数据库 是遵守ACID的关系型数据库管理系统 它的设计目标是嵌入式的 而且已经在很多嵌入式产品中使用了它 它占用资源非常的低 它能够支持Windows Linux Unix等等主流的操作系统 同时能够跟很多程
  • 利用强化学习进行股票操作实战(三)

    与上一篇文章相同之处 对于交易策略 与上一篇文章相同 当发出买入指令时 一次性全部买入 当发出卖出指令时 一次性全部卖出 还没有添加加减仓操作 模型仍然用的是DQN模型 新增内容 在之前的基础上加入了交易手续费 印花税等 在强化学习这个领域
  • 基于FPGA驱动VGA显示图片的小问题

    学习VGA显示图片的过程中 遇到了一个小问题 我在显示屏上开了一个60x60的框 放了一张图片进去显示 但是最终的结果如下图所示 出现了一个竖黑边 看了看代码 分析了一下逻辑没问题 然而看这个显示那肯定是有问题的 然后仿真了一下看看 时序图
  • 在Vue2和Vue3中事件总线的使用与区别

    前提 在Vue升级到3 0版本后 事件总线使用的方式有些许改变 Vue2可以直接使用new Vue 在Vue3中 推荐使用mitt来帮助我们实现全局事件总线和局部事件总线 接下来让我们来对比2和3版本的使用和区别 Mitt是一个微型的 Ev
  • 可靠传输的运输层协议及编程实现

    在计算机网络中 运输层协议负责在通信实体之间提供可靠的数据传输 可靠传输意味着数据的发送方可以确保数据在传输过程中不会丢失 损坏 重复或无序到达接收方 本文将介绍一种常用的可靠传输协议 停等协议 并提供其简单的编程实现 停等协议 Stop
  • STM32 F103C8T6学习笔记4:时钟树、滴答计时器、定时器定时中断

    今日理解一下STM32F103 C8T6的时钟与时钟系统 滴答计时器 定时器计时中断的配置 文章提供原理 代码 测试工程下载 目录 时钟树与时钟系统 滴答计时器 定时器计时中断 测试结果 测试工程下载 时钟树与时钟系统 该系统介绍在 STM