写点什么

【STM32】TIM--- 基本定时器

用户头像
AXYZdong
关注
发布于: 2021 年 02 月 16 日
【STM32】TIM---基本定时器

Author:AXYZdong

自动化专业 工科男

有一点思考,有一点想法,有一点理性!

定个小小目标,努力成为习惯!在最美的年华遇见更好的自己!

更多精彩文章前往:👉 个人主页



- 开发板:stm32f407VET6

- 开发环境:keil5 MDK

一、TIM 简介

定时器最基本功能:定时


  • 定时发送 USART 数据

  • 定时采集 AD 数据等


定时器与 GPIO 结合


  • 测量输入信号脉冲宽度

  • 产生输出波形 等


▲ 各个定时器的特性

二、基本定时器

基本定时器 :TIM6TIM7 ,基本功能完全一样,但所占资源彼此完全独立。


▲ 基本定时器的功能框图


  • 基本定时器时钟只能来自内部时钟

  • 基本定时器的内部时钟(CK_INT)频率为 84MHz

  • 基 本定时器还专门用于 DAC 转换触发

  • 只要设置 CK_PSCTIMx_ARR 这两个寄存器的值就可以控制事件生成的时间

三、定时器周期计算


  • Tout:溢出时间,即定时多长时间


  • TIMxCLK:定时器时钟频率

//定时器时钟源 TIMxCLK = 2 * PCLK1 25     //        PCLK1 = HCLK / 4 26     //        => TIMxCLK=HCLK/2=SystemCoreClock/2=84MHz 
复制代码


  • ARR:定时器周期,初始化结构体时用 TIM_Period 表示

  uint32_t TIM_Period;            /*!< Specifies the period value to be loaded into the active                                       Auto-Reload Register at the next update event.                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 
复制代码


  • PSC:预分频大小,初始化结构体时用 TIM_Prescaler 表示

  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.                                       This parameter can be a number between 0x0000 and 0xFFFF */
复制代码


比如我们需要一个 1s 周期的定时器,具体这两个寄存器值该如何设置。


假设,我们先设置 TIMxARR 寄存器值为 9999 ,即当 TIMxCNT 从 0 开始计算,刚好等于 9999 时生成事件,总共计数 10000 次,那么如果此时时钟源周期 为 100us 即可得到刚好 1s 的定时周期。


接下来问题就是设置 TIMxPSC 寄存器值使得 CKCNT 输出为 100us 周期 (10000Hz) 的时钟。预分频器的输入时钟 CK_PSC 为 84MHz,所以设置预分频器值为 (8400-1) 即可满 足。

四、初始化结构体

