MSP430F5529 DriverLib 库函数学习笔记(五)定时器A

目录

  • 硬知识
    • 定时器A 16位定时器原理
    • (1)时钟源选择和分频器
    • (2)Timer_A工作模式
    • (3)捕获/比较模块
    • (4)Timer_A中断(重要)
  • 定时器A API (机翻)
    • 定时器A配置和控制的函数
      • 参数
    • 定时器A 输出相关函数
      • 参数
    • 管理定时器A中断的程序
      • 参数
  • 中断向量
  • 上机实战
    • 定时器A 增计数模式CCR0中断
      • 初始化函数
      • 中断服务函数
      • 实验结果
    • 定时器A 增计数模式TAIE中断
      • 初始化函数
      • 中断服务函数
      • 实验结果
    • 输入捕获模式测量脉宽长度
      • 初始化函数
      • 中断服务函数
      • 被测信号产生
      • 实验结果

平台:Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)


硬知识

       定时器A具有如下特点:
 4种运行模式的异步16位定时/计数器;
 参考时钟源可选择配置;
 高达7个可配置的捕获/比较寄存器;
 可配置的PWM输出;
 异步输入和输出锁存;
 具有可对Timer_A中断快速响应的中断向量寄存器。
       定时器A的结构框图如图所示。
在这里插入图片描述

定时器A 16位定时器原理

       16位定时器的计数值寄存器TAR在每个时钟信号的上升沿进行增加/减少,可利用软件读取TAR寄存器的计数值。此外,当定时时间到,产生溢出时,定时器可产生中断。置位定时器控制寄存器中的TACLR控制位,可自动清除TAR寄存器的计数值,同时,在增/减计数模式下,清除了时钟分频器和计数方向。

(1)时钟源选择和分频器

       定时器的参考时钟源可以来自内部时钟ACLK、SMCLK或者来自TACLK引脚输入,可通过TASSEL控制位进行选择。选择的时钟源首先通过ID控制位进行1、2、4、8分频,对于分频后的时钟,可通过TAIDEX控制位进行1、2、3、4、5、6、7、8分频。

(2)Timer_A工作模式

       Timer_A共有4种工作模式:停止模式、增计数模式、连续计数模式和增/减计数模式,具体工作模式可以通过MC控制位进行选择,具体配置如表所示。
在这里插入图片描述
停止模式。停止模式用于定时器暂停,并不发生复位,所有寄存器现行的内容在停止模式结束后都可用。当定时器暂停后重新计数时,计数器将从暂停时的值开始以暂停前的计数方向计数。例如,停止模式前,Timer_A定时器工作于增/减计数模式并且处于下降计数方向,停止模式后,Timer_A仍然工作于增/减计数模式下,从暂停前的状态开始继续沿着下降方向开始计数。若不想这样,则可通过TAxCTL中的TACLR控制位来清除定时器的计数及方向记忆特性。
增计数模式。比较寄存器TAxCCR0用作Timer_A增计数模式的周期寄存器。由于TAxCCR0为16位寄存器,所以在该模式下,定时器A连续计数值应小于0FFFFh。TAxCCR0的数值定义了定时的周期,计数器TAR可以增计数到TAxCCR0的值,当计数值与TAxCCR0的值相等(或定时器值大于TAxCCR0的值)时,定时器复位并从0开始重新计数。增计数模式下的计数过程如左图所示。
当定时器计数值计数到TAxCCR0时,置位CCR0中断标志位CCIFG。当定时器从TAxCCR0计数到0时,置位Timer_A中断标志位TAIFG。增计数模式下中断标志位设置过程如右图所示。
在这里插入图片描述

连续计数模式。在连续计数模式下,Timer_A定时器增计数到0FFFFh之后从0开始重新计数,如此往复。连续计数模式下的计数过程如左图所示。
当定时器计数值从0FFFFh计数到0时,置位Timer_A中断标志位,连续计数模式下的中断标志位设置过程如右图所示。
在这里插入图片描述

       连续计数模式的典型应用如下:
 产生多个独立的时序信号:利用捕获比较寄存器捕获各种其他外部事件发生的定时器数据。
 产生多个定时信号:在连续计数模式下,每完成一个TAxCCRn(其中n取值为0~6)计数间隔,将产生一个中断,在中断服务程序中,将下一个时间间隔计数值赋给TAxCCRn,如 图6.4.7表示了利用两个捕获比较寄存器TAxCCR0和TAxCCR1产生两个定时信号t0和t1。在这种情况下,定时完全通过硬件实现,不存在软件中断响应延迟的影响,具体实现示意图如图所示。
在这里插入图片描述
增/减计数模式,需要对称波形的情况往往可以使用增/减计数模式。在该模式下,定时器先增计数到TAxCCR0的值,然后反方向减计数到0。计数周期仍由TAxCCR0定义,它是TAxCCR0值的2倍。增/减计数模式下的计数过程如左图所示。
在增/减计数模式下,TAxCCR0中断标志位CCIFG和Timer_A中断标志位TAIFG在一个周期内仅置位一次。当定时计数器增计数从TAxCCR0-1计数到TAxCCR0时,置位TAxCCR0中断标志位CCIFG,当定时计数器减计数从0001h到0000h时,置位Timer_A中断标志位TAIFG。增/减计数模式下中断标志位的设置过程如右图所示。
在这里插入图片描述

