您好!我用的是IAR5.0版本的编译器,编写MSP430G2553控制程序时,发现无法用TACLR对定时器进行清零,我通过IAR里面自带的寄存器观察工具观察TACTL寄存器的值,发现用软件编写TACTL|=TASSEL_2+TACLR+MC_1+ID_3;时无法寄存器TACTL中TACLR位没有置位,依然是0,很困惑,不知道是什么问题!网上查到的其他同行编写的程序都是通过这种方式对定时器进行清零的,所以请教一下这个是什么问题????
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!我用的是IAR5.0版本的编译器,编写MSP430G2553控制程序时,发现无法用TACLR对定时器进行清零,我通过IAR里面自带的寄存器观察工具观察TACTL寄存器的值,发现用软件编写TACTL|=TASSEL_2+TACLR+MC_1+ID_3;时无法寄存器TACTL中TACLR位没有置位,依然是0,很困惑,不知道是什么问题!网上查到的其他同行编写的程序都是通过这种方式对定时器进行清零的,所以请教一下这个是什么问题????
参考官方的一个例程看看是不是配置的问题
// MSP430G2xx3 Demo - Timer_A0, Normal Timer Mode Input Period and Dutycycle
// measurement
// Description: This code example implements input capture in single capture
// mode using TimerA in normal timer mode. TA1.1 is configured to output PWM
// of 25% dutycycle, that is used as capture input at TA0.1. TA0.1 is
// configured as timer input capture that is triggered by both the rising and
// the falling edges. An external connection between TA1.1 and TA0.1 is
// required in this example. Rising and Falling edges are captured and the
// dutycycle is computed. If the measured dutycycle is != 25%, then LED on
// P1.0 is set.
//
// ACLK = LFXT1 = 32kHz crystal ; SMCLK = MCLK = 8 MHz;
//
// MSP430F51x2
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P1.2/TA0.1|<-- CCI1A <-|
// | P2.1/TA1.1|--> CCR1 -->|
// | |
// | P1.0|--> LED "ON" when dutycycle != 25%
// | |
//
// W. Goh
// Texas Instruments Inc.
// March 2012
// Built with CCS v5.2 and IAR Embedded Workbench Version: 5.40.3
//******************************************************************************
#include <msp430.h>
unsigned char Count, First_Time;
unsigned int REdge1, REdge2, FEdge;
int main(void)
{
unsigned int Period, ON_Period;
unsigned char DutyCycle;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// P1SEL |= BIT0;
P1DIR |= BIT0; // P1.0/LED Output
P1OUT &= ~BIT0; // LED off
if (CALBC1_8MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz
DCOCTL = CALDCO_8MHZ;
// Configure Port Pins
P2DIR |= BIT1; // P2.1/TA1.1 Output
P2SEL |= BIT1; // TA1.1 Option select
P1DIR &= ~BIT2; // P1.1/TA0.1 Input Capture
P1SEL |= BIT2; // TA0.1 option select
// Configure TA1.1 to output PWM signal
// Period = 82/32khz = 2.5ms ~ 400Hz Freq
TA1CCR0 = 82-1; // Period Register
TA1CCR1 = 21; // TA1.1 25% dutycycle
TA1CCTL1 |= OUTMOD_7; // TA1CCR1, Reset/Set
TA1CTL = TASSEL_1 + MC_1 + TACLR; // ACLK, upmode, clear TAR
// Configure the TA0CCR1 to do input capture
TA0CCTL1 = CAP + CM_3 + CCIE + SCS + CCIS_0;
// TA0CCR1 Capture mode; CCI1A; Both
// Rising and Falling Edge; interrupt enable
TA0CTL |= TASSEL_2 + MC_2 + TACLR; // SMCLK, Cont Mode; start timer
// Variable Initialization
Count = 0x0;
First_Time = 0x01;
while(1)
{
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0
__no_operation(); // For debugger
// On exiting LPM0
if (TA0CCTL1 & COV) // Check for Capture Overflow
while(1); // Loop Forever
Period = REdge2 - REdge1; // Calculate Period
ON_Period = FEdge-REdge1; // On period
DutyCycle = ((unsigned long)ON_Period*100/Period);
if(DutyCycle!= 25)
{
P1OUT |= BIT0;
}
else
{
P1OUT &= ~BIT0;
}
}
}
// TA0_A1 Interrupt vector
#pragma vector = TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR (void)
{
switch(__even_in_range(TA0IV,0x0A))
{
case TA0IV_NONE: break; // Vector 0: No interrupt
case TA0IV_TACCR1: // Vector 2: TACCR1 CCIFG
if (TA0CCTL1 & CCI) // Capture Input Pin Status
{
// Rising Edge was captured
if (!Count)
{
REdge1 = TA0CCR1;
Count++;
}
else
{
REdge2 = TA0CCR1;
Count=0x0;
__bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main
}
if (First_Time)
First_Time = 0x0;
}
else
{
// Falling Edge was captured
if(!First_Time)
{
FEdge = TA0CCR1;
}
}
break;
case TA0IV_TACCR2: break; // Vector 4: TACCR2 CCIFG
case TA0IV_6: break; // Vector 6: Reserved CCIFG
case TA0IV_8: break; // Vector 8: Reserved CCIFG
case TA0IV_TAIFG: break; // Vector 10: TAIFG
default: break;
}
}
您好
在MSP430x2xx Family User-'s Guide里可以查到对TACLR位的解释里有这个:
Timer_A clear. Setting this bit resets TAR, the clock divider, and the count
direction. The TACLR bit is automatically reset and is always read as zero.
意思是这个位被你置位后会被自动清零的 所以你读取它的值时总为零
至于你想用这种方式来对TAR进行清零操作 也是在这个手册里有这么一句话:
It is recommended to stop the timer before modifying its operation (with
exception of the interrupt enable, interrupt flag, and TACLR) to avoid errant
operating conditions.
意思是在修改定时器寄存器时最好先把定时器停下来 但是括号里说除了修改中断使能,中断标志位和TACLR
所以直接置位TACLR来清零是可以实现的
我想您其实是已经清零成功了但是并没有发现自己成功了
建议您想一个办法来测试是否清零成功
比如使用两个定时器 第一个的CCR0里的数值是第二个里的两倍 在第一个定时器的中断里设置让灯亮
在第二个定时器的中断里对第一个的TACLR位进行置位操作 然后观察最终灯是否会亮
这个我也没有测试 只是这么个想法