2

朋友们,我必须在 61 微秒的时隙中每 14 微秒采样一次输入,并使用定时器输入(项目要求)。

我必须做 8 次才能生成一个字节。更像 UART ,但我将它用于我的硕士项目的单线总线通信。

我编写了如下代码,它给出了预期的结果,并在调试器中一次执行一条指令对其进行了测试。

下面是代码。

/*****************************************************************************

COMPARE MODE SAMPLING:


MCLK and SCLK @8MZ

The code configures P2.1  as TA1.CCI1A input.
It samples the input at P2.1 Whenever the TA1R reaches the TA1CCR1 value.

It samples input on P2.1 every 14us once in a duration of 61 us.

It then reads 8 bits one by one to read a byte.

******************************************************************************/

#include "io430g2553.h"

#define MSP_DQ BIT5


unsigned char word=0x00;



unsigned char i=0;
unsigned char temp;

void Read(void)
{

TA1CCR0 = 0x1E8; //  61 micro secs




TA1CCR1 = 0x70; // 14 micro secs

//TA0CCTL1 = CM_2 | CCIS_0 | SCS | CAP | OUTMOD_0 | CCIE;
//Keep in mind that It should not be configured as campture mode

TA1CCTL1 |= CM_2 | CCIS_0 | SCS | OUTMOD_0 | CCIE;

TA1CTL = TASSEL_2 + MC_1 + ID_0; // Register TA0CTL -> SMCLK/1, Up mode

do{

while ((TA1CCTL0 & CCIFG) == 0 ) // wait while CCIF is set
{
}

**TA1CCTL0 &= ~CCIFG; // Clear the flag** (%1%)
//TA1CTL &= ~TAIFG; // Clear the flag
i++;
} while( i<8) ;

TA1CTL = TACLR; // Stop the Timer
TA1CCTL1 = 0x00;

}

void Configure_CCI1A(void)
{

// Configuring P2.1 as TA1.CCI1A

P2OUT &= 0x00; // Clearing P1OUT
P2DIR &= ~BIT1 ; // Configuring P1.2 as input
P2SEL |= BIT1 ; // P2.1 Timer1_A, capture: CCI1A input, compare: Out1 output
P2SEL2 &= ~BIT1 ;


}


void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;

P1OUT &= 0x00; // Clearing P1OUT
P1DIR |= BIT0 ; // Configuring P1.0 as Output

__enable_interrupt();

Configure_CCI1A();
Read();

**P1OUT ^= BIT0;** //(%2%)


while(1) {

}
}


// Timer A1 interrupt service routine
#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer1_A1 (void)
{

P1OUT ^= BIT0; // To show Read occured

word <<=1; // If x = 00000010 (binary) => x <<= 2; => x=00001000
temp=0x00;
temp=((TA1CCTL1 & SCCI)>>10);
**word = word + temp ;** //(%3%)

}

但问题是,当我调用该函数时,它似乎有些卡住了。我猜它并没有完全从 ISR 中出来,尽管当我在调试器中一次运行一条指令时它完成了所有的执行。为了让我的问题清楚,这就是我测试的方式:

假设如果我在 ISR 中的突出显示表达式 (%3%) 处放置切换断点,那么它进入 ISR 时会点击切换断点 8 次,捕获正确的值并巧妙地从读取函数中出来(并且

while ((TA1CCTL0 & CCIFG) == 0 ) // wait while CCIF is set
{
} 

and

{

....

....

i++;

} while( i<8) ;

超出上述循环)

, 在电源中达到 while(1) 表达式。

但是,如果我将切换点放在突出显示的表达式 (%1%) 上,它就会出现卡住。或者,如果我将切换断点直接放在我期望的 main 中的 (%2%) 处,它会完成读取功能,将值存储在 word 变量中以达到切换断点,但代码似乎卡住并且没有命中切换中断。

我不知道是什么问题,有人可以帮忙吗?

4

1 回答 1

3

当您读取 TAIV 或您在 TACCTL1 中手动清除它时,中断标志会自动清除。但是,您在 ISR 中均未执行这些操作,因此中断仍处于挂起状态,并且您的 CPU 不断执行您的 ISR 而没有其他代码,因此它永远没有机会退出Read()

我的猜测是,通过在 ISR 中设置断点,您的开发环境会导致读取 TAIV 并清除挂起的中断。我以前经历过,但不确定这种行为有多普遍,因为它是不可取的。

于 2012-07-28T21:10:54.533 回答