(3)捕获/比较模块

捕获/比较模块的逻辑结构如图所示,在此以捕获/比较模块TAxCCR6为例进行介绍。
在这里插入图片描述
捕获模式。当CAP控制位置为1时,捕获/比较模块配置为捕获模式。捕获模式被用于捕获事件发生的时间。捕获输入CCIxA和CCIxB可连接外部引脚或内部信号,这需通过CCIS控制位进行配置。可通过CM控制位将捕获输入信号触发沿配置为上升沿触发、下降沿触发或两者都触发。捕获事件在所选输入信号触发沿产生,如果产生捕获事件,定时器将完成以下工作:
 主计数器计数值复制到TAxCCRn寄存器中;
 置位中断标志位CCIFG。
输入信号的电平可在任意时刻通过CCI控制位进行读取。捕获信号可能会和定时器时钟不同步,并导致竞争条件的产生,将SCS控制位置位可在下一个定时器时钟使捕获同步。捕获信号示意图如左图所示。
如果第二次捕获在第一次捕获的值被读取之前发生,捕获/比较寄存器就会产生一个溢出逻辑,在此情况下,将置位COV标志位,如右图所示。注意COV标志位必须通过软件消除。
在这里插入图片描述
比较模式。当CAP控制位设为0时,捕获/比较模块工作在比较模式。比较模式用来产生PWM输出信号或者在特定的时间间隔产生中断。此时TAxCCRn的值可由软件写入,并通过比较器与主计数器的计数值TAR进行比较,当TAR计数到TAxCCRn时,将依次产生以下事件:
 置位中断标志位CCIFG;
 产生内部信号EQUn=1;
 EQUn信号根据不同的输出模式触发输出逻辑;
 输入信号CCI被锁存到SCCI。
       每个捕获/比较模块都包含一个输出单元,用于产生输出信号,例如PWM信号等。每个输出单元都有8种工作模式,可产生EQUx的多种信号。输出模式可通过OUTMOD控制位进行定义,具体定义如表所示。
在这里插入图片描述
增计数模式下,定时器比较输出
       在增计数模式下,当TAR增加到TAxCCRn或从TAxCCR0计数到0时,定时器输出信号按选择的输出模式发生变化。示例如图所示,该示例利用了TAxCCR0和TAxCCR1。
在这里插入图片描述
连续计数模式下,定时器比较输出
       在连续计数模式下,定时器输出波形与增计数模式一样,只是计数器在增计数到TAxCCR0后还要继续增计数到0FFFFh,这样就延长了计数器计数到TAxCCR1数值的时间。在连续计数模式下的输出波形如图所示。在该示例中同样用到了TAxCCR0和TAxCCR1。
在这里插入图片描述
增/减计数模式下,定时器比较输出
       在增/减计数模式下,各种输出模式与定时器工作在增计数模式或连续计数模式不同。当定时器计数值TAR在任意计数方向上等于TAxCCRn时或等于TAxCCR0时,定时器输出信号都按选定的输出模式发生改变。在增/减计数模式下的输出波形如图所示。该示例利用了TAxCCR0和TAxCCR2。
在这里插入图片描述

(4)Timer_A中断(重要)

16位定时器Timer_A具有两个中断向量,分别如下:
 TAxCCR0的中断向量CCIFG0
具有其余TAxCCRn的中断标志CCIFGn及TAIFG的中断向量TAIV

       在捕获模式下,当定时计数器TAR的值被捕获到TAxCCRn寄存器内时,置位相关的CCIFGn中断标志位。在比较模式下,当定时计数器TAR的值计数到TAxCCRn的值时,置位相关的CCIFGn中断标志位。也可利用软件置位或清除任意一个CCIFG中断标志位,当相关的CCIE中断允许位和GIE总中断允许位置位,CCIFGn中断标志位将请求产生中断。
① TAxCCR0中断
       TAxCCR0中断标志位CCIFG0在Timer_A中断中具有最高的中断优先级,TAxCCR0中断产生逻辑如图所示。当相应的TAxCCR0中断请求被响应后,TAxCCR0中断标志位CCIFG0自动复位。
② TAIV中断
       TAxIV中断主要包括TAxCCRn的中断标志CCIFGn和TAIFG中断标志。中断向量寄存器可被用来判断当前被挂起的Timer_A中断,之后通过查中断向量表得到中断服务程序的入口地址,并将其添加到程序计数器中,程序将自动转入中断服务程序。禁用Timer_A中断功能并不影响TAxIV中断向量寄存器的值。
       对TAxIV中断向量寄存器的读或写,都将自动清除挂起的最高优先级中断标志位。如果同时也置位了其他中断标志位,在当前中断服务程序执行完毕后,将自动立即响应新的中断请求。
       例如,当中断服务程序访问TAxIV中断向量寄存器时,同时TAxCCRI和TAxCCR2的CCIFG中断标志位置位。首先响应TAxCCRI的CCIFG中断请求,并且自动复位TAxCCR1的CCIFG中断标志位。当在中断服务程序中执行RETI断回执后,CPU响应TAXCCR2的CCIFG中断请求。
在这里插入图片描述
Timer_A具有丰富的寄存器资源供用户使用,详细列表如表所示
在这里插入图片描述

定时器A API (机翻)

定时器A APl被分成三组函数:
处理定时器配置和控制的函数,
处理定时器内容的函数,
以及处理中断的函数。

定时器A配置和控制的函数

Timer_A_startCounter(uint16_t baseAddress, uint16_t timerMode)	
//定时器A开始计数
Timer_A_initUpMode(uint16_t baseAddress, Timer_A_initUpModeParam ∗param)
//配置定时器A为增计数模式
Timer_A_initUpDownMode(uint16_t baseAddress, Timer_A_initUpDownModeParam
∗param)
//配置定时器A为增/减计数模式
Timer_A_initContinuousMode(uint16_t baseAddress, Timer_A_initContinuousModeParam ∗param)
//配置定时器A为连续计数模式
Timer_A_initCaptureMode(uint16_t baseAddress, Timer_A_initCaptureModeParam ∗param)
//初始化为捕获模式。
Timer_A_initCompareMode(uint16_t baseAddress, Timer_A_initCompareModeParam ∗param)
//初始化为比较模式
Timer_A_clear(uint16_t baseAddress)
//复位/清除计时器时钟分频器,计数方向,计数值
Timer_A_stop(uint16_t baseAddress)
//停止计时器计时

参数

baseAddress
是TIMER_A模块的基地址

TIMER_A0_BASE
TIMER_A1_BASE
TIMER_A2_BASE

timerMode

TIMER_A_STOP_MODE
TIMER_A_UP_MODE
TIMER_A_CONTINUOUS_MODE	// [Default]
TIMER_A_UPDOWN_MODE

Timer_A_initUpModeParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_initUpMode() function as the param parameter.
//
//*****************************************************************************
typedef struct Timer_A_initUpModeParam {//! Selects Clock source.//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]//! - \b TIMER_A_CLOCKSOURCE_ACLK//! - \b TIMER_A_CLOCKSOURCE_SMCLK//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLKuint16_t clockSource;//! Is the desired divider for the clock source//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64uint16_t clockSourceDivider;//! Is the specified Timer_A period. This is the value that gets written//! into the CCR0. Limited to 16 bits[uint16_t]uint16_t timerPeriod;//! Is to enable or disable Timer_A interrupt//! \n Valid values are://! - \b TIMER_A_TAIE_INTERRUPT_ENABLE//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]uint16_t timerInterruptEnable_TAIE;//! Is to enable or disable Timer_A CCR0 captureComapre interrupt.//! \n Valid values are://! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default]uint16_t captureCompareInterruptEnable_CCR0_CCIE;//! Decides if Timer_A clock divider, count direction, count need to be//! reset.//! \n Valid values are://! - \b TIMER_A_DO_CLEAR//! - \b TIMER_A_SKIP_CLEAR [Default]uint16_t timerClear;//! Whether to start the timer immediatelybool startTimer;
} Timer_A_initUpModeParam;

Timer_A_initUpDownModeParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_initUpDownMode() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct Timer_A_initUpDownModeParam {//! Selects Clock source.//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]//! - \b TIMER_A_CLOCKSOURCE_ACLK//! - \b TIMER_A_CLOCKSOURCE_SMCLK//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLKuint16_t clockSource;//! Is the desired divider for the clock source//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64uint16_t clockSourceDivider;//! Is the specified Timer_A perioduint16_t timerPeriod;//! Is to enable or disable Timer_A interrupt//! \n Valid values are://! - \b TIMER_A_TAIE_INTERRUPT_ENABLE//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]uint16_t timerInterruptEnable_TAIE;//! Is to enable or disable Timer_A CCR0 captureComapre interrupt.//! \n Valid values are://! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default]uint16_t captureCompareInterruptEnable_CCR0_CCIE;//! Decides if Timer_A clock divider, count direction, count need to be//! reset.//! \n Valid values are://! - \b TIMER_A_DO_CLEAR//! - \b TIMER_A_SKIP_CLEAR [Default]uint16_t timerClear;//! Whether to start the timer immediatelybool startTimer;
} Timer_A_initUpDownModeParam;

Timer_A_initContinuousModeParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_initContinuousMode() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct Timer_A_initContinuousModeParam {//! Selects Clock source.//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]//! - \b TIMER_A_CLOCKSOURCE_ACLK//! - \b TIMER_A_CLOCKSOURCE_SMCLK//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLKuint16_t clockSource;//! Is the desired divider for the clock source//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64uint16_t clockSourceDivider;//! Is to enable or disable Timer_A interrupt//! \n Valid values are://! - \b TIMER_A_TAIE_INTERRUPT_ENABLE//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default]uint16_t timerInterruptEnable_TAIE;//! Decides if Timer_A clock divider, count direction, count need to be//! reset.//! \n Valid values are://! - \b TIMER_A_DO_CLEAR//! - \b TIMER_A_SKIP_CLEAR [Default]uint16_t timerClear;//! Whether to start the timer immediatelybool startTimer;
} Timer_A_initContinuousModeParam;

Timer_A_initCaptureModeParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_initCaptureMode() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct Timer_A_initCaptureModeParam {//! Selects the Capture register being used. Refer to datasheet to ensure//! the device has the capture compare register being used.//! \n Valid values are://! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6uint16_t captureRegister;//! Is the capture mode selected.//! \n Valid values are://! - \b TIMER_A_CAPTUREMODE_NO_CAPTURE [Default]//! - \b TIMER_A_CAPTUREMODE_RISING_EDGE//! - \b TIMER_A_CAPTUREMODE_FALLING_EDGE//! - \b TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGEuint16_t captureMode;//! Decides the Input Select//! \n Valid values are://! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxA//! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxB//! - \b TIMER_A_CAPTURE_INPUTSELECT_GND//! - \b TIMER_A_CAPTURE_INPUTSELECT_Vccuint16_t captureInputSelect;//! Decides if capture source should be synchronized with timer clock//! \n Valid values are://! - \b TIMER_A_CAPTURE_ASYNCHRONOUS [Default]//! - \b TIMER_A_CAPTURE_SYNCHRONOUSuint16_t synchronizeCaptureSource;//! Is to enable or disable timer captureComapre interrupt.//! \n Valid values are://! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default]//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLEuint16_t captureInterruptEnable;//! Specifies the output mode.//! \n Valid values are://! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]//! - \b TIMER_A_OUTPUTMODE_SET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET//! - \b TIMER_A_OUTPUTMODE_SET_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE//! - \b TIMER_A_OUTPUTMODE_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET//! - \b TIMER_A_OUTPUTMODE_RESET_SETuint16_t captureOutputMode;
} Timer_A_initCaptureModeParam;

Timer_A_initCompareModeParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_initCompareMode() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct Timer_A_initCompareModeParam {//! Selects the Capture register being used. Refer to datasheet to ensure//! the device has the capture compare register being used.//! \n Valid values are://! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6uint16_t compareRegister;//! Is to enable or disable timer captureComapre interrupt.//! \n Valid values are://! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default]//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLEuint16_t compareInterruptEnable;//! Specifies the output mode.//! \n Valid values are://! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]//! - \b TIMER_A_OUTPUTMODE_SET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET//! - \b TIMER_A_OUTPUTMODE_SET_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE//! - \b TIMER_A_OUTPUTMODE_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET//! - \b TIMER_A_OUTPUTMODE_RESET_SETuint16_t compareOutputMode;//! Is the count to be compared with in compare modeuint16_t compareValue;
} Timer_A_initCompareModeParam;

定时器A 输出相关函数

