Мне необходимо сконфигурировать таймер TC0 в режиме генератора, чтобы он выдавал на выводе TIOA тактовый сигнал с частотой 100 кГц. Прерывание должно вызываться при равенстве значения счетчика числу, записаному в регистр RA. Частота синхронизации MCK\8,то есть 48МГц\8 = 6 МГц.
Ниже приведен код инициализирующий таймер. Прерывание вызывается (лампочка моргает), но на выходе TIOA нет тактового сигнала! Тактирование этого таймера в PMC разрешил, в контролере PIO даный вывод также разрешил управлять переферией. Почему нет сигнала?
Структура с настройками таймера
Код
typedef struct _AT91S_MIPS_TIMER {
unsigned int Id;
unsigned short RA_100;
unsigned short RC_100;
unsigned char Div;
} AT91S_MIPS_TIMER, *AT91PS_MIPS_TIMER;
Заполнение полей структуры
Код
#define TC_CLKS_MCK8 0x1
const AT91S_MIPS_TIMER MipsTimer = { AT91C_ID_TC0,30,60,TC_CLKS_MCK8};
Разрешение выхода TIOA таймера TC0 в контроллере PIO
Код
void PIO_ini()
{
regs->PIOA_PER = 0x1;
regs->PIOA_PDR = ~0x1;
regs->PIOA_BSR=0x1;
}
Инициализация таймера TC0
Код
void Init_Mips_Timer()
{
//* Init timer interrupt
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,1 << MipsTimer.Id);
//* Disable the clock and the interrupts
MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;
MipsTimerBase->TC_IDR = 0xFFFFFFFF;
dummy = MipsTimerBase->TC_SR;
//* Suppress warning
dummy=dummy;
//* Set the Mode of the Timer Counter
MipsTimerBase->TC_CMR = AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | MipsTimer.Div;
//* open Timer 0 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, MipsTimer.Id, TIMER_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer0_irq_handler);
MipsTimerBase->TC_IER = AT91C_TC_CPAS; //Enable the RA Compare interrupt
AT91F_AIC_EnableIt (AT91C_BASE_AIC, MipsTimer.Id);
}
Запуск таймера
Код
void Start_Mips_Timer()
{
//* Enable the clock and Start timer
MipsTimerBase->TC_CCR = AT91C_TC_CLKEN;
MipsTimerBase->TC_RA = MipsTimer.RA_100; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = MipsTimer.RC_100;
MipsTimerBase->TC_CCR = AT91C_TC_SWTRG;
}
Обработка прерываний от таймера (при совпадении с RA)
Код
void timer0_irq_handler()
{
//моргание лампочкой
regs->PIOA_ODSR = 0x2;
int ps=100000;
while(ps!=0)ps--;
regs->PIOA_ODSR = 0x0;
dummy=dummy;
}