Configuración: ATMEL Studio 7, ASF3.47.0, placa de evaluación SAME70 XPlained.
En el ejemplo de trabajo mínimo que se muestra a continuación, utilizo el LED integrado para visualizar si se han ejecutado la activación del temporizador y de la interrupción. Se utiliza PIO_PD20
para comprobar si la interrupción está funcionando. Para ello, simplemente conecté mi sonda de osciloscopio a MISO
en el encabezado de seis pines cerca del centro de la placa. El código a continuación funciona como se espera hasta frecuencias de 2287 Hz. Una vez que elijo frecuencias más altas que eso, la interrupción parece no ser disparada. ¿Qué estoy haciendo mal? Necesito que esto funcione a 100 kHz.
También he utilizado el depurador para avanzar a través de las líneas individuales de código. Un breakpoint en el manejador de TC0 se activa en frecuencias de 2287 Hz o menos. Frecuencias más altas no activan el breakpoint, confirmando que la rutina de interrupción no se ejecuta.
#include
void TC0_Handler(void) {
volatile uint32_t ul_dummy;
pio_set_output(PIOD, PIO_PD20, HIGH, DISABLE, DISABLE);
ul_dummy=TC0->TC_CHANNEL[0].TC_SR; // leer el registro de estado para limpiar la bandera de interrupción.
UNUSED(ul_dummy);
pio_set_output(PIOD, PIO_PD20, LOW, DISABLE, DISABLE);
}
int main (void) {
static uint32_t ul_sysclk, ul_div, ul_tcclks;
uint32_t interrupt_frequency=2287; // en Hz
sysclk_init();
board_init();
pmc_enable_periph_clk(ID_PIOC);
pmc_enable_periph_clk(ID_PIOD);
// Apagar el LED integrado
pio_set_output(PIOC, PIO_PC8, HIGH, DISABLE, DISABLE);
// Configuración del temporizador y la interrupción
ul_sysclk=sysclk_get_cpu_hz();
pmc_enable_periph_clk(ID_TC0);
tc_find_mck_divisor(interrupt_frequency, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk);
tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG);
tc_write_rc(TC0, 0, (ul_sysclk/ul_div)/interrupt_frequency);
NVIC_EnableIRQ((IRQn_Type) ID_TC0);
tc_enable_interrupt(TC0, 0, TC_IER_CPCS);
tc_start(TC0, 0);
// Encender el LED integrado
pio_set_output(PIOC, PIO_PC8, LOW, DISABLE, DISABLE);
while(true){};
}