Timer_A_getSynchronizedCaptureCompareInput((uint16_t baseAddress, uint16_t
captureCompareRegister, uint16_t synchronized)
//获取同步的capturecompare输入
Timer_A_getOutputForOutputModeOutBitValue(uint16_t baseAddress, uint16_t
captureCompareRegister)
//为输出模式获取输出位
Timer_A_setOutputForOutputModeOutBitValue(uint16_t baseAddress, uint16_t
captureCompareRegister, uint8_t outputModeOutBitValue)
//为输出模式设置输出位
Timer_A_outputPWM(uint16_t baseAddress, Timer_A_outputPWMParam ∗param)
//计时器A运行在增计数模式产生PWM
Timer_A_getCaptureCompareCount(uint16_t baseAddress, uint16_t
captureCompareRegister)
//获取当前capturecompare计数值
Timer_A_setCompareValue(uint16_t baseAddress, uint16_t compareRegister, uint16_t
compareValue)
//设置捕获比较寄存器的值
Timer_A_getCounterValue(uint16_t baseAddress)
//读取当前计时器A计数值

参数

baseAddress
是TIMER_A模块的基地址

TIMER_A0_BASE
TIMER_A1_BASE
TIMER_A2_BASE

captureCompareRegister

TIMER_A_CAPTURECOMPARE_REGISTER_0
TIMER_A_CAPTURECOMPARE_REGISTER_1
TIMER_A_CAPTURECOMPARE_REGISTER_2
TIMER_A_CAPTURECOMPARE_REGISTER_3
TIMER_A_CAPTURECOMPARE_REGISTER_4
TIMER_A_CAPTURECOMPARE_REGISTER_5
TIMER_A_CAPTURECOMPARE_REGISTER_6

compareRegister

TIMER_A_CAPTURECOMPARE_REGISTER_0
TIMER_A_CAPTURECOMPARE_REGISTER_1
TIMER_A_CAPTURECOMPARE_REGISTER_2
TIMER_A_CAPTURECOMPARE_REGISTER_3
TIMER_A_CAPTURECOMPARE_REGISTER_4
TIMER_A_CAPTURECOMPARE_REGISTER_5
TIMER_A_CAPTURECOMPARE_REGISTER_6

synchronized

TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT
TIMER_A_READ_CAPTURE_COMPARE_INPUT

outputModeOutBitValue

TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH
TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW

Timer_A_outputPWMParam

//*****************************************************************************
//
//! \brief Used in the Timer_A_outputPWM() function as the param parameter.
//
//*****************************************************************************
typedef struct Timer_A_outputPWMParam {//! Selects Clock source.//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default]//! - \b TIMER_A_CLOCKSOURCE_ACLK//! - \b TIMER_A_CLOCKSOURCE_SMCLK//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLKuint16_t clockSource;//! Is the desired divider for the clock source//! \n Valid values are://! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default]//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64uint16_t clockSourceDivider;//! Selects the desired timer perioduint16_t timerPeriod;//! Selects the compare register being used. Refer to datasheet to ensure//! the device has the capture compare register being used.//! \n Valid values are://! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6uint16_t compareRegister;//! Specifies the output mode.//! \n Valid values are://! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default]//! - \b TIMER_A_OUTPUTMODE_SET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET//! - \b TIMER_A_OUTPUTMODE_SET_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE//! - \b TIMER_A_OUTPUTMODE_RESET//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET//! - \b TIMER_A_OUTPUTMODE_RESET_SETuint16_t compareOutputMode;//! Specifies the dutycycle for the generated waveformuint16_t dutyCycle;
} Timer_A_outputPWMParam;

compareValue
是比较模式下需要比较的计数值

管理定时器A中断的程序

Timer_A_enableInterrupt(uint16_t baseAddress)
//使能定时器中断
Timer_A_disableInterrupt(uint16_t baseAddress)
//禁用定时器中断
Timer_A_getInterruptStatus(uint16_t baseAddress)
//获取定时器中断状态
Timer_A_enableCaptureCompareInterrupt(uint16_t baseAddress, uint16_t
captureCompareRegister)
//启用捕获比较中断
Timer_A_disableCaptureCompareInterrupt(uint16_t baseAddress, uint16_t
captureCompareRegister)
//禁用捕获比较中断
Timer_A_getCaptureCompareInterruptStatus(uint16_t baseAddress, uint16_t
captureCompareRegister, uint16_t mask)
//返回捕获比较中断状态
Timer_A_clearCaptureCompareInterrupt(uint16_t baseAddress, uint16_t
captureCompareRegister)
//清除捕获比较中断标志
Timer_A_clearTimerInterrupt(uint16_t baseAddress)
//清除Timer TAIFG中断标志

参数

baseAddress
是TIMER_A模块的基地址

TIMER_A0_BASE
TIMER_A1_BASE
TIMER_A2_BASE

captureCompareRegister

TIMER_A_CAPTURECOMPARE_REGISTER_0
TIMER_A_CAPTURECOMPARE_REGISTER_1
TIMER_A_CAPTURECOMPARE_REGISTER_2
TIMER_A_CAPTURECOMPARE_REGISTER_3
TIMER_A_CAPTURECOMPARE_REGISTER_4
TIMER_A_CAPTURECOMPARE_REGISTER_5
TIMER_A_CAPTURECOMPARE_REGISTER_6

mask

TIMER_A_CAPTURE_OVERFLOW
TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG

中断向量

TIMERx_A0_VECTOR 是 CCR0 的中断向量
TIMERx_A1_VECTOR 是 TAIV 的中断向量

#define TIMER2_A1_VECTOR        (43 * 1u)                    /* 0xFFD6 Timer2_A5 CC1-4, TA */
#define TIMER2_A0_VECTOR        (44 * 1u)                    /* 0xFFD8 Timer2_A5 CC0 */
#define TIMER1_A1_VECTOR        (48 * 1u)                    /* 0xFFE0 Timer1_A3 CC1-2, TA1 */
#define TIMER1_A0_VECTOR        (49 * 1u)                    /* 0xFFE2 Timer1_A3 CC0 */
#define TIMER0_A1_VECTOR        (52 * 1u)                    /* 0xFFE8 Timer0_A5 CC1-4, TA */
#define TIMER0_A0_VECTOR        (53 * 1u)                    /* 0xFFEA Timer0_A5 CC0 */

上机实战

定时器A 增计数模式CCR0中断

初始化函数

void Timer_A_Init(void)
{Timer_A_initUpModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_ACLK;	//时钟源选为ACLK = 32768Hzhtim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_64;	//64分频htim.timerPeriod = 512 - 1;									//计数值设为512 - 1htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;		//使能CCR0中断htim.timerClear = TIMER_A_DO_CLEAR;	//把定时器的定时计数器,分频计数器的计数值清零htim.startTimer = true;				//初始化后立即启动定时器//中断频率=32768Hz / 64 / 512 = 1HzTimer_A_initUpMode(TIMER_A0_BASE, &htim);//配置定时器A0为增计数模式
}

中断服务函数

#pragma vector=TIMER0_A0_VECTOR
__interrupt
void TIMER0_A0_ISR (void)
{GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);	//翻转P4.7
}

整个源文件如下

