【STM32】定时器

systick定时器:

【STM32】Systick定时器-CSDN博客

0.通用定时器框图

1.时钟源

2.控制器

3.输入捕获

计数器实际上是与比较寄存器的影子寄存器进行比较的。

4.输出比较

1.STM32的定时器学习要点

参考手册

STM32F1xx中文参考手册.pdf · 林何/STM32F103C8 - 码云 - 开源中国 (gitee.com)

1.通用定时器和其他的区别

1)其实最多可以有17个定时器

2)功能差别

2.STM32定时器的学习要点

1)先学会定时器基本概念的使用

2)高级功能用到到时再去细看

3)设计本身的复杂性导致学习难度大,要有耐心

4)很多书面概念要搞清楚,需要不断前后对照

5)学习三宝:数据手册+外设库源码+例程

2.通用定时器的数据手册

进行比较计数器和寄存器的值进行电平的反转。

1.TIMx主要功能

定时器是基于计数器进行的,分频,然后走一格就计数一次。

1.向上/向下

向上:加法计数器【从x不断++到65535】

向下:减法计数器【从x不断--到0】

2.TIM的所属APB

3.发生的中断/DMA

2.通用定时器框图

3.预分频器

1.时基单元

1)可以在运行的时候对预分频器的值进行修改

我们这里可以在运行时对其进行修改的是count计数器(可以在当前事件执行时进行更新,也可以等到下一次更新事件发生后在进行改变)

预分频器(预分频器的值只能在下一次更新事件到来时被采用。)

2)影子寄存器【预装载寄存器】:在硬件上实际上是存在的,但是没有给他分配地址(不需要程序进行干预)

1.1 TIMx_CR1_ARPE:修改位

1.2 TIMx_CR1_UDIS:中断允许位

1.3 TIMx_CR1_CEN:时钟和计数器的使能

注意点:

真正的计时器使能信号CNR_EN是在CEN的一个时钟周期后被设置(表示计数器是在一个周期后才开始计时)

2.预分频器描述

预分频器可以在工作时被改 变。但是新的预分频器参数只能在下一次更新事件到来时被采用。【因为预分频器中带有缓冲器】

2.1 计数器的时序图:1分频--2分频

2.2 计数器的时序图:1分频--4分频

4.计数器

1.向上计数器模式

1.与51单片机不同

2.基本概念

3.是否产生更新事件

4.计数器时序图

5.ARPE=0时的更新事件【立即模式-不缓存】

6.ARPE=1时的更新事件【下一周期改变--缓存】

2.向下计数模式

注意点:

向下计数模式没有【立即模式】,因为如果原来ff,然后现在走到05,然后修改为36,不可能重新回36在继续减,这是不合理的。

3.中央对齐模式(向上/向下计数)

在中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)−1,产生一个计数器 溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。

1.注意点

1)在这个模式,不能写入TIMx_CR1中的DIR方向位。它由硬件更新并指示当前的计数方向。

2)注意加减的边界值问题:

        加法计数器是寄存器值-1

        减法计数器是减到1

2.计数器时序图

3.ARPE=1时的更新事件【下一周期更新--缓存】

5.时钟选择

1.内部时钟(CK_INT)--常规模式

1.使能

通过设置TIMx_SMCR寄存器的SMS=000,表示使用内部时钟【常规模式】。

2.外部时钟模式1:外部输入脚(TIx)

3.外部时钟模式2:外部触发输入(ETR)

4.内部触发输入(ITRx):一个定时器的输出作为另外一个定时器的输入

6.库函数

1.TIM_TimeBaseInit

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
{uint16_t tmpcr1 = 0;/* Check the parameters */assert_param(IS_TIM_ALL_PERIPH(TIMx)); assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));tmpcr1 = TIMx->CR1;  if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||(TIMx == TIM4) || (TIMx == TIM5)) {/* Select the Counter Mode */tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;}if((TIMx != TIM6) && (TIMx != TIM7)){/* Set the clock division */tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;}TIMx->CR1 = tmpcr1;/* Set the Autoreload value *///要计数的值TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;/* Set the Prescaler value *///预分频参数TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))  {/* Set the Repetition Counter value */TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;}/* Generate an update event to reload the Prescaler and the Repetition countervalues immediately *///预分频器参数的改变TIMx->EGR = TIM_PSCReloadMode_Immediate;           
}

