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

 
 
> Измерить частоту таймером at91sam7, Выходит что-то не то
Glide
сообщение Jun 24 2008, 08:21
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 18
Регистрация: 20-01-05
Пользователь №: 2 078



День добрый! Подскажите, пожалуйста, где я не прав. at91sam7x256.

Задумка: с помощью ТС0 в режиме capture измерять частоту со входа TIOA0 (частота порядка 1000 - 4000 Гц). Сам TC0 должен тактироваться MCK/128.

Реально же получается, будто TC0 тактируется частотой, близкой к MCK/228 (судя по частоте с генератора и получаемым в *m_ValPtr значениям). Причём наблюдаю ещё один непонятный эффект: нелинейность измеренного значения частоты, процентов 10-15.

Так инициализирую:

Код
    // BSP_CPU_ClkFreq()  даёт частоту MCK в кГц
    m_SomeCoeff = ( (BSP_CPU_ClkFreq() *1000) / 128); // Более-менее реальные показания удаётся получить, если 128 заменить на 228

    m_TimerID = AT91C_ID_TC0;
    m_TC      = AT91C_BASE_TC0;

    //Timer configuration
    AT91C_BASE_PMC->PMC_PCER              =  (1 << m_TimerID);     /* Enable the peripheral clk */
    AT91C_BASE_TCB->TCB_TC0.TC_CCR       =  AT91C_TC_CLKDIS;            /* TC0 timer disabled */
    
    m_TC->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK |   // ~48MHz/128
                    AT91C_TC_ETRGEDG_FALLING |                           // Triggers on falling edge
                    AT91C_TC_ABETRG |                                           // Use TIOA0 as external trigger
                    AT91C_TC_LDRA_RISING;                           // Load RA on RISING edge of TIOA0

    AT91C_BASE_TCB->TCB_TC0.TC_CCR       =  AT91C_TC_CLKEN;           /* TC0 timer enabled        */
    AT91C_BASE_TCB->TCB_TC0.TC_CCR       =  AT91C_TC_SWTRG;          /* SWTRG to reset and start */

    //AIC configuration
    AT91C_BASE_AIC->AIC_SVR[m_TimerID]    = (INT32U)TachoSensor::ISR_Handler;
    AT91C_BASE_AIC->AIC_SMR[m_TimerID]    = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL    
                                            | AT91C_AIC_PRIOR_LOWEST;

    AT91C_BASE_AIC->AIC_ICCR              = 1 << m_TimerID;
    AT91C_BASE_AIC->AIC_IECR              = 1 << m_TimerID;
    
    m_TC->TC_IER = AT91C_TC_COVFS |                     //Enable Counter Overflow interrupt
                    AT91C_TC_LDRAS;// |                    //Enable RA loading int.

    m_TC->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;


А так обрабатываю прерывания:

Код
void  TachoSensor::ISR_Handler   ()
{
    AT91C_BASE_AIC->AIC_IVR   = 0;

    unsigned int Status = m_TC->TC_SR;

    if (Status & AT91C_TC_COVFS)
    {
        OvfCnt = true;
        *m_ValPtr =  0; //  Считаем, что 0 (несущественная)
    }

    if (Status & AT91C_TC_LDRAS)
    {
        m_PrevVal = m_CurrVal;
        m_CurrVal = AT91C_BASE_TC0->TC_RA;

        if (OvfCnt)
        {
            OvfCnt = false;
            *m_ValPtr =  0;  //  Считаем, что 0 (несущественная)
        }
        else
        {
            if ( m_CurrVal != 0 )
            {
                *m_ValPtr = m_SomeCoeff / m_CurrVal;
            }
        }
    }

    AT91C_BASE_AIC->AIC_ICCR  = 1 << m_TimerID;
    AT91C_BASE_AIC->AIC_EOICR = 0;                       /* Signal end of interrupt */

} /* TachoSensor::ISR_Handler */
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aaarrr
сообщение Jul 2 2008, 10:41
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Фронты нормальные, не завалены?
Go to the top of the page
 
+Quote Post



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

 


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


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