vps主机可以做几个网站,模板网站可以做优化,网络规划设计师报名入口,ui设计师岗位介绍目录硬知识定时器A 16位定时器原理#xff08;1#xff09;时钟源选择和分频器#xff08;2#xff09;Timer_A工作模式#xff08;3#xff09;捕获/比较模块#xff08;4#xff09;Timer_A中断#xff08;重要#xff09;定时器A API (机翻)定时器A配置和控制的函…
目录硬知识定时器A 16位定时器原理1时钟源选择和分频器2Timer_A工作模式3捕获/比较模块4Timer_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分频。
2Timer_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取值为06)计数间隔将产生一个中断在中断服务程序中将下一个时间间隔计数值赋给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 产生内部信号EQUn1 EQUn信号根据不同的输出模式触发输出逻辑 输入信号CCI被锁存到SCCI。 每个捕获/比较模块都包含一个输出单元用于产生输出信号例如PWM信号等。每个输出单元都有8种工作模式可产生EQUx的多种信号。输出模式可通过OUTMOD控制位进行定义具体定义如表所示。 增计数模式下定时器比较输出 在增计数模式下当TAR增加到TAxCCRn或从TAxCCR0计数到0时定时器输出信号按选择的输出模式发生变化。示例如图所示该示例利用了TAxCCR0和TAxCCR1。 连续计数模式下定时器比较输出 在连续计数模式下定时器输出波形与增计数模式一样只是计数器在增计数到TAxCCR0后还要继续增计数到0FFFFh这样就延长了计数器计数到TAxCCR1数值的时间。在连续计数模式下的输出波形如图所示。在该示例中同样用到了TAxCCR0和TAxCCR1。 增/减计数模式下定时器比较输出 在增/减计数模式下各种输出模式与定时器工作在增计数模式或连续计数模式不同。当定时器计数值TAR在任意计数方向上等于TAxCCRn时或等于TAxCCR0时定时器输出信号都按选定的输出模式发生改变。在增/减计数模式下的输出波形如图所示。该示例利用了TAxCCR0和TAxCCR2。
4Timer_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_BASEtimerMode
TIMER_A_STOP_MODE
TIMER_A_UP_MODE
TIMER_A_CONTINUOUS_MODE // [Default]
TIMER_A_UPDOWN_MODETimer_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_BASEcaptureCompareRegister
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_6compareRegister
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_6synchronized
TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT
TIMER_A_READ_CAPTURE_COMPARE_INPUToutputModeOutBitValue
TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH
TIMER_A_OUTPUTMODE_OUTBITVALUE_LOWTimer_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_BASEcaptureCompareRegister
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_6mask
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 vectorTIMER0_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 vectorTIMER0_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 vectorTIMER0_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 vectorTIMER0_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 vectorTIMER2_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/4050Hz 占空比为1/205% 脉宽长度为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 vectorTIMER2_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 vectorUSCI_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 vectorUSCI_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.hvoid UART_printf(uint16_t baseAddress, const char *format,...);
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate);#endif /* MSP430F5529_UART_H_ */
实验结果