Перейти к содержанию
    

Прерывания TimerA

Здравствуйте.

 

Я пытаюсь мерить частоту с помощью таймера А.

На вход таймера я подаю искомую чатоту - для примера 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 */    
  }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сколько я понял, вы работаете с DCO. Но таймер тактируется от ACLK вместо SMCLK.

// Clock from SMCLK - measure frenq of DCO - must use LPM1 for active DCO

TACTL = TASSEL1|MC1|TAIE|TACLR; //SMCLK Continuous interrupt_on_overflow clear

 

TASSEL1 следует поменять на TASSEL2.

 

TACCTL0 = CM1|CAP|CCIE; // Capture on_falling CCI0A interrupts

захват будет по переднему фронту, а не по заднему как Вы написали.

 

А вот если входная частота отсутствует - то не происходит вызова

прерывания по CCR0 - Контроллер как бы подвисает.

Если нет входной частоты, то кто же выведет контроллер из режима lpm0? Если нет захвата - нет и прерывания от него.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сколько я понял, вы работаете с DCO. Но таймер тактируется от ACLK вместо SMCLK.

TASSEL1 следует поменять на TASSEL2.

Да таймер тактируется с ACLK - это место в коде закомментарено.

TASSEL2 в msp430f1121 не используется. Обозначен как unused bite

 

TACCTL0 = CM1|CAP|CCIE; // Capture on_falling CCI0A interrupts

захват будет по переднему фронту, а не по заднему как Вы написали.

slau049.pdf

описание TACTLx

10 Capture on falling edge

То есть если первый бит установлен - то по спаду. Есть всего два макроса для CM - CM1 и CM0

предполагаю, что CM1 является более старшим битом.

 

Если нет входной частоты, то кто же выведет контроллер из режима lpm0? Если нет захвата - нет и прерывания от него.

Но частота то на CCI есть. Синхронный режим не включен - сам CCI мог бы и тактировать.

А если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан?

Как то криво получается. Я полагал что такое получается только в случае синхронной работы

захвата. А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от

тактирвоания TA. На то он и асинхронный режим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть макросы СМ_0, СМ_1 и т.д., а есть СМ0 и СМ0. Я не заметил что Вы использовали макрос без подчеркивания.

 

Как

А вот если входная частота отсутствует - то не происходит вызова

прерывания по CCR0 - Контроллер как бы подвисает.

Вот исходный код - если тактировать от ACLK без кварца(закомментарено) - то 0 частота не меряется.

соотнести с

Но частота то на CCI есть.
?!!

CCI - бит, а частота по всей видимости у вас на ножке CCI0A. Видимо я не так понял Вас.

 

А если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан?

Как то криво получается. Я полагал что такое получается только в случае синхронной работы

захвата. А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от

тактирвоания TA. На то он и асинхронный режим

Я могу ошибаться, но вроде-бы было какое-то ограничение на входную частоту - я мог спутать 430 и авр. Если найду что-то конкретное - напишу.

 

 

>если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан

Пологаю это так и есть.

 

>А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от

тактирвоания TA.

Если на вход подать частоту, намного превышающую ту которая тактирует таймер, то схема захвата просто не отловит все фронты сигнала. Например, за один полупериод у Вас пришло 10 задних фронтов входного сигнала. Какое значение записать в регистр захвата? Все это мое скромное и личное имхо. возможно я где-то ошибся.

 

 

Есть бит переполнения захвата, если произошел второй захват перед прочтением первого.

Изменено пользователем CSB

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...