The basic timer stm32 learning --TIM

  stm32f1 series, there are basic timers, general purpose timers, three senior timer TIM timer. Which, TIM6 / 7 is the article to talk about the basic timer.

  Basic Timer TIM6 / 7 is only 16-bit count-up timer is only used for timing. The general-purpose timer and timer have more advanced features, such as can also be output compare, input capture and other functions, related to the introduction of the article will be written on the back, where they talk about the basic timer.

  Take a look at the basic block diagram of the timer, as shown in 24-1.

  

 

  Figure 24-1

  Clock Source

  We refer to the section of the reference manual RCC clock tree can know, RCC timer clock TIMxCLK, that is, the internal clock CK_INT is provided by the APB1 divided by the prescaler. Shown in Figure 24-2, if the prescaler is APB1 1 ,, the same frequency, or the frequency is doubled. At this time, i.e., for dividing the pre APB1 division factor is 2, TIMxCLK = 36 * 2 = 72MHz.

  

 

  Figure 24-2

  Counter Clock

  The block diagram in FIG. 24-1, the counter clocked by an internal clock CK_INT, after PSC prescaler obtained CK_CNT. PSC is a 16-bit prescaler, it can be any number between 1 and 65536 dividing clock timer TIMxCLK. CK_CNT value calculated after dividing mentioned in the reference register described in the manual TIMx_PSC, 24-3 as shown in FIG.

  

 

  Figure 24-3

  即 = CK_CNT CK_PSC / (PSC [15: 0] +1).

  counter

  The counter CNT is a 16-bit counter, counts up only the maximum count value 65535.

  Automatic reload registers TIMx_ARR

  TIMx_ARR register deposit with the maximum count value, when the counted value, will generate an interrupt. Of course you have to enable the interrupt can.

  Timing time calculation

  A counted number of times is 1 / CK_CNT, an interrupt is generated time (ARR + 1) / CK_CNT. If a variable is set in the interrupt service routine interrupts for recording time, the scheduled time is: (ARR + 1) / CK_CNT * time.

  TIM_TimeBaseInitTypeDef

  FIG. 24-4 is a timer TIM_TimeBaseInitTypeDef basic structure is defined.

  

 

  Figure 24-4

  TIM_Prescaler:指定定时器预分频器数值,由TIMx_PSC寄存器配置,可设置范围为0x0000~0xFFFF,即0~65535;

  TIM_CounterMode:计数模式,可分为向上计数、向下计数以及三种中心对齐模式。而基本定时器只能向上计数;

  TIM_Period:计数器周期,即自动重装载寄存器TIMx_ARR的值,在事件生成时更新到影子寄存器,由TIMx_CR1寄存器的ARPE位配置是否使能缓冲;

  TIM_ClockDivision:时钟分频,配置定时器时钟CK_INT频率与数字滤波器采样时钟频率分频比,基本定时器没有这个功能,不用设置;

  TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可以很容易控制输出PWM个数,这里不用设置。

  定时1s实验

  例如,需要做一个1s的定时,CK_PSC=72MHz,则PSC=71,那么CK_CNT=1MHz,

  计一个数时间:1/CK_CNT = 1/1MHz = 1us,

  中断一次的时间:(ARR+1)/CK_CNT = (999+1)/1MHz = 1ms,

  则定时时间:(ARR+1)/CK_CNT*time = 1ms*1000 = 1s

  我们用led的亮灭状态变化来展示1s的定时。

  初始化TIM_TimeBaseInitTypeDef

  前文提到的TIM_TimeBaseInitTypeDef结构体有5个成员,但基本定时器TIM6/7只用到了TIM_Prescaler和TIM_Period这两个成员,其他三个是通用定时器和高级定时器才会用到的。

 

 /**

  * @brief 基本定时器配置

  * @param 无

  * @retval 无

  */

  static void BASIC_TIM_Mode_Config(void)

  {

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // 内部时钟72MHz

  TIM_TimeBaseStructure.TIM_Period = 999; // 自动重装载寄存器的值

  TIM_TimeBaseStructure.TIM_Prescaler= 71; // 预分频器数值

  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM6, TIM_FLAG_Update); // 清除计数器中断标志位

  TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

  TIM_Cmd(TIM6, ENABLE);

  }

 

  中断优先级配置

  有关中断配置相关已经在之前的文章介绍过,有不清楚的地方可移步阅读。这里只说几个配置的关键点。可配置中断优先级分组为0,即0位抢占优先级,4位子优先级。配置中断源为TIM6_IRQn。

  

/**

  * @brief 中断优先级配置

  * @param 无

  * @retval 无

  */

  static void BASIC_TIM_NVIC_Config(void)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  }

 

  中断函数

  中断函数在stm32f10x_it.c文件里配置。

  

extern volatile uint32_t time; // 该变量定义在main()函数里

  void TIM6_IRQHandler(void)

  {

  if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)

  {

  time++; // 每中断一次,time值加1,中断一次时间为1ms,需要中断1000次才可定时1s,即time值为1000

  TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update);

  }

  }

 

  最后在main()函数里调用led和定时器的初始化配置函数,在一个循环里判断time变量的值是否为1000,如果已经达到1000,则led灯状态变化(亮或灭)一次,并且time变量值重赋为0,以便继续判断及定时。

最后给大家分享些smt32方面的资料便于学习参考

(STM32中断系统)
http://www.makeru.com.cn/live/1392_1124.html?s=45051

(定时器)
http://www.makeru.com.cn/live/1392_1199.html?s=45051

基于STM32-WiFi智能小车机器人开发实战
http://www.makeru.com.cn/course/details/3008?s=45051

 

Guess you like

Origin www.cnblogs.com/8734ujn/p/11608349.html