По даташиту вывод PB14 является PWM0 и TIOA1. Хочу сделать так: PWM0 генерит импульсы, а счетчик TC2 их считает, т.е тактовый сигнал для TC2 является TIOA1. На деле получил: PWM0 генерит пачку импульсов, но таймер не запускается. Если таймер тактировать от внутреннего генератора, то все ок. В чем я ошибаюсь? Исходники привожу: // Обработчик прерывания от таймера2 по сравнению. void timer2_handler(void) { volatile unsigned long dummy; dummy = AT91C_BASE_TC2->TC_SR; if(dummy&0x00000004) { BASE_PIO_LED->PIO_SODR = LED_B;// мыргаю, что мол закончил. AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF; } }
static void configure_tc2(void) { volatile unsigned long dummy;
/* Enable periph clock for the PIO controller */ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC2); /* Enable the periph */ /* Disable the clock and the interrupts */ AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC2->TC_IDR = 0xFFFFFFFF; /* Clear status bit */ dummy = AT91C_BASE_TC2->TC_SR; AT91C_BASE_TCB2->TCB_BMR = 0x00000030; /* Set the Mode of the Timer Counter */ AT91C_BASE_TC2->TC_CMR = 0x00008007;
AT91C_BASE_TC2->TC_RA = 15;
/* Enable interrupts */ /* Disable the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC2); /* Save the interrupt handler routine pointer and the interrupt priority */ AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned long) timer2_handler; /* Store the Source Mode Register */ AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST; /* Clear the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC2);
AT91C_BASE_TC2->TC_IER = AT91C_TC_CPAS;
/* Enable the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC2);
/* Clock is started */ AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN; /* Counter is reset and the clock is started */ AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG; }
void pwmc_handler(void) { unsigned int i; static unsigned int cnt = 0; i = AT91C_BASE_PWMC->PWMC_ISR; /* if (BASE_PIO_LED->PIO_ODSR & LED_B) { BASE_PIO_LED->PIO_CODR = LED_B; } else { BASE_PIO_LED->PIO_SODR = LED_B; }*/ if((++cnt)>=32768){ AT91C_BASE_PWMC->PWMC_IDR = 1; AT91C_BASE_PWMC->PWMC_DIS = 1; cnt = 0; }
}
void configure_pwm(void) { AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PWMC); AT91C_BASE_PIOB->PIO_PDR = (1<<14); // config PB14 AT91C_BASE_PIOB->PIO_BSR = (1<<14); AT91C_BASE_PWMC->PWMC_MR = 0; AT91C_BASE_PWMC_CH0->PWMC_CMR = 0x00000400; AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 120; AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 240;
/* Enable interrupts */ /* Disable the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_PWMC); /* Save the interrupt handler routine pointer and the interrupt priority */ AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PWMC] = (unsigned long) pwmc_handler; /* Store the Source Mode Register */ AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PWMC] = 0x00000026; /* Clear the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_PWMC); AT91C_BASE_PWMC->PWMC_IER = 1; /* Enable the interrupt on the interrupt controller */ AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_PWMC); AT91C_BASE_PWMC->PWMC_ENA = 1; }
int main() { /* === LED configuration (PIO in OUTPUT) === */ configure_leds(); configure_tc2(); configure_pwm(); __enable_interrupt(); while(1); }
|