typedef struct{  //预分频器  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.                                       This parameter can be a number between 0x0000 and 0xFFFF */  //计数模式  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.                                       This parameter can be a value of @ref TIM_Counter_Mode */  //定时器周期  uint32_t TIM_Period;            /*!< Specifies the period value to be loaded into the active                                       Auto-Reload Register at the next update event.                                       This parameter must be a number between 0x0000 and 0xFFFF.  */   //时钟分频  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */  //重复计算器  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter                                       reaches zero, an update event is generated and counting restarts                                       from the RCR value (N).                                       This means in PWM mode that (N+1) corresponds to:                                          - the number of PWM periods in edge-aligned mode                                          - the number of half PWM period in center-aligned mode                                       This parameter must be a number between 0x00 and 0xFF.                                        @note This parameter is valid only for TIM1 and TIM8. */} TIM_TimeBaseInitTypeDef; 
复制代码

五、基本定时器实验

基本定时器循环定时 1s ,并使能定时器中断,每隔 1s 在定时器中断服务函数使 LED 状态翻转。


编程思路

  • 初始化 LED

  • 开启定时器时钟

  • 设置定时器周期和预分频器

  • 启动定时器中断,开启定时器

  • 中断服务函数翻转 LED

time.h

// =============================================# @Time    : 2021-02-16# @Author  : AXYZdong# @InfoQ   : https://www.infoq.cn/profile/95CAD506550AB9/publish# @FileName: time.h# @Software: keil5 MDK// =============================================
#ifndef _TIME_H#define _TIME_H
#include "stm32f4xx.h"
//宏定义#define BASIC_TIM TIM6#define BASIC_TIM_CLK RCC_APB1Periph_TIM6
#define BASIC_TIM_IRQn TIM6_DAC_IRQn#define BASIC_TIM_IRQHandler TIM6_DAC_IRQHandler
void TIM_Config(uint16_t ARR , uint16_t PSC);
#endif
复制代码

time.c

// =============================================# @Time    : 2021-02-16# @Author  : AXYZdong# @InfoQ   : https://www.infoq.cn/profile/95CAD506550AB9/publish# @FileName: time.c# @Software: keil5 MDK// =============================================
#include "time.h"#include "bsp_led.h"
extern void TIM_Config(uint16_t ARR , uint16_t PSC);
void TIM_Config(uint16_t ARR , uint16_t PSC){ NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQn;//定时器中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 /* *注意:TIM_TimeBaseInitTypeDef 结构体里面有 5 个成员,TIM6 和 TIM7 的寄存器里面只有 *TIM_Prescaler 和 TIM_Period,所以使用 TIM6 和 TIM7 的时候只需初始化这两个成员即可, * 另外三个成员是通用定时器和高级定时器才有. *----------------------------------------------------------------------- * TIM_Prescaler 都有 * TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_Period 都有 * TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器) *----------------------------------------------------------------------- */ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(BASIC_TIM_CLK, ENABLE); //开启 TIMx_CLK
TIM_TimeBaseInitStruct.TIM_Period = ARR; //累计 TIM_Period 个后产生一个更新或者中断TIM_TimeBaseInitStruct.TIM_Prescaler = PSC; //设定定时器频率
TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseInitStruct); //初始化定时器 TIMx
TIM_ITConfig(BASIC_TIM, TIM_IT_Update, ENABLE); //开启定时器更新中断 TIM_Cmd(BASIC_TIM, ENABLE); //使能定时器
}
void BASIC_TIM_IRQHandler(){ if(TIM_GetITStatus(BASIC_TIM , TIM_IT_Update) == SET) { LED0 = ~ LED0; TIM_ClearITPendingBit(BASIC_TIM , TIM_IT_Update); }}
复制代码

main.c

// =============================================# @Time    :2021-02-16# @Author  : AXYZdong# @InfoQ   : https://www.infoq.cn/profile/95CAD506550AB9/publish# @FileName: main.c# @Software: keil5 MDK// =============================================
#include "stm32f4xx.h"#include "time.h"#include "bsp_led.h"
int main(void){ LED_GPIO_Config(); //初始化LED TIM_Config(9999,8399); //初始化定时器 while(1) { }}
复制代码

六、总结

  • 宏定义的使用可以便于代码移植

  • LED 状态翻转使用了 位带 操作

  • 软件设置的定时时间和 LED 闪烁时间不太一致,不清楚哪个地方出问题了?有知道的小伙伴可以 👇 下方留言告诉我哦


【参考文献】


[1] 《零死角玩转 STM32—基于野火 F407[霸天虎]开发板 》


猜你喜欢:

【STM32】点亮 LED

【STM32】GPIO 输入—按键检测

【STM32】0.96 寸 OLED 显示屏(7 针 SPI 协议)软件模拟 SPI

【STM32】1.44 寸 TFT 液晶屏显示字符、汉字和图片

【STM32】stm32f407 + DS18B20 碰出不一样的火花

【STM32】5 分钟了解 STM32 的串口通信

【STM32】串口通信出现乱码(使用官方标准库)

【STM32】串口通信 --- 用代码与芯片对话


本次的分享就到这里


好书不厌百回读,熟读自知其中意。将学习成为习惯,用知识改变命运,用博客见证成长,用行动证明努力。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

听说 👉 点赞 👈 的人运气不会太差,每一天都会元气满满呦!^ _ ^

码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了👉 关注 👈我哦!

如果以上内容有任何错误或者不准确的地方,欢迎在下面👇留个言。或者你有更好的想法,欢迎一起交流学习~~~


发布于: 2021 年 02 月 16 日阅读数: 42
用户头像

AXYZdong

关注

没有伞的孩子要学会奔跑! 2020.06.01 加入

自动化专业 工科男 有一点思考,有一点想法,有一点理性。 定个小小目标,努力成为习惯。

评论

发布
暂无评论
【STM32】TIM---基本定时器