Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7S256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
hd44780
Здравствуйте.
2 вопроса по AT91SAM7S256.

1. PIT пошёл в общем-то без проблем, но не пойму с какой частотой он прерывания генерит.

CODE

/// PIT period value in µseconds.
#define PIT_PERIOD 1000

//------------------------------------------------------------------------------
/// 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); // Запретить прерывание PIT
// Задать обработчик прерывания PIT
IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);

// Разрешить прерывание PIT
IRQ_EnableIT(AT91C_ID_SYS);
PIT_EnableIT();

// Enable the pit
PIT_Enable();
} // ConfigurePit

//------------------------------------------------------------------------------
/// Handler for PIT interrupt. Increments the timestamp counter.
//------------------------------------------------------------------------------
// 250 mks, 4 kHz - 1 ms
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);

seconds ++; // increment seconds
..........
} // if
} // ISR_Pit

//------------------------------------------------------------------------------
/// Waits for the given number of milliseconds (using the timestamp generated
/// by the SAM7 microcontroller's PIT
/// \param delay Delay to wait for, in milliseconds.
//------------------------------------------------------------------------------
void delay_ms(unsigned long delay)
{
volatile unsigned int start = timestamp;
unsigned int elapsed;
do {
elapsed = timestamp;
elapsed -= start;
}
while (elapsed < delay);
}


delay_ms работает нормально, а в seconds бред собачий... Я наверное не врубился в логику его работы.

2. TC0 . Взял из иаровского примера, не работает вообще
CODE

//------------------------------------------------------------------------------
/// Configure Timer Counter 0 to generate an interrupt every 250ms.
//------------------------------------------------------------------------------
void ConfigureTc(void)
{
unsigned int div;
unsigned int tcclks;

// Enable peripheral clock
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;

// Configure TC for a 4Hz frequency and trigger on RC compare
TC_FindMckDivisor(4, BOARD_MCK, &div, &tcclks);
TC_Configure(AT91C_BASE_TC0, tcclks | AT91C_TC_CPCTRG);
AT91C_BASE_TC0->TC_RC = (BOARD_MCK / div) / 4; // timerFreq / desiredFreq

// Configure and enable interrupt on RC compare
IRQ_ConfigureIT(AT91C_ID_TC0, 0, TC0_IrqHandler);
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
IRQ_EnableIT(AT91C_ID_TC0);
} // ConfigureTc

//------------------------------------------------------------------------------
// Прерывание TC0
//------------------------------------------------------------------------------
void TC0_IrqHandler(void)
{
volatile unsigned int dummy;
// Clear status bit to acknowledge interrupt
dummy = AT91C_BASE_TC0->TC_SR;

// Toggle LED state
LED_Toggle(0);
} // TC0_IrqHandler


Сам по себе LED_Toggle(0); работает. Поверено в PIT.

Полный проект иара прилагаю.
Помогите, кто может пожалуйста. Спасибо.

Дисплей HD44780 работает нормально. Проблем нет biggrin.gif .
mempfis_
В вашем проекте переопределена константа периода PIT
Код
/// PIT period value in µseconds.
#define PIT_PERIOD          1000
//#define PIT_PERIOD          250


т.е. частота должна быть не 4кГц а 1кГц (если входная частота таймера 48МГц)

По поводу ТС0 - примеры в IAR откровенная какашка. Я давно разбирался с ними и уже подзабыл подробности поэтому привожу свой рабочий пример инициализации ТС0 на генерацию прерываний ра в 5 uS
CODE

//--------------------------------------------
//обработчик прерываний 0
__thumb void TC0_ISR(void)
{

unsigned int status;

//читаем статус прерывания
status = AT91C_BASE_TC0->TC_SR;

//проверка совпадения
if(status&AT91C_TC_CPCS)
{
//совпадение
if(tc0_cp_cnt > 0)
{
tc0_cp_cnt--;

if(tc0_cp_cnt == 0)
{
//запрещаем прерывание
AT91C_BASE_TC0->TC_IDR = AT91C_TC_CPCS;
}
}
}

}
//--------------------------------------------


