• MSP430F5529库函数定时器A——定时中断


    目录

    定时器A介绍

    (1)资源简介

    (2)定时器A时钟选择

    (3)Timer_A工作模式

     【1】增计数模式(01)

    【2】连续计数模式(10)

    【3】增减计数模式(11)

     (4)Timer_A中断

    函数介绍

    Timer_A_startCounter()

    函数声明

    作用

    参数

    Timer_A_initUpMode() 

    函数声明

    作用

    参数

    中断 

    使用

    Timer_A_initContinuousMode() 

    函数声明

    作用

    参数

    使用

    Timer_A_initUpDownMode() 

    函数声明

    作用

    参数

    使用

    实验

    TALE中断

    CCIFG0中断

    实验现象


    MSP430F5529的定时器有定时器A与定时器B,定时器B比定时器A强大一点。这里先只简单介绍定时器A,主要是教你使用库函数,详细资料请看用户手册,其他博客视频教程

    定时器A可以硬件输出PWM,脉冲捕获,定时中断。本文只讲定时中断部分

    定时器A介绍

    (1)资源简介

    定时器 A 是一个十六位的定时/计数器,MSP430F5529 中包含有 3 个定时器 A 的子模块 和 7 个捕捉/比较模块。定时器 A 支持多重捕获/比较,PWM 输出和内部定时。定时器还有 扩展中断功能,中断可以由定时器溢出产生或由捕获/比较寄存器产生。定时器 A 的特性包括:

     四种运行模式的异步 16 位定时/计数器

     可选择配置的时钟源

     可配置的 PWM 输出

     异步输入和输出锁存

     对所有 TA 中断快速响应的中断向量寄存器

    (2)定时器A时钟选择

    MSP430F5529定时器时钟 TACLK 可以选择 ACLKSMCLK 或者来自外部的 TAxCLK。SMCLK系统默认 1048576Hz,ACLK系统默认为32768Hz。

    (3)Timer_A工作模式

    看手册,我们知道有四中工作模式,第一个是停止状态,不计数,所以不讲。

     【1】增计数模式(01)

    此模式下,从0开始计数,可通过TAxCCR0的数值定义定时的周期。TAxCCR0数值小于0FFFFh。

    一般用于软件PWM,定时中断。这个用到应该是最多的

    【2】连续计数模式(10)

    从0开始计数,直至计数到0FFFFh之后从0开始重新计数。与增计数模式不同的是,不能被提前结束,必须是从0计数到0FFFFh。定时周期只能由时钟源频率决定

    一般用于捕获脉冲

    【3】增减计数模式(11)

    从0开始计数,增加到TAxCCR0,再从TAxCCR0减少到0。

     (4)Timer_A中断

    Timer_A有两个中断向量,CCIFG0中断TAIV中断。后面会有介绍

    1. TIMERx_A0_VECTOR // CCR0 的中断向量
    2. TIMERx_A1_VECTOR // TAIV 的中断向量

    函数介绍

    Timer_A_startCounter()

    函数声明

    void Timer_A_startCounter (uint16_t baseAddress, uint16_t timerMode);

    作用

    指定定时器A中的3个子定时器,并且以指定方式开始计数。

    参数

    baseAddress 

    1. TIMER_A0_BASE
    2. TIMER_A1_BASE
    3. TIMER_A2_BASE

     timerMode

    1. TIMER_A_STOP_MODE
    2. TIMER_A_UP_MODE //增计数模式
    3. TIMER_A_CONTINUOUS_MODE //连续计数模式
    4. TIMER_A_UPDOWN_MODE //增减计数模式

    Timer_A_initUpMode() 

    函数声明

    void Timer_A_initContinuousMode (uint16_t baseAddress,Timer_A_initContinuousModeParam ∗param)

    作用

    配置指定的3个子定时器为增计数模式

    参数

    baseAddress与上面一样

    Param的值为如下

    1. 1)clockSource:选择时钟源
    2. TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]
    3. TIMER_A_CLOCKSOURCE_ACLK
    4. TIMER_A_CLOCKSOURCE_SMCLK
    5. TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK
    6. 2)clockSourceDivider:选择时钟分频次数
    7. TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]
    8. TIMER_A_CLOCKSOURCE_DIVIDER_2
    9. TIMER_A_CLOCKSOURCE_DIVIDER_3
    10. TIMER_A_CLOCKSOURCE_DIVIDER_4
    11. TIMER_A_CLOCKSOURCE_DIVIDER_5
    12. TIMER_A_CLOCKSOURCE_DIVIDER_6
    13. TIMER_A_CLOCKSOURCE_DIVIDER_7
    14. TIMER_A_CLOCKSOURCE_DIVIDER_8
    15. TIMER_A_CLOCKSOURCE_DIVIDER_10
    16. TIMER_A_CLOCKSOURCE_DIVIDER_12
    17. TIMER_A_CLOCKSOURCE_DIVIDER_14
    18. TIMER_A_CLOCKSOURCE_DIVIDER_16
    19. TIMER_A_CLOCKSOURCE_DIVIDER_20
    20. TIMER_A_CLOCKSOURCE_DIVIDER_24
    21. TIMER_A_CLOCKSOURCE_DIVIDER_28
    22. TIMER_A_CLOCKSOURCE_DIVIDER_32
    23. TIMER_A_CLOCKSOURCE_DIVIDER_40
    24. TIMER_A_CLOCKSOURCE_DIVIDER_64
    25. TIMER_A_CLOCKSOURCE_DIVIDER_48
    26. TIMER_A_CLOCKSOURCE_DIVIDER_56
    27. 3)timerPeriod:指定的Timer_A时间段。这是写入的值进入CCR0。限制为16位[uint16_t]
    28. 4)timerInterruptEnable_TAIE:使能还是失能定时器中断
    29. TIMER_A_TAIE_INTERRUPT_ENABLE //使能定时器中断
    30. TIMER_A_TAIE_INTERRUPT_DISABLE //失能定时器中断
    31. 5)captureCompareInterruptEnable_CCR0_CCIE:选择中断响应
    32. TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE //CCR0中断
    33. TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE //TAIE中断
    34. 6)timerClear:选择是否把定时器的定时计数器,分频计数器的计数值清零
    35. TIMER_A_DO_CLEAR //清除
    36. TIMER_A_SKIP_CLEAR //不清除
    37. 7)startTimer:选择初始化之后是否立即启动定时器
    38. true //初始化后立即启动定时器
    39. false //初始化后不启动定时器

    中断 

    当定时器计数到CCR0的值的时候,置为标志位CCIFG。当定时器的值从CCR0计数到0的瞬间,置为TAIFG。 

    使用

    我们定时0.5s

    首先我们选择SMCLK作为主时钟,32分频之后就是32750HZ,计数16375次数(写入值要-1)。

    然后打开中断,最后两个设置与我一致即可,不用变化。

    1. void Timer_A_Init(void)
    2. {
    3. Timer_A_initUpModeParam htim = {0};
    4. htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源选为SMCLK = 1048576 HZ
    5. htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32; //32分频 32768
    6. htim.timerPeriod = 16384 - 1; //计数值设为1637432768/2=16374),定时0.5s
    7. htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; //使能TALE中断
    8. htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    9. htim.timerClear = TIMER_A_DO_CLEAR; //把定时器的定时计数器,分频计数器的计数值清零
    10. htim.startTimer = true; //初始化后立即启动定时器
    11. //配置定时器A为增计数模式
    12. Timer_A_initUpMode(TIMER_A0_BASE, &htim);
    13. }

    Timer_A_initContinuousMode() 

    函数声明

    void Timer_A_initContinuousMode (uint16_t baseAddress,Timer_A_initContinuousModeParam ∗ param )

    作用

    配置定时器A为连续计数模式

    参数

    baseAddress与上面一样

    Timer_A_initUpModeParam相比,Timer_A_initContinuousModeParam 少了(3)timerPeriod,因为连续计数模式是从0到0FFFFh的,所以不需要配置周期。

    也少了(5)captureCompareInterruptEnable_CCR0_CCIE,因为当定时值从FFFFh到0的瞬间,回设置TAIFG的标志位。所以他没有CCIFG0中断

    使用

    1. Timer_A_initContinuousModeParam htim = {0};
    2. htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    3. htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
    4. htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
    5. htim.timerClear = TIMER_A_DO_CLEAR;
    6. htim.startTimer = true;
    7. Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);

    Timer_A_initUpDownMode() 

    函数声明

    1. void Timer_A_initUpDownMode (uint16_t baseAddress,Timer_A_initUpDownModeParam ∗ param )

    作用

    配置定时器A为增/减计数模式

    参数

    baseAddress与上面一样

    Timer_A_initUpModeParam相比,Timer_A_initUpDownModeParam 一摸一样。

    使用

    1. Timer_A_initUpDownModeParam htim = {0};
    2. htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源选为SMCLK = 1.048MHz
    3. htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32; //64分频 32750
    4. htim.timerPeriod = 16374 - 1; //计数值设为16374 - 1
    5. htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; //使能TALE中断
    6. htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    7. htim.timerClear = TIMER_A_DO_CLEAR; //把定时器的定时计数器,分频计数器的计数值清零
    8. htim.startTimer = true; //初始化后立即启动定时器
    9. //配置定时器A为增计数模式
    10. Timer_A_initUpDownMode(TIMER_A0_BASE, &htim);

    实验

    因为增计数模式最简单,且使用方便,所以我以下都使用增计数模式。连续计数模式是在后续捕获实验中讲解。增减模式这个我也想不到有啥应用场景,知道的可以在评论区评论。

    实验为软件模拟实现PWM。周期为1S,占空比为50%

    TALE中断

    因为TALE的中断向量被公用,所以需要使用Switch语句,

    1. #include "driverlib.h"
    2. #define MCLK_IN_HZ 25000000
    3. #define delay_us(x) __delay_cycles((MCLK_IN_HZ/1000000*(x)))
    4. #define delay_ms(x) __delay_cycles((MCLK_IN_HZ/1000*(x)))
    5. void Timer_A_Init(void)
    6. {
    7. Timer_A_initUpModeParam htim = {0};
    8. htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源选为SMCLK = 1048576 HZ
    9. htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32; //32分频 32768
    10. htim.timerPeriod = 16384 - 1; //计数值设为1637432768/2=16374),定时0.5s
    11. htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; //使能TALE中断
    12. htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    13. htim.timerClear = TIMER_A_DO_CLEAR; //把定时器的定时计数器,分频计数器的计数值清零
    14. htim.startTimer = true; //初始化后立即启动定时器
    15. //配置定时器A为增计数模式
    16. Timer_A_initUpMode(TIMER_A0_BASE, &htim);
    17. }
    18. void main (void)
    19. {
    20. //Stop WDT
    21. WDT_A_hold(WDT_A_BASE);
    22. //P4.1为输出
    23. GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN1);
    24. Timer_A_Init();
    25. //interrupts enabled
    26. __bis_SR_register(GIE);
    27. while(1)
    28. {
    29. }
    30. }
    31. #pragma vector=TIMER0_A1_VECTOR
    32. __interrupt
    33. void TIMER0_A1_ISR (void)
    34. {
    35. switch(TA0IV)
    36. {
    37. case TA0IV_NONE:
    38. break;
    39. case TA0IV_TACCR1:
    40. break;
    41. case TA0IV_TACCR2:
    42. break;
    43. case TA0IV_TACCR3:
    44. break;
    45. case TA0IV_TACCR4:
    46. break;
    47. case TA0IV_5:
    48. break;
    49. case TA0IV_6:
    50. break;
    51. case TA0IV_TAIFG:
    52. GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN1);
    53. break;
    54. default:
    55. break;
    56. }
    57. }

    CCIFG0中断

    看注释掉的部分,就是要改的地方。 

    1. #include "driverlib.h"
    2. #define MCLK_IN_HZ 25000000
    3. #define delay_us(x) __delay_cycles((MCLK_IN_HZ/1000000*(x)))
    4. #define delay_ms(x) __delay_cycles((MCLK_IN_HZ/1000*(x)))
    5. void Timer_A_Init(void)
    6. {
    7. Timer_A_initUpModeParam htim = {0};
    8. htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源选为SMCLK = 1048576 HZ
    9. htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_32; //32分频 32768
    10. htim.timerPeriod = 16384 - 1; //计数值设为1637532768/2=16375),定时0.5s
    11. // htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; //使能TALE中断
    12. // htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
    13. htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; //失能TALE中断
    14. htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
    15. htim.timerClear = TIMER_A_DO_CLEAR; //把定时器的定时计数器,分频计数器的计数值清零
    16. htim.startTimer = true; //初始化后立即启动定时器
    17. //配置定时器A为增计数模式
    18. Timer_A_initUpMode(TIMER_A0_BASE, &htim);
    19. }
    20. void main (void)
    21. {
    22. //Stop WDT
    23. WDT_A_hold(WDT_A_BASE);
    24. //P4.1为输出
    25. GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN1);
    26. Timer_A_Init();
    27. //interrupts enabled
    28. __bis_SR_register(GIE);
    29. while(1)
    30. {
    31. }
    32. }
    33. //#pragma vector=TIMER0_A1_VECTOR
    34. //__interrupt
    35. //void TIMER0_A1_ISR (void)
    36. //{
    37. // switch(TA0IV)
    38. // {
    39. // case TA0IV_NONE:
    40. // break;
    41. // case TA0IV_TACCR1:
    42. // break;
    43. // case TA0IV_TACCR2:
    44. // break;
    45. // case TA0IV_TACCR3:
    46. // break;
    47. // case TA0IV_TACCR4:
    48. // break;
    49. // case TA0IV_5:
    50. // break;
    51. // case TA0IV_6:
    52. // break;
    53. // case TA0IV_TAIFG:
    54. // GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN1);
    55. // break;
    56. // default:
    57. // break;
    58. // }
    59. //}
    60. #pragma vector=TIMER0_A0_VECTOR
    61. __interrupt
    62. void TIMER0_A0_ISR (void)
    63. {
    64. GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN1);
    65. }

    实验现象

  • 相关阅读:
    【LeetCode】剑指 Offer Ⅱ 第8章:树(12道题) -- Java Version
    阿里400+天,我为什么离开阿里
    MySQL数据库八股文
    【Go ~ 0到1 】 第六天 文件的读写与创建
    Doris数据库BE——冷热数据方案
    Linux安装Hadoop超详细教程
    KVM管理平台选型与开源企业级虚拟化平台oVirt详解
    力扣(LeetCode)2578. 最小和分割(C++)
    以赛促教,以赛促研 ——计算机科学系举办“火焰杯”软件测试开发选拔赛颁奖仪式
    Spring系列-1 启动流程
  • 原文地址:https://blog.csdn.net/qq_63922192/article/details/127741121