Galizin 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба Здравствуйте. Я пытаюсь мерить частоту с помощью таймера А. На вход таймера я подаю искомую чатоту - для примера 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 */ } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CSB 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба На сколько я понял, вы работаете с 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? Если нет захвата - нет и прерывания от него. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Galizin 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 · Жалоба На сколько я понял, вы работаете с 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. На то он и асинхронный режим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CSB 0 13 ноября, 2007 Опубликовано 13 ноября, 2007 (изменено) · Жалоба Есть макросы СМ_0, СМ_1 и т.д., а есть СМ0 и СМ0. Я не заметил что Вы использовали макрос без подчеркивания. Как А вот если входная частота отсутствует - то не происходит вызова прерывания по CCR0 - Контроллер как бы подвисает. Вот исходный код - если тактировать от ACLK без кварца(закомментарено) - то 0 частота не меряется. соотнести с Но частота то на CCI есть. ?!! CCI - бит, а частота по всей видимости у вас на ножке CCI0A. Видимо я не так понял Вас. А если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан? Как то криво получается. Я полагал что такое получается только в случае синхронной работы захвата. А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от тактирвоания TA. На то он и асинхронный режим Я могу ошибаться, но вроде-бы было какое-то ограничение на входную частоту - я мог спутать 430 и авр. Если найду что-то конкретное - напишу. >если частота CCI превышает чатоту таймера - эначит не каждый спад CCI будет распознан Пологаю это так и есть. >А в асинхрнном режиме флаг прерывания выставляетс я асинхронно и независимо от тактирвоания TA. Если на вход подать частоту, намного превышающую ту которая тактирует таймер, то схема захвата просто не отловит все фронты сигнала. Например, за один полупериод у Вас пришло 10 задних фронтов входного сигнала. Какое значение записать в регистр захвата? Все это мое скромное и личное имхо. возможно я где-то ошибся. Есть бит переполнения захвата, если произошел второй захват перед прочтением первого. Изменено 13 ноября, 2007 пользователем CSB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться