STM32TIM时钟(1)

2024-02-05 09:36
文章标签 时钟 stm32tim

本文主要是介绍STM32TIM时钟(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、介绍部分
    • TIM简介
    • 了解定时器类型
      • 基本定时器框图
      • 通用定时器框图
      • 高级定时器框图
      • 定时器级联关系
    • 所需简化定时器中断流程图
    • 时序部分
      • 预分频器时序
      • 计数器时序
        • 无影子寄存器计数器时序
        • 有影子寄存器计数器时序
    • 时钟树
  • 二、实例部分
    • 使用定时器计数
    • 使用对射红外传感器来控制计数器
      • 电路连接
      • 代码部分
  • 总结
    • 所使用函数总结
    • NVIC分组与优先级分配的关系


前言

简介STM32的时钟,主要连接通用定时器的用法,了解定时器中断的原理,以及如何基础的利用定时器中断


一、介绍部分

TIM简介

在这里插入图片描述

了解定时器类型

注意定时器的编号以及所在总线

在这里插入图片描述

基本定时器框图

计数器加到阈值选择中断会进入NVIC(即框图的向上的箭头),称更新中断,向下的箭头表示产生一个新的事件,触发内部其他电路工作,而不是进入中断,称更新事件。

在这里插入图片描述
主模式触发DAC:即通过更新时间,映射到TRGO,这样就可以不需要频繁中断来输出波形

通用定时器框图

在这里插入图片描述
基本定时器计数器只有向上计数
通用和高级定时器计数器有三种方法如下图:
在这里插入图片描述

高级定时器框图

在这里插入图片描述

定时器级联关系

在这里插入图片描述

所需简化定时器中断流程图

在这里插入图片描述

时序部分

预分频器时序

在这里插入图片描述

计数器时序

在这里插入图片描述

无影子寄存器计数器时序

在这里插入图片描述

有影子寄存器计数器时序

在这里插入图片描述

时钟树

在这里插入图片描述

二、实例部分

使用定时器计数

硬件电路只需连接STM32最小电路与OLED即可
封装定时器初始化函数Timer.c内容如下:

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void){// 初始化时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);// 使用内部时钟(默认)TIM_InternalClockConfig(TIM2);// 配置事间基础(时基单元)TIM_TimeBaseInitTypeDef TIM_InitStructure;// 时钟分频TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 计算模式TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 重载值(有1的偏差)<计数值> 10000/10000=1TIM_InitStructure.TIM_Period = 10000-1;// 预分频(有1的偏差)<频率> 72000000/7200=10000TIM_InitStructure.TIM_Prescaler = 7200-1;// 重复计数器(不使用)TIM_InitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_InitStructure);// 由于时基初始化后会立即进入中断一次,提前清除以下标志位TIM_ClearFlag(TIM2,TIM_IT_Update);// 中断使能,更新中断到NVICTIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);// NVIC分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 初始化NVICNVIC_InitTypeDef NVIC_InitStructure;// 中断通道NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;// 中断通道使能NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// 抢占优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 响应优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStructure);// 启动定时器TIM_Cmd(TIM2,ENABLE);
}uint16_t Num;uint16_t GetNum(void){return Num;
}//中断函数
void TIM2_IRQHandler(void){// 获取中断标志位if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){Num++;// 清除标志位TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}

主函数逻辑main.c内容如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,"Num:");while (1){OLED_ShowNum(2,1,GetNum(),4);// 查看计数器的变化OLED_ShowNum(3,1,TIM_GetCounter(TIM2),4);}
}

使用对射红外传感器来控制计数器

红外传感器每产生10次上升沿即Num+1

电路连接

在这里插入图片描述

代码部分

封装定时器内容Timer.c

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void){// 初始化时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);// 红外传感器所在引脚GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);// 使用外部时钟模式2,不分频,中断方式,滤波/*@arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.@arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.*/// 使用红外传感器的上升沿作为计数器+1TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0f);// 配置事间基础(时基单元)TIM_TimeBaseInitTypeDef TIM_InitStructure;// 时钟分频TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 计算模式TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 重载值(有1的偏差)<计数值>TIM_InitStructure.TIM_Period = 9-1;// 预分频(有1的偏差)<频率>TIM_InitStructure.TIM_Prescaler = 1-1;// 重复计数器(不使用)TIM_InitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_InitStructure);// 由于时基初始化后会立即进入中断一次,提前清除以下标志位TIM_ClearFlag(TIM2,TIM_IT_Update);// 中断使能,更新中断到NVICTIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);// NVIC分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 初始化NVICNVIC_InitTypeDef NVIC_InitStructure;// 中断通道NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;// 中断通道使能NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;// 抢占优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 响应优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStructure);// 启动定时器TIM_Cmd(TIM2,ENABLE);
}uint16_t Num;uint16_t GetNum(void){return Num;
}//中断函数
void TIM2_IRQHandler(void){// 获取中断标志位if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){Num++;// 清除标志位TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}

主函数main.c内容:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,"Num:");OLED_ShowString(2,1,"CNT:");while (1){OLED_ShowNum(1,6,GetNum(),4);// 查看计数器的变化OLED_ShowNum(2,6,TIM_GetCounter(TIM2),4);}
}

