Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Измерение частоты
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
A R T
Доброго времени суток ВСЕМЪ!!!

Измеряю частоту синусоидального сигнала в диапазоне от 20 до 50Гц. Периодически (примерно один раз на пять замеров) происходит ошибка измерения (отклонение от реальной в 2…3 раза в обе стороны!!!).
Инициализация, обработка препывания и расчет частоты приведены ниже:

void timera_init()
//Clock source=ACLK
//Divider=1
//TIMACLK=32,768KHz
//Frequency=258,0Hz ( 3,88mS)
{
TACTL=0x00; //stop timer
//channel0
TACCTL0=0x00;
TACCR0=0x7F;
//channel1
TACCTL1=0x64;//TAOM1.1,TAOM1.0,TAOUT1
TACCR1=0x7F;
//channel2
TACCTL2=0x4110;//TASCS2,TACAP2,TACCIE2
TACCR2=0x00;

TAR=0x0000;//clear timer counter
TACTL=0x116;//TASSEL.0,TAMC.0,1,TAIE
}

#pragma vector=TIMERA1_VECTOR
__interrupt void ta_interrupt_routine(void)
{
if(TACTL&TAIFG)//Если таймер досчитал до 125
{
fTimeCounter++;//инкрементируем счетчик таймера.
TACTL&=~TAIFG;//Чистим флаг!
}

if(TACCTL2&CCIFG)//Если фронт сигнала,
{
fTime=fTimeCounter;//снимаем количество переполнений ТА.
fTime0=fTime1;//состояние ТА на начало процесса.
fTime1=TACCR2;//состояние ТА на конец процесса.
fTimeCounter=0;//обнуляем счетчик переполнений ТА.
TACCTL2&=~CCIFG;//Чистим флаг!
}
}

void main(void)
{

//Определяем частоту:
float fFreq=1/(2*(fTime*3.90625e-3+(fTime1-fTime0)*30.517578125e-6));

}

Также имеются прерывания ADC (неповторяющаяся последовательность каналов, в прерывании перезапуск).

Реализую на MSP430F1122. Тактируюсь от часового кварца (32768Гц). Частота тактирования стабильная.

Пожалуйста посоветуйте, что можно предпринят.

Зарание спасибо всем ответившим!!!
Сергей Борщ
Цитата(A R T @ Feb 14 2007, 09:50) *
#pragma vector=TIMERA1_VECTOR
__interrupt void ta_interrupt_routine(void)
{
if(TACTL&TAIFG)//Если таймер досчитал до 125
{
fTimeCounter++;//инкрементируем счетчик таймера.
TACTL&=~TAIFG;//Чистим флаг!
}

if(TACCTL2&CCIFG)//Если фронт сигнала,
{
fTime=fTimeCounter;//снимаем количество переполнений ТА.
fTime0=fTime1;//состояние ТА на начало процесса.
fTime1=TACCR2;//состояние ТА на конец процесса.
fTimeCounter=0;//обнуляем счетчик переполнений ТА.
TACCTL2&=~CCIFG;//Чистим флаг!
}
}
Первое, что бросилось в глаза: не нужно принудительно чистить чистить флаги, но обязательно нужно читать TAIV:
Код
__interrupt void ta_interrupt_routine(void)
{
    unsigned TAIVcopy=TAIV;
    switch(TAIVcopy)
    {
        case 2:    /* CCP1 */
            ............................
        break;
        case 4:    /* CCP2 */
            ............................
        break;
    }
}
И второе - вы запрещаете прерывания на момент вычисления float fFreq=1/(2*(fTime*3.90625e-3+(fTime1-fTime0)*30.517578125e-6));?
Вот, посмотрите, аналогичный случай рассматривался: http://electronix.ru/forum/index.php?s=&am...st&p=199921
A R T
Здравствуйте, Сергей!
Спасибо за участие и дельные советы!!!

Зарелизил обработку прерывания ТА1, как Вы предложили. Теперь выглядит так:
Код
#pragma vector=TIMERA1_VECTOR
__interrupt void ta_interrupt_routine(void)
{
  unsigned uTAIVcopy=TAIV;
  switch(uTAIVcopy)
  {
  case 0x04:
    fTime=fTimeCounter;
    fTimeCounter=0;//обнуляем счетчик таймера.
    fTime0=fTime1;
    fTime1=TACCR2;
    cFreqFalse++;//Задержка для выравнивания fTime,fTime0,fTime1.
    break;
  case 0x0a:
    fTimeCounter++;//инкрементируем счетчик таймера.
  default:
    _NOP();
  }
}


Расчет частоты сделал так:
Код
void main(void)
{

  //Определяем частоту:
  if(cFreqFalse>3) //Задержка для выравнивания fTime,fTime0,fTime1.
  {
    _DINT();
    fFreq=1/(2*(fTime*3.90625e-3+(fTime1-fTime0)*30.517578125e-6));
    cFreqFalse=0;
    _EINT();
  }

}


Ошики стали появляться реже…

Поставил точку останова после расчета частоты и при 50Гц их вообще не обнаружил, однако в реальном времени ошибки периодически случаются (всмысле при 50Гц). На частоте 20Гц ошибки появляются ~2...3 через 5…7 отсчетов. Т.е. при снижении частоты ошибки появляются чаще…

Что еще можно сделать???
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.