2.TIM_ITConfig

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
{  /* Check the parameters */assert_param(IS_TIM_ALL_PERIPH(TIMx));assert_param(IS_TIM_IT(TIM_IT));assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE){/* Enable the Interrupt sources */TIMx->DIER |= TIM_IT;}else{/* Disable the Interrupt sources */TIMx->DIER &= (uint16_t)~TIM_IT;}
}

7.定时器例程分析和编程实践

1.RCC_Configuration

TIM2接APB1,GPIOB接APB2

2.GPIO_Configuration

配置的是GPIOB

3.NVIC_Configuartion

void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;#ifdef  VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endifNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the TIM1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

 4.TIM2_IRQHandler

5.时钟编写

8.代码移植

1.先写定时器

如果不知道定时器的名字是什么可以去“startup_stm32f10x_hd.s”查看

再去“stm32f10x_it.c”中填写

2.RCC_Configuration

注意点:

TIM2和GPIOB所对应的APB对应不一样,所以一定要分开声明,要不然会出现错误。

TIM2---》APB2

GPIOB--》APB1

void RCC_Configuration(void)
{//打开时钟//注意点://TIM2和GPIOB的APB不一样,所以只能分开声明,要不然不起效果
//	RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB2Periph_GPIOB, ENABLE);	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}

3.GPIO_Configuration

void GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* GPIOA Configuration: */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_WriteBit(GPIOB, GPIO_Pin_8, Bit_RESET); 
}

4.NVIC_Configuration

void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;#ifdef  VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endifNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the TIM1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

5.APB的分频问题

TIM2接APB1,GPIOB接APB2

我们APB1不能超过36MHZ,所以要对72MHZ进行分频

		//72MHZ定时器的定义// 主频是72MHz,HCLK是72M,PCLK2是72M,PCLK1是36M// TIM2接在PCLK1下(APB1)所以源是36M,CK_CNT是36M/7200=5KHzTIM_TimeBaseStructure.TIM_Prescaler = 7199;//例如:时钟频率=72/(时钟预分频+1)TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;// 计数个数是10000,所以计数时间是10000*1/5000=2sTIM_TimeBaseStructure.TIM_Period = 9999;//自动重装载寄存器周期的值(定时时间)累计//0xffff 个频后产生个更新或者中断(也就是说定时时间到)

6.完整代码

main

#include "stm32f10x.h"                  // Device header
/**根据定时器2来实现数码管每隔1秒闪烁一次
*/void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);int main(){//设置TIM2定时器TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_Configuration();  //系统时钟配置NVIC_Configuration();	 //NVIC配置GPIO_Configuration();	 //通用IO端口配置//72MHZ定时器的定义// 主频是72MHz,HCLK是72M,PCLK2是72M,PCLK1是36M// TIM2接在PCLK1下(APB1)所以源是36M,CK_CNT是36M/7200=5KHzTIM_TimeBaseStructure.TIM_Prescaler = 7199;//例如:时钟频率=72/(时钟预分频+1)TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;// 计数个数是10000,所以计数时间是10000*1/5000=2s//注意点:我们计算出来的值是5,但是我们实际上是从0开始,所以我们这里要-1TIM_TimeBaseStructure.TIM_Period = 4;//自动重装载寄存器周期的值(定时时间)累计//0xffff 个频后产生个更新或者中断(也就是说定时时间到)TIM_TimeBaseStructure.TIM_ClockDivision = 0;//初始化定时器2TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//打开中断,溢出中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //定时器打开TIM_Cmd(TIM2, ENABLE); while (1);//进入中断return 0;
}void RCC_Configuration(void)
{//打开时钟//注意点://TIM2和GPIOB的APB不一样,所以只能分开声明,要不然不起效果
//	RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB2Periph_GPIOB, ENABLE);	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}void GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* GPIOA Configuration: */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //使亮数码管GPIO_WriteBit(GPIOB, GPIO_Pin_8, Bit_SET); 
}void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;#ifdef  VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endifNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the TIM1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

stm32f10x_it.c

void TIM2_IRQHandler(void){if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)  //检测制定的中断是否发生{TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除中断处理位。//LED的取反GPIO_WriteBit(GPIOB, GPIO_Pin_8, !GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8));}  
}

9.问题解决:APB频率计算问题

cnt的计数公式 

cnt=1s*频率值(HZ)

例如:

此时TIM2一定是分完频,结果为36MHZ

初始化:TIM_TimeBaseStructure.TIM_Prescaler = 7199;--》【最后要+1】

CK_CNT=36M/72 00=5KHZ

实际测试得到的是1KHZ的结果,说明前面分析有误

初始化:计数个数为1 0000个

所以:计数时间为:1 0000*1/5000=2s

结论:APB1时钟确实是36MHZ,但是APB1到定时器时钟那边中间被乘以2,所以又变成72MHZ了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/136809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring的循环依赖问题

文章目录 1.什么是循环依赖2.代码演示3.分析问题4.问题解决5.Spring循环依赖6. 疑问点6.1 为什么需要三级缓存6.2 没有三级缓存能解决吗?6.3 三级缓存分别什么作用 1.什么是循环依赖 上图是循环依赖的三种情况,虽然方式有点不一样,但是循环依…

合成数据在金融服务中的应用

人工智能在金融服务中有着广泛的应用,从流程自动化到聊天机器人和欺诈检测。据估计,到 447 年,银行从人工智能应用中节省的潜在成本总额将达到 2023 亿美元。 但是,其中一些应用程序有其局限性,因为财务数据是最敏感和…

排序算法的空间复杂度和时间复杂度

