• stm32---基本定时器(TIM6,TIM7)


            STM32F1的定时器非常多,由两个基本定时器(TIM6,TIM7)、4个通用定时器(TIM2-TIM5)和两个高级定时器(TIM1,TIM8)组成。基本定时器的功能最为简单,类似于51单片机内定时器。通用定时器是在基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能主要针对工业电机控制方面。但无论是哪个定时器,它们的频率都为72M。

    基本定时器只有向上计数方式,且其挂载在APB1总线上,只能由内部时钟供能。基本定时器比较简单,就跟systic差不多。

    这个是stm32的中文手册中的介绍。

    图介绍:其中自动重装载寄存器(ARR)跟systic中的load寄存器作用一样,其作用主要有三部分:

    1. 设置定时器周期: ARR 决定了基本定时器计数器在溢出(从最大值返回0)之前所需的计数值。换句话说,ARR 值定义了定时器的定时周期。一旦计数器计数达到 ARR 的值,定时器将自动重新加载为0并触发一个更新事件。

    2. 产生定时中断: 当基本定时器的计数器达到 ARR 的值时,会触发一个更新事件,您可以配置定时器中断来捕获这个事件。这允许您在特定的时间间隔内执行代码,以执行定时任务。

    3. 生成PWM信号: 如果您使用基本定时器来生成PWM信号,ARR 将决定PWM信号的周期,即高电平和低电平的时间。

    基本定时器通常是16位的,所以 ARR 可以设置的最大值是 65535。预分频器也是16位的,但是在预分频器中数值会自动加1,也就是它的取值范围为1到65536,(因为这个预分频器是作为分母用的,分母不能为0,如:给预分频值设为2-1,那么该定时器的频率为32M)。

    自动重装载寄存器下面还有个影子寄存器,这个寄存器是实际起作用的寄存器,这个寄存器我们不能人为的去访问,基本定时器中的控制寄存器(TIMx_CR1)有一位(ARPE)是用来设置自动重装载寄存器是否具有缓冲的,stm32中文手册中的图如下:

    当ARPE位设置为0时,该自动重装载寄存器不具备缓冲,它会直接把数值传给影子寄存器,

    当ARPE位设置为1时,该自动重装载寄存器具备缓冲,它需要一个更新事件的产生才会把数值传给影子寄存器。

     我们可以写一个基本定时器的简单代码:

    1. void TIM_MyConfig(u16 per,u16 psc)
    2. {
    3. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    4. /*打开时钟*/
    5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
    6. /*初始化定时器*/
    7. TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ;
    8. TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    9. TIM_TimeBaseInitStruct.TIM_Period = per;//自动重装载值
    10. TIM_TimeBaseInitStruct.TIM_Prescaler = psc; //分频系数
    11. TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct);
    12. TIM_Cmd(TIM6, ENABLE);
    13. }

    1、第一步打开时钟,因为TIM2-TIM7都是挂载在APB1总线上的,所以我们需要打开APB1时钟,我们可以设置为TIM6。

    2、初始化定时器,这个要注意函数是TIM_TimeBaseInit();,这个与其它(如:GPIO的初始化函数GPIO_Init)不一样,其中:

    TIM_ClockDivision是用来设置定时器的时钟分频因子的成员,它用于控制定时器时钟的分频,从而影响定时器的计数速度。

    在STM32中,TIM_ClockDivision 的设置有以下选项:

    1. TIM_CKD_DIV1: 不分频。定时器的时钟不经过分频,以外部时钟源的速度进行计数。

    2. TIM_CKD_DIV2: 分频为2。定时器的时钟被分为2,即每2个外部时钟周期计数器增加1。

    3. TIM_CKD_DIV4: 分频为4。定时器的时钟被分为4,即每4个外部时钟周期计数器增加1。

    但是我们基本定时器使用到的是内部时钟源所以用不到 TIM_ClockDivision,可以设置为TIM_CKD_DIV1或者不配置这个成员,这个我们只在通用定时器或者高级定时器才用得到

    TIM_CounterMode是用来设置计数模式的成员,基本定时器只有一种向上计数模式,所以这一位设置为TIM_CounterMode_Up就可以了。

    TIM_Period是用来设置自动重装载值的成员(也就是设置计数次数),也就是自动重装载寄存器中的值,当计数器的计数值达到该值时会产生一个更新事件,这个值我们可以通过传参来设置。

    TIM_Prescaler 是用来设置分频系数的值(也就是设置多久计数一次),该值也可以通过传参来设置。

    在main函数中我们可以这样写:

    1. void HardWare_Init(void)
    2. {
    3. TIM_MyConfig(5000-1,7200-1);//0.5秒计数产生一次更新事件
    4. }
    5. int main(void)
    6. {
    7. u8 flag = 0;
    8. HardWare_Init();
    9. while(1)
    10. {
    11. if(TIM_GetFlagStatus(TIM6,TIM_FLAG_Update) == SET)
    12. {
    13. flag = !flag;
    14. }
    15. if(flag)
    16. {
    17. PAin(8) = 0;
    18. }
    19. else
    20. {
    21. PAin(8) = 1;
    22. }
    23. TIM_ClearFlag(TIM6,TIM_FLAG_Update);
    24. }
    25. }

    可以通过设置基本定时器来让LED灯按时闪烁,其中也用到了位带操作(PAin(8))。因为我们需要判断的是定时器是否发生更新事件,当定时器发生更新事件时说明完成了一个计数周期,所以我们用到的函数是 TIM_GetFlagStatus(TIM6,TIM_FLAG_Update)。

  • 相关阅读:
    浅谈软件测试面试一些常见的问题
    Win11校园网无法连接怎么办?Win11连接不到校园网的解决方法
    postgresql-常用数学函数
    C++-CMake指令:include指令【.cmake文件/MACRO宏/function函数】
    二进制转换16进制 快速心算
    龙蜥及其理事分获“2022 OSCAR 尖峰开源社区及项目、尖峰开源人物”奖项
    怎样在Windows10系统中安装配置PL/SQL
    扫码登录认证技术原理介绍及实践
    JavaScript基础——巩固练习(3)
    【面试心得】WebBench 整理
  • 原文地址:https://blog.csdn.net/wbyyd1314/article/details/132819657