(三)定时器
一、MSP430单片机的定时器概述
MSP430共有4个16位定时器,主要包括定时器A的0、1、2以及定时器B,每个定时器输出通道个数不同。
时钟源包括ACLK、SMCLK和TACLK
二、定时器的工作模式
定时器主要包括4个工作模式:
① 停止模式。
停止模式用于定时器暂停,并不发生复位,所有寄存器现行的内容在停止模式结束后都可用。当定时器暂停后重新计数时,计数器将从暂停时的值开始以暂停前的计数方向计数。例如,停止模式前,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。增计数模式下中断标志位设置过程如右图所示。
注意:该模式如果只用定时器的溢出中断,用CCR0中断和TAIV中断都差不多,只差了一个时钟周期。
③ 连续计数模式
在连续计数模式下,Timer_A定时器增计数到0FFFFh之后从0开始重新计数,如此往复。连续计数模式下的计数过程如左图所示。
当定时器计数值从0FFFFh计数到0时,置位Timer_A中断标志位,连续计数模式下的中断标志位设置过程如右图所示。

④ 增/减计数模式
需要对称波形的情况往往可以使用增/减计数模式。在该模式下,定时器先增计数到TAxCCR0的值,然后反方向减计数到0。计数周期仍由TAxCCR0定义,它是TAxCCR0值的2倍。增/减计数模式下的计数过程如左图所示。
在增/减计数模式下,TAxCCR0中断标志位CCIFG和Timer_A中断标志位TAIFG在一个周期内仅置位一次。当定时计数器增计数从TAxCCR0-1计数到TAxCCR0时,置位TAxCCR0中断标志位CCIFG,当定时计数器减计数从0001h到0000h时,置位Timer_A中断标志位TAIFG。增/减计数模式下中断标志位的设置过程如右图所示。
三、定时器的中断
每个16位定时器Timerx_A具有两个中断向量,分别如下:
捕获/比较寄存器TAxCCR0的中断向量CCIFG0;
具有其余捕获/比较寄存器TAxCCRn的中断标志CCIFGn及溢出位TAIFG的中断向量TAIV。
在捕获模式下,当定时计数器TAR的值被捕获到TAxCCRn寄存器内时,置位相关的CCIFGn中断标志位。
在比较模式下,当定时计数器TAR的值计数到TAxCCRn的值时,置位相关的CCIFGn中断标志位。
注意:捕获/比较只与CCIFGn有关,和定时计数溢出寄存器TAIFG无关
① TAxCCR0中断
TAxCCR0中断标志位CCIFG0在Timer_A中断中具有最高的中断优先级。
② TAIV中断
TAxIV中断主要包括TAxCCRn的中断标志CCIFGn和TAIFG中断标志。
四、定时器A相关函数
(1)定时器A配置和控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Timer_A_startCounter(uint16_t baseAddress, uint16_t timerMode)
Timer_A_initUpMode(uint16_t baseAddress, Timer_A_initUpModeParam ∗param)
Timer_A_initUpDownMode(uint16_t baseAddress, Timer_A_initUpDownModeParam ∗param)
Timer_A_initContinuousMode(uint16_t baseAddress, Timer_A_initContinuousModeParam ∗param)
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)
|
(2)管理定时器A中断的相关函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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)
|
(3)定时器A输出相关函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Timer_A_getSynchronizedCaptureCompareInput((uint16_t baseAddress, uint16_t captureCompareRegister, uint16_t synchronized)
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)
Timer_A_getCaptureCompareCount(uint16_t baseAddress, uint16_t captureCompareRegister)
Timer_A_setCompareValue(uint16_t baseAddress, uint16_t compareRegister, uint16_t compareValue)
Timer_A_getCounterValue(uint16_t baseAddress)
|
五、相关实例
(1)定时器计数中断模式的初始化
中断频率 = 25MHZ/分频/htim.timerPeriod(CCR0寄存器的值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void TIMA_2_Init(void) { Timer_A_initUpModeParam htim = {0}; htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_64; htim.timerPeriod = 240000 - 1; htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE; htim.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE; htim.timerClear = TIMER_A_DO_CLEAR; htim.startTimer = true;
Timer_A_initUpMode(TIMER_A2_BASE, &htim); }
|
(2)CCR0中断的代码
1 2 3 4 5
| #pragma vector = TIMER0_A0_VECTOR __interrupt void TIMA0_0_ISR (void) {
}
|
(3)TAIV中断的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #pragma vector=TIMER0_A1_VECTOR __interrupt void TIMA0_1_ISR (void) { switch(TA0IV) { case TA0IV_TAIFG: { Timer_A_clearTimerInterrupt(TIMER_A0_BASE); break; } case TA0IV_NONE: break; case TA0IV_TACCR1: break; case TA0IV_TACCR2: break; case TA0IV_TA0CCR3: break; case TA0IV_TA0CCR4: break; case TA0IV_5: break; case TA0IV_6: break; default: break; } }
|
TAxIFG要和你选的定时器对应
(4)PWM输出初始化配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| void TIMA_0_PWM_Init(void) {
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5);
Timer_A_initUpModeParam htim = {0}; htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_4; htim.timerPeriod = 625 - 1; htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; 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);
Timer_A_initCompareModeParam htim_PWM = {0}; htim_PWM.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE; htim_PWM.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
htim_PWM.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; htim_PWM.compareValue = (int)(625 * 0.2); Timer_A_initCompareMode(TIMER_A0_BASE, &htim_PWM);
htim_PWM.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2; htim_PWM.compareValue = (int)(625 * 0.4); Timer_A_initCompareMode(TIMER_A0_BASE, &htim_PWM);
htim_PWM.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_3; htim_PWM.compareValue = (int)(625 * 0.6); Timer_A_initCompareMode(TIMER_A0_BASE, &htim_PWM);
htim_PWM.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_4; htim_PWM.compareValue = (int)(625 * 0.8); Timer_A_initCompareMode(TIMER_A0_BASE, &htim_PWM);
}
|
定时器可以同时配置PWM输出(比较模式)以及计数中断
(5)改变占空比
1 2 3 4 5
| Timer_A_setCompareValue( TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, i*625/10 );
|
占空比与输出电压成正比