总结

所使用函数总结

// 时钟初始化(时钟分频、计数模式、重载值、分频值、重复计数器值)
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
// 启动定时器
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
// 设置外部定时器模式2
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//  使中断更新到NVIC                          
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
// 获取定时器计数器的值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
// 获取定时中断标志位
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
// 清除标志位
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
// 获取定时中断标志位(适用于中断函数内)
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
// 清除标志位(适用于中断函数内)
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

NVIC分组与优先级分配的关系

在这里插入图片描述

这篇关于STM32TIM时钟(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/680494

相关文章

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

油表加速器时钟屏保 就是这么酷酷的

太酷了!这个时钟屏保太有个性了!油表加速器时钟屏保,模拟汽车加速表盘,非常有质感,用它做屏保,简直就是酷毙了~!今天小编给大家分享一个非常实用好看的时钟屏保(芝麻时钟),官网地址(https://clock.zhimasoft.cn/?bili) 芝麻时钟-油表加速器时钟屏保 我们一起来看下,油表加速器表盘时钟屏保是怎么设置的? 1、打开芝麻时钟软件,找到"时钟屏保"菜单,点击后打开;(

彩虹数字屏保时钟 芝麻时钟开启个性化的时代 屏保怎么能少它

彩虹数字屏保时钟 芝麻时钟开启个性化的时代 屏保怎么能少它?电脑屏保多样化,让大家有了更多的选择,让更多人有机会把自己的电脑打扮得漂漂亮亮,今天小编给大家推荐:芝麻时钟(官网下载地址:http://clock.zhimasoft.cn/?bili),一起看下怎么开启彩虹数字时钟屏保吧! 彩虹数字屏保时钟 1、先下载芝麻时钟到电脑,可以百度,或者微软应用商城搜索“芝麻时钟”下载;

STM32CubeMX 1 创建一个新工程 利用时钟点亮LED KEIL5 Jlink配置

直接上ST的官网下载STM32CubeMX安装 地址: 单片机:STM32F103C8T6 带外部8MHz晶振 目的:利用Timer和使LED按照1Hz的频率闪烁。 在此方面学霸级人物的指引下学习了,并写此文章记录,以防忘记。 新建工程 出现如下界面,中央就是这个封装的引脚图: 接下来开始配置 1. 设置外部晶振接口在PD0和PD1 单机想要配置的引脚,出现选择菜单。

Android AnalogClock TextClock DigitalClock Chronometer 时钟 定时器

AnalogClock 相关属性:  android:dial="@drawable/img1" //表盘android:hand_hour="@drawable/alert_dialog_icon" //时针android:hand_minute="@drawable/alert_dialog_icon" //分针 TextClock 相关属性: android:f

RP2040 C SDK clocks时钟源配置使用

RP2040 C SDK clocks时钟源配置使用 🌿RP2040时钟源API函数文档:https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_clocks 🍁RP2040时钟树: 系统时钟源可以来自外部时钟输入(external clocks)、 晶体振荡器(XOS

分布式系统理论基础三-时间、时钟和事件顺序

GitHub:https://github.com/wangzhiwubigdata/God-Of-BigData 关注公众号,内推,面试,资源下载,关注更多大数据技术~大数据成神之路~预计更新500+篇文章,已经更新50+篇~ 现实生活中时间是很重要的概念,时间可以记录事情发生的时刻、比较事情发生的先后顺序。分布式系统的一些场景也需要记录和比较不同

Linux学习笔记12---主频和时钟配置实验

本章学习 I.MX6U 的时钟系统,学习如何配置 I.MX6U 的 系统时钟和其他的外设时钟,使其工作频率为 528MHz ,其他的外设时钟源都工作在 NXP 推荐的频率。  1、MX6U 时钟系统详解          I.MX6U 的系统主频为 528MHz,有些型号可以跑到 696MHz,但是默认情况下内部 boot rom 会将 I.MX6U 的主

【Power Compiler手册】9.时钟门控(4修改时钟门控结构)

修改时钟门控结构 在执行 RTL 时钟门控时,可以指定 `set_clock_gating_style -max_fanout` 命令来限制由单个时钟门控元素门控的寄存器数量。结果可能是具有相同使能信号的多个时钟门控元素,并且在逻辑上,具有相同的门控时钟信号。所有具有相同使能信号的时钟门控单元属于同一个时钟门控组。由单个时钟门控元素门控的所有寄存器属于同一个时钟门控子组。 由 `compi