一、排序算法的时间复杂度和空间复杂度 排序算法 平均时间复杂度 最坏时间复杂度 最好时间复杂度 空间复杂度 稳定性 冒泡排序 O(n) O(n) O(n) O(1) 稳定 直接选择排序 O(n) O(n) O(n) O(1) 不稳定 直接插入排序 O(n) O(n) O(n) O(1) 稳定 快速排序 O(n…

nacos做服务配置和服务器发现

一、创建项目 1、创建一个spring-boot的项目 2、创建三个模块file、system、gateway模块 3、file和system分别配置启动信息,并且创建一个简单的控制器 server.port9000 spring.application.namefile server.servlet.context-path/file4、在根目录下引入依赖 <properties&g…

docker部署es+kibana

es 暴露的端口特别多 &#xff0c;十分耗内存&#xff0c;数据一般要放置到安全目录&#xff0c;挂载 官网推荐的命令&#xff1a;docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" elasticsearch…

高能数造电池3D打印智能制造小试线,开启全固态电池数字化新时代

在科技创新的浪潮中&#xff0c;电池制造领域又迎来了一次突破性的进展。近日&#xff0c;高能数造(西安)技术有限公司重磅推出了其最新电池数字制造装备——全固态电池3D打印智能制造小试线 &#xff0c;这一创新性的技术开启了全固态电池的数字化智造新时代&#xff0c;为全固…

如何在时间循环里最优决策——时间旅行者的最优决策

文章目录 每日一句正能量前言时间旅行和平行宇宙强化学习策略梯度算法代码案例推荐阅读赠书活动 每日一句正能量 做一个决定&#xff0c;并不难&#xff0c;难的是付诸行动&#xff0c;并且坚持到底。 前言 时间循环是一类热门的影视题材&#xff0c;其设定常常如下&#xff1…

Pycharm加载项目时异常,看不到自己的项目文件

最近看到一个朋友问&#xff0c;他把项目导入pycharm为什么项目里的包不在项目里显示&#xff0c;只在projects file里显示&#xff1f;问题截图如下&#xff1a; Project里看不到自己的项目文件 只能在Project Files里看到自己的项目文件 问题解答 我也是偶然发现的这个方案…

jQuery中显示与隐藏

在我们jQuery当中&#xff0c;有多个显示隐藏的方法&#xff0c;本篇介绍一下hide()、show()、toggle() 在我们JS当中&#xff0c;或是CSS当中&#xff0c;我们常用到display:none或block; 在我们jQuery当中&#xff0c;我们该如何实现显示隐藏 在我们jQuery当中&#xff0c;我…

Linux CentOS 8(HTTPS的配置与管理)

Linux CentOS 8&#xff08;HTTPS的配置与管理&#xff09; 目录 一、HTTPS 介绍二、SSL 证书的介绍三、实验配置 一、HTTPS 介绍 HTTPS 在 HTTP 的基础下加入 SSL&#xff0c;SSL 是“Secure Sockets Layer”的缩写&#xff0c;中文为“安全套接层”。因此 HTTPS 是以安全为目…

【Unity ShaderGraph】| 物体靠近时局部溶解,根据坐标控制溶解的位置【文末送书】

前言 【Unity ShaderGraph】| 物体靠近时局部溶解&#xff0c;根据坐标控制溶解的位置一、效果展示二、根据坐标控制溶解的位置&#xff0c;物体靠近局部溶解三、应用实例&#x1f451;评论区抽奖送书 前言 本文将使用ShaderGraph制作一个根据坐标控制溶解的位置&#xff0c;物…

如何用Java实现一个基于机器学习的情感分析系统,用于分析文本中的情感倾向

背景&#xff1a;练习两年半&#xff08;其实是两周半&#xff09;&#xff0c;利用工作闲余时间入门一下机器学习&#xff0c;本文没有完整的可实施的案例&#xff0c;由于知识体系不全面&#xff0c;目前代码只能运行&#xff0c;不能准确的预测 卡点&#xff1a; 1 由于过…

技术分享 | app自动化测试(Android)--触屏操作自动化

导入TouchAction Python 版本 from appium.webdriver.common.touch_action import TouchActionJava 版本 import io.appium.java_client.TouchAction;常用的手势操作 press 按下 TouchAction 提供的常用的手势操作有如下操作&#xff1a; press 按下 release 释放 move_…

CentOS Linux 系统镜像

CentOS Linux具有以下特点&#xff1a; 稳定性&#xff1a;CentOS Linux旨在提供一个稳定、可靠的服务器环境&#xff0c;适合用于关键业务应用和生产环境。高效性&#xff1a;CentOS Linux经过优化和调整&#xff0c;可以充分发挥硬件的性能&#xff0c;提高系统的整体效率。…

Rust和isahc库编写代码示例

Rust和isahc库编写的图像爬虫程序的代码&#xff1a; rust use isahc::{Client, Response}; fn main() { let client Client::new() .with_proxy("") .finish(); let url ""; let response client.get(url) .send() …

无线测温系统在电厂的必要性,保障电力系统稳定运行

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;采集关键电力设备接电的实时温度&#xff0c;克服有线温度监测系统存在的诸如线路多&#xff0c;布线复杂&#xff0c;维护困难等不足&#xff0c;将无线无源传感器与Zigbee无线通信技术相结合&#xff0c;将物联网技…

关于VUE启动内存溢出

安装node v10.14.2 后 启动公司的VUE项目 使用命令npm run dev 命令 报错&#xff1a; <--- Last few GCs --->[20940:00000244699848E0] 215872 ms: Scavenge 1690.2 (1836.4) -> 1679.6 (1836.4) MB, 5.4 / 0.7 ms (average mu 0.266, current mu 0.253) a…

jQuery中淡入与淡出

在我们jQuery中为我们封装了很多好玩的方法&#xff0c;我为大家介绍一下淡入与淡出&#xff01; 我们需要配合事件来玩淡入淡出 淡出语法&#xff1a;fadeOut([speed,[easing],[fn]) (1)参数都可以省略 (2)speed:三种预定速度之一的字符串(“slow”“normal”or “fast”)或…

阿里云 :推出通义大模型编码助手产品【通义灵码】

本心、输入输出、结果 文章目录 阿里云 &#xff1a;推出通义大模型编码助手产品【通义灵码】前言通义灵码简介主要功能主要功能点 支持的语言和 IDEjetbrains IDEA 安装计费相关弘扬爱国精神 阿里云 &#xff1a;推出通义大模型编码助手产品【通义灵码】 编辑&#xff1a;简简…

ARMday2(环境创建+工程配置+创建文件+单步调试)

目录 一、汇编环境的创建 二、为工程配置链接脚本&#xff08;map.lds&#xff09; 三、为工程创建汇编文件 start.s 编程调试 接下来我们需要建立一个 start.s 汇编文件添加到我们的工程中去 四、对汇编代码进行单步调试&#xff08;仿真&#xff09; 五、汇编工程的编译 …