完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F103系列的单片机一共有11个定时器:
2个高级定时器 4个通用定时器 2个基本定时器 2个看门狗定时器 1个系统滴答定时器 除去看门狗定时器和滴答定时器,其他8个定时器列表: 其中, TIM1和TIM8是高级定时器 TIM2 - TIM5是通用定时器 TIM6和TIM7是基本定时器 这8个定时器都是16位的,它们计数的类型除了基本定时器TIM6和TIM7,都支持向上、向下、向上/向下3种计数模式。 计数器的3种计数模式: 向上计数模式:从0开始,计到arr预设值,产生溢出事件,返回重新计时; 向下计数模式:从arr预设值开始,计到0,产生溢出事件,返回重新计时; 中央对齐模式:从0开始向上计数,计到arr产生溢出事件,然后向下计数,计数到1以后,又产生溢出,然后再从0开始向上计数(这种计数方式也叫向上/向下计数)。 基本定时器(TIM6和TIM7)主要功能: 只有最基本的定时功能。基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。 通用定时器(TIM2 - TIM5)主要功能: 除了基本的定时器的功能外,还可以测量输入信号的脉冲长度( 输入捕获) 或者产生输出波形( 输出比较和PWM)。 高级定时器(TIM1和TIM8)主要功能: 高级定时器不但具有基本、通用定时器的所有的功能,还具有控制交直流电动机的所有功能。比如它可以输出6路互补带死区的信号,刹车功能等等。 通用定时器的时钟来源: a. 内部时钟(CK_INT) b. 外部时钟模式1:外部输入脚(TIx) c. 外部时钟模式2:外部触发输入(ETR) d. 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器 自动装载寄存器arr值得计算: Tout = ((arr + 1)*(psc + 1))/Tclk; Tclk:TIMx的输入时钟频率(单位:MHz) Tout:TIMx的溢出时间(单位:us) eg: 计时1秒,输入时钟频率为72MHz,psc预分频的值为35999,那么,((arr + 1)*(psc + 1))/72M = ((arr + 1)*(35999 + 1))/72M = 1s,就可以求解出自动预装载寄存器arr = 1999。 定时器每次计数到预设值后,会产生一次中断更新事件,进入中断服务函数。因此,每个定时器有一个或者多个对应的中断处理函数的入口。 对于STM32F103C8T6,需要注意的是,这款芯片没有基本定时器TIM6和TIM7。它的中断服务函数名如下: 不知小伙伴们还记不记得上一篇的精准延时?没错啦,精准延时那里就用到了系统滴答定时器。 ARM Cortex-M3内核中有一个Systick定时器,它是一个24位(0~(2^24-1))的倒计数定时器,这个脉冲计数值保存在当前计数值寄存器STK_VAL(Systick current value register)中,当计数到0时,它就会从Load寄存器中自动重装定时初值,只要不把CTRL寄存器中的ENABLE清0,它就永不停。 Systick定时器只能向下计数,每接收到一个时钟脉冲,STK_VAL的值就会向下减1,当减到0时,硬件会自动把重装载寄存器STK_LOAD(Systick reload value register)中保存的数据加载到STK_VAL,重新开始向下计数。如果STK_VAL的值被减至0时,会触发异常产生中断。所以,小伙伴们不要因为好玩,在程序里写一句 delay_ms(0) 或 delay_us(0)。这样会触发异常产生中断,到时你就找不着北啦~ 既然提到了精准延时,那这次小R给小伙伴们分享更加准确的LED灯闪烁时间,我们使用通用定时器中断来实现LED灯闪烁: 1. 新建两个文件,tim.c 和 tim.h 2. 在头文件 tim.h 添加下面代码: #ifndef _TIM_H #define _TIM_H #include “stm32f10x.h” void TIMx_Init(u16 arr, u16 psc); #endif 3. 把 tim.c 添加到工程中 4. 在 tim.c 中添加以下代码: #include “tim.h” void TIMx_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //声明TIMx定时器结构体 NVIC_InitTypeDef NVIC_InitStructure; //声明中断优先级结构体 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置中断优先级分组 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能APB1总线上的TIM3时钟 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件活动的自动装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许TIM3中断更新 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //配置外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设置抢先优先级为0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //设置子优先级为3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //初始化中断优先级 TIM_Cmd(TIM3,ENABLE); //使能TIM3 } void TIM3_IRQHandler(void) //TIM3中断服务函数 { if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET) //检查TIM3更新中断 { GPIOC-》ODR ^= 0X0001《《13; //PC13高低电平交替翻转 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除TIM3中断标志位 } } 定时器中断配置步骤: 1. NVIC优先级组配置 2. 使能定时器时钟 3. 初始化定时器 4. 设置定时器允许更新中断 5. 设置定时器中断优先级 6. 使能定时器 7. 编写中断服务函数 5. 实现定时器更新中断LED灯闪烁功能 #include “stm32f10x.h” #include “delay.h” #include “led.h” #include “tim.h” int mian(void) { led_init(); TIMx_Init(1999, 35999); while(1) { } } 需要注意的是:在中断函数中需要检验一下标志位,因为定时器的所有事件共用一个中断。但只使用更新中断不用检验也是没有问题滴。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1763 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1617 浏览 1 评论
1059 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
723 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1933浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
726浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
550浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 13:29 , Processed in 0.816141 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号