реклама на сайте
подробности

 
 
> Прерывания TimerA, Если нет TACLK не возникают прерывания захвата
Oleg Galizin
сообщение Nov 13 2007, 09:25
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 25-03-07
Пользователь №: 26 499



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

Я пытаюсь мерить частоту с помощью таймера А.
На вход таймера я подаю искомую чатоту - для примера 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 */    
  }
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
CSB
сообщение Nov 13 2007, 10:12
Сообщение #2


Частый гость
**

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



На сколько я понял, вы работаете с 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? Если нет захвата - нет и прерывания от него.
Go to the top of the page
 
+Quote Post
Oleg Galizin
сообщение Nov 13 2007, 11:07
Сообщение #3





Группа: Участник
Сообщений: 14
Регистрация: 25-03-07
Пользователь №: 26 499



Цитата(CSB @ Nov 13 2007, 13:12) *
На сколько я понял, вы работаете с 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. На то он и асинхронный режим.
Go to the top of the page
 
+Quote Post
CSB
сообщение Nov 13 2007, 12:07
Сообщение #4


Частый гость
**

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



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

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

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

Цитата
А если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан?
Как то криво получается. Я полагал что такое получается только в случае синхронной работы
захвата. А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от
тактирвоания TA. На то он и асинхронный режим

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


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

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


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

Сообщение отредактировал CSB - Nov 13 2007, 12:54
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 14:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01384 секунд с 7
ELECTRONIX ©2004-2016