#include "driverlib.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}void Timer_A_Init(void)
{Timer_A_initUpModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_ACLK;htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_64;htim.timerPeriod = 512 - 1;htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;htim.timerClear = TIMER_A_DO_CLEAR;htim.startTimer = true;Timer_A_initUpMode(TIMER_A0_BASE, &htim);//配置定时器A为增计数模式
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN7);Timer_A_Init();//interrupts enabled__bis_SR_register(GIE);while(1){}
}#pragma vector=TIMER0_A0_VECTOR
__interrupt
void TIMER0_A0_ISR (void)
{GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);
}

实验结果

如图,成功得到脉宽为1s的方波
在这里插入图片描述

定时器A 增计数模式TAIE中断

初始化函数

void Timer_A_Init(void)
{Timer_A_initUpModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;	//时钟源选为SMCLK = 25MHzhtim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_5;	//5分频htim.timerPeriod = 25000 - 1;									//计数值设为25000 - 1htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;	//使能TALE中断htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;	htim.timerClear = TIMER_A_DO_CLEAR;	//把定时器的定时计数器,分频计数器的计数值清零htim.startTimer = true;	//初始化后立即启动定时器Timer_A_initUpMode(TIMER_A0_BASE, &htim);	//配置定时器A为增计数模式
}

中断服务函数

#pragma vector=TIMER0_A1_VECTOR
__interrupt
void TIMER0_A1_ISR (void)
{switch(TA0IV){case TA0IV_NONE:break;case TA0IV_TACCR1:break;case TA0IV_TACCR2:break;case TA0IV_TACCR3:break;case TA0IV_TACCR4:break;case TA0IV_5:break;case TA0IV_6:break;case TA0IV_TAIFG:GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);break;default:break;}
}

整个源文件如下

#include "driverlib.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}void Timer_A_Init(void)
{Timer_A_initUpModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_5;htim.timerPeriod = 25000 - 1;htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;htim.timerClear = TIMER_A_DO_CLEAR;htim.startTimer = true;//设得中断频率为25MHz / 5 / 25000 = 200HzTimer_A_initUpMode(TIMER_A0_BASE, &htim);//配置定时器A为增计数模式
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN7);Timer_A_Init();//interrupts enabled__bis_SR_register(GIE);while(1){}
}#pragma vector=TIMER0_A1_VECTOR
__interrupt
void TIMER0_A1_ISR (void)
{switch(TA0IV){case TA0IV_NONE:break;case TA0IV_TACCR1:break;case TA0IV_TACCR2:break;case TA0IV_TACCR3:break;case TA0IV_TACCR4:break;case TA0IV_5:break;case TA0IV_6:break;case TA0IV_TAIFG:GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);break;default:break;}
}

实验结果

如图所示,得到100Hz的方波,为所设定时器中断频率的一半。
在这里插入图片描述

输入捕获模式测量脉宽长度

在这里插入图片描述

初始化函数

先将Timer_A2初始化为连续计数模式
时钟源为SMCLK
将P2.5/TA2.2复用为输入捕获模式
TA2.2对应TIMER_A2_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2
检测上升沿和下降沿

uint32_t Sign_Counts = 0;
void Timer_A2_Capture_Init()
{Timer_A_initContinuousModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;htim.timerClear = TIMER_A_DO_CLEAR;htim.startTimer = true;Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);Timer_A_initCaptureModeParam capture_htim = {0};capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;capture_htim.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;capture_htim.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;Timer_A_initCaptureMode(TIMER_A2_BASE,&capture_htim);
}

中断服务函数

TA2.2对应TA2IV_TACCR2
检测到上升沿时记下初始计数值
检测到下降沿后记下结束时计数值,并将溢出次数清零
当被测信号为高电平时,每溢出一次,溢出次数增1,
最终信号长度即溢出次数*计时周期数+结束时计数值-初始计数值

#pragma vector=TIMER2_A1_VECTOR
__interrupt
void TIMER2_A1_ISR (void)
{static uint16_t Overflow_Times = 0;static uint16_t Sign_Begin = 0, Sign_End = 0;switch(TA2IV){case TA2IV_TACCR2:if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5)){Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);}else{Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);if(!Overflow_Times)Sign_Counts = Sign_End - Sign_Begin;else{Sign_Counts = (uint32_t)65536 * Overflow_Times + Sign_End - Sign_Begin;Overflow_Times = 0;}}Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);break;case TA2IV_TAIFG:if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5)){++Overflow_Times;}elseOverflow_Times = 0;Timer_A_clearTimerInterrupt(TIMER_A2_BASE);break;default:break;}
}

被测信号产生

信号产生引脚为P1.2
频率=25MHz/12500/40=50Hz
占空比为1/20=5%
脉宽长度为1/50*5%=1ms
将产生信号的P1.2接至检测信号的P2.5

