当前位置:网站首页>STM32__03—初识定时器
STM32__03—初识定时器
2022-04-23 16:41:00 【c语言的神】
一,TIM简介
TIM的本质就是计数器,对输入的时钟进行计数,基准时钟为主频72MHZ,不分频时每秒可以产生72M个脉冲。TIM分高级,通用,基础定时器,我使用的是f102c8t6只有TIM1~TIM4四个定时器,其中TIM1为高级定时器,其他为通用定时器,本次主要围绕通用定时器。
1,通用定时器内部结构
左侧为时钟输入,这次我们主要了解TIMx_ETR外部时钟与内部时钟TIMxCLK,TIMx_CH1,为输入捕获,本次不涉及。
上面结构过于复杂这里引用B站江科大做的一张图
对于这张图,我们只需要从左到右对定时器进行初始就可以
2,初始化定时器
1)首先要启用内部时钟。开启TIM2(本次使用的为TIM)时钟,使用内部时钟模式。
使用的函数有:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
基础与通用定时器都连接在APB1总线,高级定时器连接在APB2总线。
TIM_InternalClockConfig(TIM2);
使用内部时钟,就算没有调用这个函数系统默认使用内部时钟。
2)时基单元的配置,与配置GPIO相似,都是对结构体变量进行配置
TIM_TimeBaseInitTypeDef TIM_TimerBaseStructure;
定义结构体变量名
TIM_TimerBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
时钟分频,这里不使用。
TIM_TimerBaseStructure.TIM_CounterMode=TIM_CounterMode_Up ;
计数器模式,这里选择常规的向上计数
TIM_TimerBaseStructure.TIM_Period=10000-1;
对ARR自动重装器进行配置
TIM_TimerBaseStructure.TIM_Prescaler=7200-1;
对PSC预分频器进行配置
注意:这里使用我们这里使用了定时一秒的操作,可以参考公式
-1是为了消除误差,我们可以这么理解,内部时钟的频率为72MHZ,先用预分频器分成7200份,这样每份就是10000HZ,然后我们用一个容量为10000的计数器去计算脉冲,10000HZ为一秒产生10000个脉冲,这样一秒之后就把计数器装满,产生溢出。
TIM_TimerBaseStructure.TIM_RepetitionCounter=0;
重复计数器,高级定时器才有,我们这里置0。
TIM_TimeBaseInit(TIM2,&TIM_TimerBaseStructure);
调用初始化函数,完成对时基单元的配置
3)中断使能
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
这个函数为清除中断标志位,为什么多了这一步呢?我们可以看一下TIM_TimeBaseInit()的定义
立即生成更新事件以重新加载预分器和重复计数器值,可以理解为,在初始化时基单元后会立即生成更新事件,导致中断标志位置1,复位完就立即进入中断函数,会导致程序提前一步运行,所以初始化完时基单元不要忘了这一步。
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
更新中断到NVIC
4)NVIC的配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
结构体变量命名
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn ;
定时器TIM2在NCIV的中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
通道使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
优先级
NVIC_Init(&NVIC_InitStructure);
NVIC初始化函数
TIM_Cmd(TIM2,ENABLE);
启用或禁用指定的TIM外设
5)中断服务函数的调用
void TIM2_IRQHandler();
一个完整的定时器初始化完成。
二,代码部分
1,Timer.c
#include "stm32f10x.h" // Device header
void Timer_Init()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启TIM2时钟,注意是APB1Z总线
TIM_InternalClockConfig(TIM2);//上电后默认使用内部时钟,但是为了程序的完整性,还是调用了这个函数
//时基单元的初始化
TIM_TimeBaseInitTypeDef TIM_TimerBaseStructure;
TIM_TimerBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//时钟分频,滤波使用
TIM_TimerBaseStructure.TIM_CounterMode=TIM_CounterMode_Up ;//向上计数
TIM_TimerBaseStructure.TIM_Period=10000-1;//ARR自动重装器的值
TIM_TimerBaseStructure.TIM_Prescaler=7200-1;//PSC预分频率的值
//这里可以理解为给72MHZ的信号分7200份,每一份就是10000hz,然后用一个容量为10000的容器
//去装,每装满一次为1S
TIM_TimerBaseStructure.TIM_RepetitionCounter=0;//重复计数器,高级定时器才有
TIM_TimeBaseInit(TIM2,&TIM_TimerBaseStructure);
//使能中断
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//更新中断到NVIC
//NVIC配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn ;//定时器TIM2在NCIV的中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//优先级
NVIC_Init(&NVIC_InitStructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
//中断服务函数
//void TIM2_IRQHandler()
//{
// if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
// {
// TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
// }
//}
2,oled.c
#include "stm32f10x.h" // Device header
void LED_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
}
void LED1_ON()
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
void LED1_OFF()
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
void LED1_Turn()
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
}
void LED2_Turn()
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)==0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
}
void LED2_ON()
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
void LED2_OFF()
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
3,main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Buzzer.h"
#include "OLED.h "
#include "Timer.h"
uint16_t Num;
int main()
{
OLED_Init();
Timer_Init();
OLED_ShowString(1,1,"Num:");
while(1)
{
OLED_ShowNum(1,5,Num,5);
OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);
}
}
void TIM2_IRQHandler()
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
实现Num每秒加1,并在屏幕显示。
三,总结
stm32的定时器花了很长时间才搞懂。万事开头难,但是不知道会这么难。
版权声明
本文为[c语言的神]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_58931449/article/details/124360344
边栏推荐
- File upload and download of robot framework
- Loading order of logback configuration file
- Postman batch production body information (realize batch modification of data)
- Modify the test case name generated by DDT
- 聊一聊浏览器缓存控制
- Kunteng full duplex digital wireless transceiver chip kt1605 / kt1606 / kt1607 / kt1608 is suitable for interphone scheme
- Report FCRA test question set and answers (11 wrong questions)
- Pseudo Distributed installation spark
- There is a problem with the light switch from 1 to 100
- NVIDIA graphics card driver error
猜你喜欢
Oak-d raspberry pie cloud project [with detailed code]
磁盘管理与文件系统
Nacos 详解,有点东西
Hyperbdr cloud disaster recovery v3 Version 2.1 release supports more cloud platforms and adds monitoring and alarm functions
各大框架都在使用的Unsafe类,到底有多神奇?
Deepinv20 installation MariaDB
How magical is the unsafe class used by all major frameworks?
loggie 源码分析 source file 模块主干分析
Force buckle - 198 raid homes and plunder houses
Installation and management procedures
随机推荐
Detailed explanation of gzip and gunzip decompression parameters
Day 9 static abstract class interface
Findstr is not an internal or external command workaround
Dlib of face recognition framework
Gartner 发布新兴技术研究:深入洞悉元宇宙
Creation of RAID disk array and RAID5
299. Number guessing game
There is a problem with the light switch from 1 to 100
Change the icon size of PLSQL toolbar
logback的配置文件加载顺序
How does flash cache data in memory?
众昂矿业:萤石浮选工艺
loggie 源码分析 source file 模块主干分析
Zhongang Mining: Fluorite Flotation Process
计组 | 【七 输入/输出系统】知识点与例题
G008-HWY-CC-ESTOR-04 华为 Dorado V6 存储仿真器配置
浅谈 NFT项目的价值、破发、收割之争
最詳細的背包問題!!!
Questions about disaster recovery? Click here
Public variables of robotframework