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

 
 
> PIT в at91sam7s256, Работа по прерываниям
mempfis_
сообщение Mar 25 2010, 14:52
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Из работающего атмеловского примера выделил код настройки AIC и PIT для организации работы по прерываниям.
Собственно ниже то что получилось.

CODE


void IRQ_ConfigureIT(unsigned int source, unsigned int mode, void( *handler )( void ))
{
// Disable the interrupt first
AT91C_BASE_AIC->AIC_IDCR = 1 << source;

// Configure mode and handler
AT91C_BASE_AIC->AIC_SMR[source] = mode;
AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;

// Clear interrupt
AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}

//------------------------------------------------------------------------------
/// Enables interrupts coming from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void IRQ_EnableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IECR = 1 << source;
}

//------------------------------------------------------------------------------
/// Disables interrupts coming from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void IRQ_DisableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IDCR = 1 << source;
}


//------------------------------------------------------------------------------
void PIT_Init(unsigned int period, unsigned int pit_frequency)
{
AT91C_BASE_PITC->PITC_PIMR = period? (period * pit_frequency + 8) >> 4 : 0;
AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
}

//------------------------------------------------------------------------------
/// Set the Periodic Interval Value of the PIT.
/// \param piv PIV value to set.
//------------------------------------------------------------------------------
void PIT_SetPIV(unsigned int piv)
{
AT91C_BASE_PITC->PITC_PIMR = (AT91C_BASE_PITC->PITC_PIMR & AT91C_PITC_PIV)
| piv;
}

//------------------------------------------------------------------------------
/// Enables the PIT if this is not already the case.
//------------------------------------------------------------------------------
void PIT_Enable(void)
{
AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
}

//----------------------------------------------------------------------------
/// Enable the PIT periodic interrupt.
//----------------------------------------------------------------------------
void PIT_EnableIT(void)
{
AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;
}

//------------------------------------------------------------------------------
/// Disables the PIT periodic interrupt.
//------------------------------------------------------------------------------
void PIT_DisableIT(void)
{
AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN;
}

//------------------------------------------------------------------------------
/// Returns the value of the PIT mode register.
/// \return PIT_MR value.
//------------------------------------------------------------------------------
unsigned int PIT_GetMode(void)
{
return AT91C_BASE_PITC->PITC_PIMR;
}

//------------------------------------------------------------------------------
/// Returns the value of the PIT status register, clearing it as a side effect.
/// \return PIT_SR value.
//------------------------------------------------------------------------------
unsigned int PIT_GetStatus(void)
{
return AT91C_BASE_PITC->PITC_PISR;
}

//------------------------------------------------------------------------------
/// Returns the value of the PIT Image Register, to read PICNT and CPIV without
/// clearing the current values.
/// \return PIT_PIIR value.
//------------------------------------------------------------------------------
unsigned int PIT_GetPIIR(void)
{
return AT91C_BASE_PITC->PITC_PIIR;
}

//------------------------------------------------------------------------------
/// Returns the value of the PIT Value Register, clearing it as a side effect.
/// \return PIT_PIVR value.
//------------------------------------------------------------------------------
unsigned int PIT_GetPIVR(void)
{
return AT91C_BASE_PITC->PITC_PIVR;
}

//------------------------------------------------------------------------------
/// Handler for PIT interrupt. Increments the timestamp counter.
//------------------------------------------------------------------------------

void ISR_Pit(void)
{
unsigned int status;

// Read the PIT status register
status = PIT_GetStatus() & AT91C_PITC_PITS;
if (status != 0) {
// 1 = The Periodic Interval timer has reached PIV since the last read of PIT_PIVR.
// Read the PIVR to acknowledge interrupt and get number of ticks
//Returns the number of occurrences of periodic intervals since the last read of PIT_PIVR.
timestamp += (PIT_GetPIVR() >> 20);
}
}

//------------------------------------------------------------------------------
/// Configure the periodic interval timer (PIT) to generate an interrupt every
/// millisecond.
//------------------------------------------------------------------------------
void ConfigurePit(void)
{
// Initialize the PIT to the desired frequency
PIT_Init(PIT_PERIOD, BOARD_MCK / 1000000);

// Configure interrupt on PIT
IRQ_DisableIT(AT91C_ID_SYS);
IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);
IRQ_EnableIT(AT91C_ID_SYS);
PIT_EnableIT();

// Enable the pit
PIT_Enable();
}


void main(void)
{
//разрешение тактирования pio
AT91C_BASE_PMC->PMC_PCER = (1ul<<AT91C_ID_PIOA)|(1ul<<AT91C_ID_SYS)|(1ul<<AT91C_ID_FIQ);

//попытка настройки gpio
AT91C_BASE_PIOA->PIO_OER = (1ul<<3)|(1ul<<2)|(1ul<<1)|(1ul<<0);
AT91C_BASE_PIOA->PIO_SODR = (1ul<<3)|(1ul<<2)|(1ul<<1)|(1ul<<0);

//настройка PIT, 1mС, установлено прерывание
ConfigurePit();

long status=0;

for(;;)
{
static long timer=1000000;
if(timer > 0) timer--;
else
{
timer=1000000;

if(status == 0)
{
//устанавливаем ножку
AT91C_BASE_PIOA->PIO_SODR = (1ul<<3)|(1ul<<2)|(1ul<<1)|(1ul<<0);
status = 1;
}
else
{
//сбрасываем ножку
AT91C_BASE_PIOA->PIO_CODR = (1ul<<3)|(1ul<<2)|(1ul<<1)|(1ul<<0);
status = 0;
}
}
}



Код в основном цикле использую для того чтобы убедится что процессор работает. Точнее он работает если в ConfigurePIT() закоментировать разрешение прерывания PIT PIT_EnableIT(). Отличие моего проекта от атмеловского в том что я пытаюсь настроить только одно прерывание а там учавствуют несколько (от таймера, PIO).
Думал что проблема могла быть в том что не подключил тактирование AIC. На всякий случай ввёл
Код
AT91C_BASE_PMC->PMC_PCER = (1ul<<AT91C_ID_PIOA)|(1ul<<AT91C_ID_SYS)|(1ul<<AT91C_ID_FIQ);

Не помогло. Вероятно я чтото упускаю в коде или настройках.

P.S. Вопрос на засыпку - у меня тактовая частота процессора 48MHz (планируется использование USB). И при этом исполняю код только из flash. Не слишком ли это высокая частота?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 11:09
Рейтинг@Mail.ru


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