Здравствуйте.
Я пытаюсь мерить частоту с помощью таймера А.
На вход таймера я подаю искомую чатоту - для примера SMCLK или ACLK.
На вход захвата TACCR0 подаю сигнал с частотой 42,3 ( 128/3 ) Hz.
В первом прерывании по захвату я сохраняю захваченное значение.
По истечении 64 прерываний я снова читаю захваченное значение
Нахожу разность с сохраненным - это количество входных
импульсов за 3/128*64 Sec. На основании этого делением
расчитываю частоту. При бездействии ухожу в lpm0.
Если входная частота есть - то все меряется как следует.
А вот если входная частота отсутствует - то не происходит вызова
прерывания по CCR0 - Контроллер как бы подвисает.
Вот исходный код - если тактировать от ACLK без кварца(закомментарено) - то 0 частота не меряется.
Код
LONG TimerSavedValue;
WORD Capt0SavedCount;
WORD CurrentHiTimer;
WORD Capt0Count;
LONG CountFromPrevTime;
void main()
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= LCD_CLK|LCD_DI; // Set P1.0 to output direction
P2DIR |= LCD_POWER;
P2OUT |= LCD_POWER; // LCD Power on
P1OUT &= ~(LCD_CLK|LCD_DI);
P1SEL = CLOCK42HZ; // P1.1 to timer
DCOCTL = DCO0|DCO1|DCO2;
TACCTL0 = CM1|CAP|CCIE; // Capture on_falling CCI0A interrupts
// Clock from SMCLK - measure frenq of DCO - must use LPM1 for active DCO
TACTL = TASSEL1|MC1|TAIE|TACLR; //SMCLK Continuous interrupt_on_overflow clear
//TACTL = TASSEL0|MC1|TAIE|TACLR; //ACLK Continuous interrupt_on_overflow clear
_EINT();
do
{
_BIS_SR(LPM0_bits); /* Wait end of measure */
_NOP();
{
FLOAT F;
F = CountFromPrevTime * 128.0 / 3 /Capt0SavedCount;
DisplayFloat(F);
if ( (BUTTON_POWER & P1IN) == 0 )
{
DCOCTL = DCOCTL + DCO0;
if ( DCOCTL == 0 )
{
BCSCTL1 = (BCSCTL1&~(RSEL0|RSEL1|RSEL2)) + ((BCSCTL1+RSEL0)&(RSEL0|RSEL1|RSEL2));
}
}
}
}while(1);
}
static WORD GetHiTAWord(WORD TACaptValue)
{
WORD RetVal = CurrentHiTimer;
if ( (SWORD)TACaptValue > 0 && ( (TACTL & TAIFG) ) )
{
RetVal++; /* Correct TA owerflow if need */
}
return RetVal;
}
/* Owerflow TA ISR */
#if !defined(__GNUC__)
interrupt [TIMERA1_VECTOR] void TAOwerflow(void)
#else
interrupt (TIMERA1_VECTOR) TAOwerflow(void)
#endif
{
if ( TAIV ) // Pseudo Reading TAIV !!!!
CurrentHiTimer++;
}
/* CCR0 capture vector */
#if !defined(__GNUC__)
interrupt [TIMERA0_VECTOR] void TACapture(void)
#else
interrupt (TIMERA0_VECTOR) TACapture(void)
#endif
{
Capt0Count++;
if ( Capt0Count >= 64 )
{
t_Timer Value;
Value.Word[LO] = TACCR0;
Value.Word[HI] = GetHiTAWord( Value.Word[LO] );
// Calculate tick count from prev time
CountFromPrevTime = Value.Long - TimerSavedValue;
// Save previon value
TimerSavedValue = Value.Long;
// Save time measure interval ticks.
Capt0SavedCount = Capt0Count;
Capt0Count = 0;
_BIC_SR_IRQ(LPM4_bits); /* Exit from all LPM */
}
}