//--------------------------------------------
//настройка timer0
__thumb void ConfigureTC0(void)
{
volatile unsigned int dummy;

// Enable peripheral clock
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;

// Disable TC clock
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;

// Disable interrupts
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;

// Clear status register
dummy = AT91C_BASE_TC0->TC_SR;

// Set mode
//LDRB = AT91C_TC_LDRB_RISING
//LDRA = AT91C_TC_LDRA_RISING
//WAVE = 0, capture mode
//CPCTRG = 0
//ABETRG - TIOB external trigger
//ETRGEDG = AT91C_TC_EEVTEDG_RISING
//LDBDIS = 0, Counter clock is not disabled when RB loading occurs.
//BURST = 0
//CLKI = 0, без инверсии клока
//BOARD_MCK/1024
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CPCTRG | AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
AT91C_BASE_TC0->TC_RC = 120;// 48000000;// 12;

//инсталяция прерываний в AIC
IRQ_DisableIT(AT91C_ID_TC0);
IRQ_ConfigureIT(AT91C_ID_TC0, 1, TC0_ISR);
IRQ_EnableIT(AT91C_ID_TC0);

//разрешаем прерывание по переполнению счётного регистра и загрузке регистра А
//AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // AT91C_TC_COVFS/*|AT91C_TC_LDRAS|AT91C_TC_LDRBS*/;

//запуск ТС0
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG|AT91C_TC_CLKEN;
}

__thumb void delay_5us(unsigned int temp)
{

//загружаем задержку
tc0_cp_cnt = temp;

//разрешаем прерывание
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;

while(tc0_cp_cnt);

}
//--------------------------------------------


Константа заносимая в регистр RC определяет период прерываний
AT91C_BASE_TC0->TC_RC = 120; //T=(120*2)/48000000 = 5 uS

А вообще достаточно PIT для генерации любых задержек.
Код
volatile unsigned int delay_timer;
void delay_ms(unsigned int delay)
{
delay_timer = delay;

while(delay_timer);
}

в обработчик прерывания PIT внесите строку
unsigned int  pivr_val = (PIT_GetPIVR() >> 20); //кол-во пропущенных милисекундных прерываний
timestamp += pivr_val;
if(delay_timer > 0)
{
if(delay_timer >= pivr_val)  delay_timer -= pivr_val;
else delay_timer = 0;
}
hd44780
Цитата(mempfis_ @ Aug 24 2012, 17:33) *
т.е. частота должна быть не 4кГц а 1кГц (если входная частота таймера 48МГц)


Да так вроде есть, я кажется понял, в чём ошибся, но ещё не проверил sad.gif .

Цитата(mempfis_ @ Aug 24 2012, 17:33) *
По поводу ТС0 - примеры в IAR откровенная какашка.


laughing.gif
Я работу с таймером списывал из примера basic-usart-hw-handshaking-project, сейчас вижу, что у них там команда
//запуск ТС0
AT91C_BASE_TC0->TC_CCR = .... | AT91C_TC_CLKEN;
пропущена. Может ещё что ... Кстати в getting-started-project она есть sm.gif .

Цитата(mempfis_ @ Aug 24 2012, 17:33) *
привожу свой рабочий пример инициализации ТС0 на генерацию прерываний ра в 5 uS


Да, спасибо огромное, получилось. Я про AT91C_TC_CLKEN забыл biggrin.gif .

PIT мне 1 мс даёт для задержек. Другого пока не надо. Я им ещё ради примера 2 кГц на пине сгенерировал. Оциллографом глядел - нормально.

PS. Вообще хочу FFT анализатор спектра звука (как в винампе) сделать. Вот таймер уже мне около 24 кГц (для оцифровки сигнала) выдал.
Теперь буду с АЦП разбираться. Дисплей цветной от мобилы есть, я с ним на ATMega16А вроде уже разобрался малость biggrin.gif .
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.