管理员
最后登录1970-1-1
在线时间 小时
注册时间2013-3-25
|
STM32定时器分类
基本定时器TIM6和TIM7都有一个16位的计数器,计数方式只能向上,没有外面IO,是属于内部定时器。
基本定时器TIM6和TIM7框图剖析
基本定时器主要由PSC预分频器、CNT计数器、自动重装载寄存器这三部分组成。16位的计数器在
预分频器时钟CK_CNT的驱动下从0往上计数,计数器的计数模式只能是向上,最大是2^16=65535,
当计数值等于自动重装载寄存器中的数值时,产生一个更新事件,该事件可以是计数器溢出中断或者
是DMA请求。更新事件之后,计数器清零,重新开始计数。
①定时器时钟
定时器时钟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位的计数器,只能往上计数,当计数达到自动重装载寄存器的时候产生更新事件,
并清零从头开始计数。
④自动重装载寄存器
自动重装载寄存器ARR是一个16位的寄存器,这里面装着计数器能计数的最大数值。
定时时间的计算
定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在CK_CNT的驱动下,计一个数的时间则是CK_CLK
的倒数,等于:1/(TIMxCLK/(PSC+1)),产生一次中断的时间则等于:1/(CK_CLK * ARR)。
如果在中断服务程序里面设置一个变量time,用来记录中断的次数,那么就可以计算出我们需要的定时时间等于:1/(CK_CLK * ARR)* time
基本定时器除了可以产生基本的定时之外,还可以用来触发DAC的同步电路,实际上TIM6和TIM7在内部已经连接到了各自
的DAC中,关于这部分的知识我们在DAC章节再详细讲解。
============================基本定时器TIM6和TIM7编程要点============================
1、开定时器时钟TIMx_CLK, x[6,7]
2、设置自动重装载寄存器ARR的值
3、确定计数器的时钟,设置PSC的分频系数
4、初始化TIMx, x[6,7]
5、使能TIMx, x[6,7] update中断
6、打开定时器
7、编写中断服务程序
简单的不能再简单了,简直就跟51单片机的定时器一样
我看到很多人在初始化基本定时器的时候,还拼命的初始化TIM_CounterMode、TIM_ClockDivision和TIM_RepetitionCounter
这三个成员,基本定时器根本就没有计数模式的设置,只能向上计数,也没有时钟分频因子和重复计数器,你们倒是在
瞎折腾个啥,型号也没有,所以你折腾了也没关系,不会出错,就因为瞎打误撞你还真以为就理解对了,其实你还不懂。
- /*
- * 注意: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,15,16,17]才有
- *-------------------------------------------------------------------------------------------------------------
- */
复制代码 基本定时器初始化代码如下:
- void TIMx_Configuration(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
- // 开启TIMx_CLK,x[6,7],即内部时钟CK_INT=72M
- macTIM_APBxClock_FUN (macTIM_CLK, ENABLE);
-
- // 自动重装载寄存器周的值(计数值)
- TIM_TimeBaseStructure.TIM_Period=1000;
-
- // 累计 TIM_Period个频率后产生一个更新或者中断
- // 时钟预分频数为71,则驱动计数器的时钟CK_CNT = CK_INT / (71+1)=1M
- TIM_TimeBaseStructure.TIM_Prescaler= 71;
-
- // 时钟分频因子 ,基本定时器TIM6和TIM7没有,不用管
- //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
-
- // 计数器计数模式,基本定时器TIM6和TIM7只能向上计数,没有计数模式的设置,不用管
- //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
-
- // 重复计数器的值,基本定时器TIM6和TIM7没有,不用管
- //TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
-
- // 初始化定时器TIMx, x[6,7]
- TIM_TimeBaseInit(macTIMx, &TIM_TimeBaseStructure);
-
- // 清除计数器中断标志位
- TIM_ClearFlag(macTIMx, TIM_FLAG_Update);
-
- // 开启计数器中断
- TIM_ITConfig(macTIMx,TIM_IT_Update,ENABLE);
-
- // 使能计数器
- TIM_Cmd(macTIMx, ENABLE);
-
- // 暂时关闭TIMx,x[6,7]的时钟,等待使用
- macTIM_APBxClock_FUN (macTIM_CLK, DISABLE);
- }
复制代码 默认初始化的是基本定时器TIM6,如果想用TIM7,把macTIM6这个宏注释掉即可
- /********************基本定时器TIM参数定义,只限TIM6、7************/
- #define macTIM6 // 如果使用TIM7,注释掉这个宏即可
- #ifdef macTIM6 // 使用基本定时器TIM6
- #define macTIMx TIM6
- #define macTIM_APBxClock_FUN RCC_APB1PeriphClockCmd
- #define macTIM_CLK RCC_APB1Periph_TIM6
- #define macTIM_IRQ TIM6_IRQn
- #define macTIM_INT_FUN TIM6_IRQHandler
- #else // 使用基本定时器TIM7
- #define macTIMx TIM7
- #define macTIM_APBxClock_FUN RCC_APB1PeriphClockCmd
- #define macTIM_CLK RCC_APB1Periph_TIM7
- #define macTIM_IRQ TIM7_IRQn
- #define macTIM_INT_FUN TIM7_IRQHandler
- #endif
复制代码
基本定时器TIM6和TIM7 定时1s代码
TIM—基本定时器定时.rar
(312.26 KB, 下载次数: 266)
教程:
TIM—通用定时器.pdf
(351.15 KB, 下载次数: 318)
|
|