完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1. 定时器简介
STM32F4的定时器分布如下: - 其中基本定时器包括TIM6、TIM7,其结构最简单,也具有最基本的定时功能,一是用于基本定时、产生时基、二是用于驱动DAC数模转换器。 - 其中通用定时器包括TIME2-TIME5,TIME9-TIME14共10个;通用定时器除了包含基本定时器的功能外还有输入捕获、输出比较和PWM功能等。 - 其中高级定时器包括TIM1、TIM8; 定时器的相关常用寄存器功能如下: 1.1 时钟源选择寄存器(TIMx_SMCR) 定时器的时钟源有4个: - 内部时钟(CK_INT) - 外部时钟模式1:外部输入脚(TIx) - 外部时钟模式2:外部触发输入(ETR),仅适用于TIM2、TIM3、TIM4 - 内部触发输入(ITRx):使得A定时器作为B定时器的预分频器(A为B提供时钟) 这是通过设置TIMx_SMCR的相关位来选择的。其中内部时钟(CK_INT)来自于APB1或APB2总线。 1.2 预分频寄存器(TIMx_PSC) 该寄存器用于对时钟进行分频,然后提供给计数器,作为计数器的时钟。 其中16位空间存储分频系数。 1.3 定时器计数寄存器(TIMx_CNT) 它存储了定时器当前的计数值。 1.4 自动重装载寄存器(TIMx_ARR) 该寄存器在物理结构上对应着2个寄存器,一个是程序员可以操作的,另一个是看不到且不能操作的ARM把它叫做影子寄存器。实际上真正起作用的是影子寄存器。 根据 TIMx_CR1 寄存器中 APRE 位的设置: APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2 者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装载寄存器( ARR) 的内容传送到影子寄存器。 1.5 DMA/中断使能寄存器(TIMx_DIER) 这里我们只用最后一位:更新中断使能(UIE:update interrupt enable),改为置1用来允许由更新事件产生的中断。 1.6 控制寄存器1(TIMx_CR1) 简单应用中,我们只需要使用最后一位:计数器使能位(CEN:counter enable),改为必须置1才能使计数器开始计数。 1.7 状态寄存器(TIMx_SR) 该寄存器用来标记当前定时器相关的各种事件/中断是否发生。 2. 库函数操作实例 接下来我们使用定时器产生定时中断,根据配置定时器的实际步骤,以TIM3为例解析配置过程。 定时器相关的库函数主要集中在固件库文件 stm32f4xx_tim.h 和 stm32f4xx_tim.c 文件中。 定时器配置步骤如下: 2.1 定时器时钟使能 TIM3挂载在APB1下,所以要通过使能APB1总线的使能函数来使能TIM3的时钟源。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能 TIM3 时钟 1 2.2 初始化定时器参数 配置定时器相关参数。 void TIM_TimeBaseInit( TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct ); 第一个参数是指定哪个定时器; 第二个参数是定时器配置参数结构体; typedef struct{ uint16_t TIM_Prescaler; //分频系数 uint16_t TIM_CounterMode; //计数方式(向上、向下、中央对其) uint16_t TIM_Period; //自动重载计数值(即定时时间) uint16_t TIM_ClockDivision; //时钟分频因子???? uint8_t TIM_RepetitionCounter; } TIM_TimeBaseInitTypeDef; 实际的: TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //声明初始化参数结构体变量 TIM_TimeBaseStructure.TIM_Period = 5000; //以下开始填充 TIM_TimeBaseStructure.TIM_Prescaler =7199; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //执行初始化 2.3 设置TIM3_DIER允许更新中断 库函数TIM_ITConfig用来设置打开中断 void TIM_ITConfig(TIM_TypeDef* TIMx, //指定哪个定时器 uint16_t TIM_IT, //指定中断类型(更新中断、触发中断等等) FunctionalState NewState); //使能还是失能 实际的: TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能更新中断 2.4 设置中断优先级 既然使用中断,就必须设置NVIC,使用NVIC_Init 函数设置。这里就不多讲了,很常用。 2.5 使能定时器 配置好后要使能定时器,使其开始工作,使用TIM_Cmd函数: void TIM_Cmd(TIM_TypeDef* TIMx, //指定定时器 FunctionalState NewState); //指定状态 实际的: TIM_Cmd(TIM3, ENABLE); //使能 TIM3 外设 2.6 编写中断函数 最后还是要编写中断函数来处理定时器产生的相关中断。流程为: 在中断产生后:通过状态寄存器的值来判断此次中断属于什么类型->执行相关操作->清除SR寄存器的中断标志。 读取中断状态的函数: ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t); 清除中断状态标志位的函数: void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); 另外,固件库中还提供了两个函数用来判断定时器的状态和清除定时器状态标志函数:TIM_GetFlagStatus 和 TIM_ClearFlag,它们的作用和上面两个相似,不过它们要先判断中断是否使能,然后再判断中断标志位,而TIM_GetITStatus直接判断中断标志位。 实际的: if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //判断中断状态 { // //do sth here. //执行操作 // } TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除中断标志 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1627 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1550 浏览 1 评论
984 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1601 浏览 2 评论
1867浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
650浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
518浏览 3评论
536浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
506浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 23:23 , Processed in 0.787643 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号