#define TIMER_PERIOD 12500
void Timer_A0_PWM_Init(void)
{Timer_A_outputPWMParam htim = {0};//P1.2复用输出GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2);//时钟源选为SMCLK = 25MHzhtim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;//分频系数设为40htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_40;//装载值设为12500 - 1htim.timerPeriod = TIMER_PERIOD - 1;//P1.2 对应 TA0.1 故设为TIMER_A_CAPTURECOMPARE_REGISTER_1htim.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;htim.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;//脉宽为1mshtim.dutyCycle = TIMER_PERIOD / 20 ;//P1.2 对应 TA0.1 为TIMER_A0_BASETimer_A_outputPWM(TIMER_A0_BASE, &htim);
}

整个源文件如下

#include "driverlib.h"
#include "MSP430F5529_UART.h"#define MCLK_IN_HZ      25000000#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}#define TIMER_PERIOD 12500
void Timer_A0_PWM_Init(void)
{Timer_A_outputPWMParam htim = {0};//P1.2复用输出GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2);//时钟源选为SMCLK = 25MHzhtim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;//分频系数设为40htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_40;//装载值设为12500 - 1htim.timerPeriod = TIMER_PERIOD - 1;//P1.2 对应 TA0.1 故设为TIMER_A_CAPTURECOMPARE_REGISTER_1htim.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;htim.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;//脉宽为1mshtim.dutyCycle = TIMER_PERIOD / 20 ;//P1.2 对应 TA0.1 为TIMER_A0_BASETimer_A_outputPWM(TIMER_A0_BASE, &htim);
}uint32_t Sign_Counts = 0;
void Timer_A2_Capture_Init()
{Timer_A_initContinuousModeParam htim = {0};htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;htim.timerClear = TIMER_A_DO_CLEAR;htim.startTimer = true;Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);Timer_A_initCaptureModeParam capture_htim = {0};capture_htim.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;capture_htim.captureMode = TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE;capture_htim.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;capture_htim.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;capture_htim.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;capture_htim.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;Timer_A_initCaptureMode(TIMER_A2_BASE,&capture_htim);
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();UART_Init(USCI_A1_BASE, 115200);Timer_A0_PWM_Init();Timer_A2_Capture_Init();//interrupts enabled__bis_SR_register(GIE);while(1){delay_ms(1000);UART_printf(USCI_A1_BASE, "Pulse width: %fms\r\n", 1000.*Sign_Counts/UCS_getSMCLK());}
}#pragma vector=TIMER2_A1_VECTOR
__interrupt
void TIMER2_A1_ISR (void)
{static uint16_t Overflow_Times = 0;static uint16_t Sign_Begin = 0, Sign_End = 0;switch(TA2IV){case TA2IV_TACCR2:if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5)){Sign_Begin = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);}else{Sign_End = Timer_A_getCaptureCompareCount(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);if(!Overflow_Times)Sign_Counts = Sign_End - Sign_Begin;else{Sign_Counts = (uint32_t)65536 * Overflow_Times + Sign_End - Sign_Begin;Overflow_Times = 0;}}Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);break;case TA2IV_TAIFG:if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN5)){++Overflow_Times;}elseOverflow_Times = 0;Timer_A_clearTimerInterrupt(TIMER_A2_BASE);break;default:break;}
}

MSP430F5529_UART.c

/** MSP430F5529_UART.c**  Created on: 2021年7月25日*      Author: Royic*/
#include "driverlib.h"#include <string.h>
#include <stdarg.h>
#include <stdio.h>
void UART_printf(uint16_t baseAddress, const char *format,...)
{uint32_t length;va_list args;uint32_t i;char TxBuffer[128] = {0};va_start(args, format);length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);va_end(args);for(i = 0; i < length; i++)USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp = 0;USCI_A_UART_initParam huart = {0};if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}if(Baudrate <= 9600){huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp = (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp = (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp < 16)huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else{huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp /= 16;}huart.clockPrescalar = (int)UART_Temp;if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){huart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);}else{huart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity = USCI_A_UART_NO_PARITY;huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;huart.uartMode = USCI_A_UART_MODE;if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart)){return STATUS_FAIL;}//Enable UART module for operationUSCI_A_UART_enable(baseAddress);//Enable Receive InterruptUSCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}

MSP430F5529_UART.h

/** MSP430F5529_UART.h**  Created on: 2021年7月25日*      Author: Royic*/#ifndef MSP430F5529_UART_H_
#define MSP430F5529_UART_H_#include "driverlib.h"void UART_printf(uint16_t baseAddress, const char *format,...);
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate);#endif /* MSP430F5529_UART_H_ */

实验结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vim 常用快捷键(整理版)

最常用&#xff1a; x 删除后面的字符 X 删除前一个字符 删除3个字符就是3x dd:删除一行 D 删除到行尾 J:删除换行符&#xff0c;使下一行并上来。 nJ:连接后面的n行 u:撤销上一次操作 U:撤销当前行的所有修改 ctrlr:对撤消的撤消 I 在行首插入 a 在光标后插入 A…

MSP430F5529 DriverLib 库函数学习笔记(六)定时器A产生PWM波

目录1.通过Timer_A_outputPWM配置产生PWM波初始化函数计算修改占空比的函数整体程序效果2.单定时器产生多路PWM信号初始化函数实验结果3.对称PWM信号的产生初始化程序实验结果平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EX…

