1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、定时器简介
STM32F1 系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器。 基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定时,没有外部 IO。 通用定时器 TIM2/3/4/5 是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部 IO。 高级定时器 TIM1/8是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有 8 个外部 IO。 1.1 基本定时器功能 ①时钟源 定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB1 预分频器后分频提供,如果APB1 预分频系数等于 1,则频率不变,否则频率乘以 2,库函数中 APB1 预分频的系数是 2,即 PCLK1=36M,所以定时器时钟 TIMxCLK=36*2=72M。 ②计数器时钟 定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。PSC 是一个16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)。 ③计数器 计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。 ④自动重装载寄存器 自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。 1.2 基本定时器时基 基本定时器的核心是时基,不仅基本定时器有,通用定时器和高级定时器也有。基本定时器与通用定时器的时基有3个(TIMx_CNT、TIMx_PSC、TIMx_ARR)。高级定时器的时基有4个(TIMx_CNT、TIMx_PSC、TIMx_ARR、TIMx_RCR)。 二、基本定时器使用流程 2.1 NVIC 设置 /** @brief NVIC初始化(使用TIM6基本定时器) @param 无 @return 无 */ void BASIC_TIM_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; // 设置中断组为 0 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断来源 NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn ; // 设置主优先级为 0 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 设置抢占优先级为 3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 2.2 定时器中断配置 /** @brief 定时器中断配置(使用TIM6基本定时器) @param 无 @return 无 */ void BASIC_TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* 可以从上图看出基本定时器和通用定时器使用APB1总线, 高级定时器使用APB2总线。 */ // 开启定时器时钟,即内部时钟 CK_INT=72M RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); /* 预分频将输入时钟频率按1~65536之间的值任意分频,分频值决定了计数频率。 计数值为计数的个数,当计数寄存器的值达到计数值时,产生溢出,发生中断。 如系统时钟为72MHz,预分频 TIM_Prescaler = 71, 计数值 TIM_Period = 1000, 则 TIM_Period * (TIM_Prescaler + 1) / 72000000 = 0.001, 即每1ms产生一次中断。 */ // 自动重装载寄存器周的值(计数值) TIM_TimeBaseStructure.TIM_Period = 1000; // 累计 TIM_Period 个频率后产生一个更新或者中断 // 时钟预分频数为 71, // 则驱动计数器的时钟 CK_CNT = CK_INT / (71+1)=1M TIM_TimeBaseStructure.TIM_Prescaler = 71; // 时钟分频因子 ,基本定时器没有,不用管 //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置 //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重复计数器的值,基本定时器没有,不用管 //TIM_TimeBaseStructure.TIM_RepetitionCounter=0; /* 完成时基设置 */ // 初始化定时器 TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); /* 为了避免在设置时进入中断,这里需要清除中断标志位。 如果是向上计数模式(基本定时器采用向上计数), 则采用函数 TIM_ClearFlag(TIM6, TIM_FLAG_Update), 清除向上溢出中断标志。 */ // 清除计数器中断标志位 TIM_ClearFlag(TIM6, TIM_FLAG_Update); // 使能计数器 TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); // 开启计数器 TIM_Cmd(TIM6, ENABLE); // 暂时关闭定时器的时钟,等待使用 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, DISABLE); } 2.3 中断服务程序 #define BASIC_TIM_IRQHandler TIM6_IRQHandler // 1ms发生一次中断,time 记录中断次数 uint16_t time; void BASIC_TIM_IRQHandler(void) { if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) { time++; TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update); } } 三、设计实例 board_timer.h #ifndef BOARD_TIMER_H #define BOARD_TIMER_H /************************************************** * INCLUDES */ #include “stm32f10x.h” /************************************************** * DEFINITIONS */ #define BASIC_TIM_IRQHandler TIM6_IRQHandler /************************************************** * API FUNCTIONS */ void BASIC_TIM_Config(void); void BASIC_TIM_NVIC_Config(void); #endif board_timer.c #include “board_timer.h” /************************************************** * GLOBAL VALUE */ uint16_t time; /************************************************** * PUBLIC FUNCTIONS */ /** @brief NVIC初始化(使用TIM6基本定时器) @param 无 @return 无 */ void BASIC_TIM_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; // 设置中断组为 0 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断来源 NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn ; // 设置主优先级为 0 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 设置抢占优先级为 3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** @brief 定时器中断配置(使用TIM6基本定时器) @param 无 @return 无 */ void BASIC_TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* 可以从上图看出基本定时器和通用定时器使用APB1总线, 高级定时器使用APB2总线。 */ // 开启定时器时钟,即内部时钟 CK_INT=72M RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); /* 预分频将输入时钟频率按1~65536之间的值任意分频,分频值决定了计数频率。 计数值为计数的个数,当计数寄存器的值达到计数值时,产生溢出,发生中断。 如系统时钟为72MHz,预分频 TIM_Prescaler = 71, 计数值 TIM_Period = 1000, 则 TIM_Period * (TIM_Prescaler + 1) / 72000000 = 0.001, 即每1ms产生一次中断。 */ // 自动重装载寄存器周的值(计数值) TIM_TimeBaseStructure.TIM_Period = 1000; // 累计 TIM_Period 个频率后产生一个更新或者中断 // 时钟预分频数为 71, // 则驱动计数器的时钟 CK_CNT = CK_INT / (71+1)=1M TIM_TimeBaseStructure.TIM_Prescaler = 71; // 时钟分频因子 ,基本定时器没有,不用管 //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置 //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重复计数器的值,基本定时器没有,不用管 //TIM_TimeBaseStructure.TIM_RepetitionCounter=0; /* 完成时基设置 */ // 初始化定时器 TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); /* 为了避免在设置时进入中断,这里需要清除中断标志位。 如果是向上计数模式(基本定时器采用向上计数), 则采用函数 TIM_ClearFlag(TIM6, TIM_FLAG_Update), 清除向上溢出中断标志。 */ // 清除计数器中断标志位 TIM_ClearFlag(TIM6, TIM_FLAG_Update); // 使能计数器 TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); // 开启计数器 TIM_Cmd(TIM6, ENABLE); // 暂时关闭定时器的时钟,等待使用 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, DISABLE); } main.c #include “board_timer.h” extern uint16_t time; int main() { /* 基本定时器 TIMx,x[6,7] 定时配置 */ BASIC_TIM_Config(); /* 配置基本定时器 TIMx,x[6,7]的中断优先级 */ BASIC_TIM_NVIC_Config(); /* 基本定时器 TIMx,x[6,7] 重新开时钟,开始计时 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); while(1) { if(time == 1000) { /* 1000 * 1 ms = 1s 时间到 */ time = 0; /* LED1 取反 */ static uint8_t tmp = 0; /*LED1 反转*/ if(tmp == 0) { // 该函数在GPIO输出章节中 UseLibSetOutput(GPIOB, GPIO_Pin_0,0); tmp = 1; } else { // 该函数在GPIO输出章节中 UseLibSetOutput(GPIOB, GPIO_Pin_0,1); tmp = 0; } } } return 0; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1820 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1634 浏览 1 评论
1104 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
740 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
756浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
587浏览 3评论
605浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
570浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-31 01:46 , Processed in 0.887489 second(s), Total 78, Slave 62 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号