引言
三个定时器TA0、TA1、TA2可配置成连续计数模式、增计数模式、增减计数模式。
可分别对每个定时器的三个比较捕获寄存器配置为比较计数模式或捕获模式。
* Timer_A_initUpModeParam; TIMA 0->TAxCCR0 溢出后中断
* Timer_A_initContinuousModeParam; TIMA 0->0xFFFF 溢出后中断
* Timer_A_initUpDownModeParam; TIMA 0->TAxCCR0->0 从0到0一个周期后进入中断
* Timer_A_initCaptureModeParam; 捕获上升沿或下降沿,捕获到跳变信号进入中断。TAxCCRn里是进入中断时,主计数器的值。
* Timer_A_outputPWMParam; 产生PWM信号
* Timer_A_initCompareModeParam; 比较值寄存器与主计数器的计数值TAR进行比较,一旦相等进入中断
官方例程解析
#include "driverlib.h"
#define COMPARE_VALUE 50000
void main (void)
{
//Stop WDT
WDT_A_hold(WDT_A_BASE);
//Set P1.0 to output direction
GPIO_setAsOutputPin(
GPIO_PORT_P1,
GPIO_PIN0
);
//Start timer in continuous mode sourced by SMCLK
Timer_A_initContinuousModeParam initContParam = {0};
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
initContParam.timerClear = TIMER_A_DO_CLEAR;
initContParam.startTimer = false;
Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);
//Initiaze compare mode
Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0
);
Timer_A_initCompareModeParam initCompParam = {0};
initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
initCompParam.compareValue = COMPARE_VALUE;
Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
Timer_A_startCounter( TIMER_A1_BASE,
TIMER_A_CONTINUOUS_MODE
);
//Enter LPM0, enable interrupts
__bis_SR_register(LPM0_bits + GIE);
//For debugger
__no_operation();
}
//******************************************************************************
//
//This is the TIMER1_A3 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER1_A0_VECTOR)))
#endif
void TIMER1_A0_ISR (void)
{
uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0)
+ COMPARE_VALUE;
//Toggle P1.0
GPIO_toggleOutputOnPin(
GPIO_PORT_P1,
GPIO_PIN0
);
//Add Offset to CCR0
Timer_A_setCompareValue(TIMER_A1_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0,
compVal
);
}
官方例程中将定时器A1配置成连续计数模式,其比较捕获寄存器0(即CCR0)选择比较计数模式。并关闭A1的溢出中断,打开CCR0的比较计数中断。当主计数器A1的计数值达到比较计数值(COMPARE_VALUE)时,进入TIMER1_A0_VECTOR。
在中断里:第一次进入:compVal = 50000+50000-65535=34465
TA1R = 50000
共计50000个数进入中断
第二次进入:compVal = 34465+50000-65535=18930
TA1R = 34465
共计65535-34465+18930 = 50000个数进入中断
以此类推......
故官方例程每50000/1000000=0.05秒进入一次中断,并翻转一次P1.0
配置增计数模式中断
结构体中initContParam.timerPeriod的值是CCR0的值,故中断向量选择TIMER1_A0_VECTOR。因为是溢出中断,中断服务函数里要加Timer_A_clearTimerInterrupt (TIMER_A1_BASE);。如果是比较计数中断则可以选择不加。
void main (void)
{
//Stop WDT
WDT_A_hold(WDT_A_BASE);
//Set P1.0 to output direction
GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0);
//Start timer in continuous mode sourced by SMCLK
Timer_A_initUpModeParam initContParam = {0};
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
initContParam.timerPeriod = 50000;
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
initContParam.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
initContParam.timerClear = TIMER_A_DO_CLEAR;
initContParam.startTimer = false;
Timer_A_initUpMode(TIMER_A1_BASE, &initContParam);
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
Timer_A_startCounter( TIMER_A1_BASE,TIMER_A_UP_MODE);
__bis_SR_register(GIE);
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER1_A0_VECTOR)))
#endif
void TIMER1_A0_ISR (void)
{
//Toggle P1.0
GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
}
配置连续计数中断
连续计数中结构体不设置CCR0的值,不使用比较捕获计数的话,溢出中断中断向量为TIMER1_A1_VECTOR。如果设置REGISTER_0为比较计数模式,中断向量为TIMER1_A0_VECTOR。如果设置REGISTER_1或REGISTER_2为比较计数模式,中断向量都为TIMER1_A1_VECTOR。并且优先级REGISTER_1>REGISTER_2>溢出中断。
void main (void)
{
//Stop WDT
WDT_A_hold(WDT_A_BASE);
GPIO_setAsOutputPin (GPIO_PORT_P1,GPIO_PIN0 );
GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN7 );
GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN0);
GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN7);
//Start timer in continuous mode sourced by SMCLK
Timer_A_initContinuousModeParam initContParam = {0};
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;//1MHZ
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
initContParam.timerClear = TIMER_A_DO_CLEAR;
initContParam.startTimer = false;
Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
//Initiaze compare mode
Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);
Timer_A_initCompareModeParam initCompParam = {0};
initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE;
initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
initCompParam.compareValue = COMPARE_VALUE;
Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
Timer_A_startCounter( TIMER_A1_BASE,TIMER_A_CONTINUOUS_MODE);
__bis_SR_register(GIE);
while(1)
{
if(y>20)
{
GPIO_toggleOutputOnPin(
GPIO_PORT_P4,
GPIO_PIN7
);
y=0;
}
if(x>20)
{
GPIO_toggleOutputOnPin(
GPIO_PORT_P1,
GPIO_PIN0
);
x=0;
}
}
}
#pragma vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR (void)
{
x=x+1;
}
#pragma vector=TIMER1_A1_VECTOR
__interrupt
void TIMER1_A1_ISR (void)
{
switch( TA1IV )
{
case 2: y=y+1;
break;//CCR1
case 4: y=y+1;
break;//CCR2
/*case 10: y=y+1;
break;*/
}
y=y+1;//time
Timer_A_clearTimerInterrupt (TIMER_A1_BASE);
}