Key_EXTI_Config:神舟IV

GPIO 输入上拉&#xff0c;按键按下&#xff0c;pin接地&#xff0c;触发中断 Key_Config 1 void Key_Config(void)2 {3 GPIO_InitTypeDef GPIO_InitStructure;4 5 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);6 7 /* Configure KEY1 Button PC4*/8 RCC_APB2…

Java 将HTML转为XML

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(七)定时器B

目录硬知识Timer_B特点及结构Timer_B寄存器定时器B API处理计时器配置和控制的函数参数处理计时器输出的函数参数管理定时器B中断的函数参数平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 硬知识 16位定时器B(…

ruoyi接口权限校验

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(八)模数转换模块(ADC12)

目录硬知识模数转换概述MSP430单片机ADC12模块介绍MSP430单片机ADC12模块操作ADC12的转换模式采样和转换转换存储器使用片内集成温度传感器ADC12模块寄存器ADC_12A API (机翻)处理初始化和转换的函数参数处理中断的函数参数处理ADC_12A的辅助功能的函数参数上机实战&#xff08…

有意思的鼠标指针交互探究

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

python基本数据类型——str

一、字符串的创建 test str() / "" test str("licheng") / "licheng" 无参数&#xff0c;创建空字符串一个参数&#xff0c;创建普通字符串两个参数&#xff0c;int&#xff08;字节&#xff0c;编码&#xff09;二、字符串的常用方法 #capita…

MSP430F5529 DriverLib 库函数学习笔记(九)SPI

目录硬知识USCI的同步模式SPI概述SPI特性及结构框图同步操作原理与操作USCI寄存器——SPI模式USCI_x_SPI API &#xff08;机翻&#xff09;处理状态和初始化的函数参数处理数据的函数参数管理中断的函数参数DMA相关参数平台&#xff1a;Code Composer Studio 10.3.1 MSP430F5…

轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

深入理解Threadlocal

SUN公司早在JDK1.2的时候就为我们提供了java.lang.ThreadLocal,低版本的JDK所提供的get()返回的是Object对象&#xff0c;需要强制类型转换&#xff0c;使用起来不方便&#xff0c;而在JDK1.5引入了泛型&#xff0c;在一定程度地简化ThreadLocal的使用。 我们知道在spring容器中…

HDU 2289 几何+圆台

题意;给定一个圆台杯子的R&#xff0c;r&#xff0c;H和里面水的体积V 求h 二分。。。。。。。。。。。。。。。。。 因为解不出来h。。。。。。。。。。。。 View Code 1 /*2 几何3 圆台体积4 V1/3*pi*h*(r1*r1r2*r2r1*r2)5 6 */7 #include<stdio.h>8 #include<stri…

MSP430F5529 DriverLib 库函数学习笔记(十)SPI驱动墨水屏

目录上机实战SPI 驱动 墨水屏墨水屏介绍电子纸的分类电泳型电子纸技术详解原理结构优势与不足实验电路介绍程序分析引脚初始化SPI模块初始化发送和接收全部源代码main.cmain.h墨水屏相关Paper_Display.cPaper_Display.hInclude.h实验结果现象波形对应平台&#xff1a;Code Comp…

Xamarin开发IOS笔记:切换输入法时输入框被遮住

在进行IOS开发的过程中&#xff0c;出现类似微信朋友圈的交互界面&#xff0c;当用户遇到感兴趣的内容可以进行评论。为了方便评论输入&#xff0c;当出现评论输入框的时候自动将评论输入框移动至键盘的上方&#xff0c;这样方便边输入边查看。 当用户隐藏键盘或者切换输入法的…

技术管理进阶——你了解成长的全貌吗?

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(十一)I2C / IIC

目录硬知识USCI的I2C模式I2C概述MSP430单片机I2C模块特征及结构框图I2C原理I2C主从操作&#xff08;1&#xff09;从模式&#xff08;2&#xff09;主模式I2C模式下的USCI中断USCI寄存器—I2C模式I2C API (机翻)API介绍主机模式主机模式单字节传输主机模式多字节传输主机模式单…

使用 Abp.Zero 搭建第三方登录模块(一):原理篇

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP430F5529 DriverLib 库函数学习笔记(十二)I2C实战

目录上机实战I2C给 DAC 芯片 DAC7571 写入数字量DAC7571 介绍程序分析引脚复用I2C 初始化发送一个字节发送一个字读取一个字节读取多个字节中断服务函数整体代码main.cMSP430F5529_I2C.cMSP430F5529_I2C.h实验结果I2C 读取 TMP421 温度TMP421 简介程序摘要TMP421初始化温度的读…

mysqldump造成Buffer Pool污染的研究 [转]

原文链接&#xff1a;http://www.shaoqun.com/m/a/43307.aspx 前言&#xff1a; 最近Oracle MySQL在其官方Blog上贴出了 5.6中一些变量默认值的修改。其中innodb_old_blocks_time 的默认值从0替换成了1000&#xff08;即1s&#xff09; 关于该参数的作用摘录如下&#xff1a; h…