Estoy usando LPC1788 MCU con el compilador KeilV5.
Tengo un temporizador ISR en el que leo un valor de un canal ADC específico y lo escribo en una tarjeta SD usando la biblioteca FATFS.
Aquí está mi código ISR del temporizador:
void TIMER1_IRQHandler(void){
if (TIM_GetIntStatus(LPC_TIM1, TIM_MR1_INT)== SET){
ADC_Init(LPC_ADC,838);
ADC_ChannelCmd (LPC_ADC,0,ENABLE);
while (!(ADC_ChannelGetStatus(LPC_ADC,0, ADC_DATA_DONE)));
ADCResult = ADC_ChannelGetData(LPC_ADC,0);
sprintf(OutputSample,"%ld\r\n",ADCResultScaled);
f_lseek(&File1, f_size(&File1));
//f_write(&File1,OutputSample,strlen(OutputSample), &FilePointer);
Counter++;
TIM_ClearIntPending(LPC_TIM1, TIM_MR1_INT);
}
}
No hay ningún problema con el código anterior, pero cuando elimino el signo de comentario de la función f_write, el programa se detiene y nada se ejecuta exactamente después de que se habilita el temporizador 1. (referido a la depuración, después de ejecutar TIM_Cmd(LPC_TIM1, ENABLE) en la función principal)
Entonces no puedo escribir los datos en la tarjeta SD en el ISR de Timer.
Debo mencionar que la función f_write funciona bien fuera del Timer ISR.
¿Puedes adivinar dónde está el problema?
Gracias de antemano.
Por lo general, es una muy, muy mala idea usar FatFS de las interrupciones. El patrón más común es adquirir los datos en el ISR, almacenarlos en algún lugar y tener una tarea de ciclo principal que almacene los datos en cola en algún lugar.
Si su controlador SPI usa interrupciones y no habilita las interrupciones anidadas (tema avanzado), entonces sus interrupciones SPI no se ejecutarán hasta que finalice la interrupción del temporizador.
+1 para @filo, quien abordó correctamente el problema de las interrupciones anidadas que no están habilitadas (o tienen la misma prioridad, por lo tanto, no se activan).
Sin embargo, el problema no está en el SPI (que normalmente no se usa con la interrupción en FatFS, a menos que se realicen algunas modificaciones importantes en el código. El SPI se usa en el sondeo, con las funciones y xmit_spi()
) xmit_spi_multi()
.
El problema radica en el disk_timerproc()
, que debe llamarse (con una interrupción) cada ms, para tiempos de espera y para actualizar el estado de la tarjeta (tarjeta insertada, protegida contra escritura, etc.).
En el ejemplo LPC17xx, disk_timerproc()
es llamado por SysTick_Handler()
.
Tienes por tanto dos caminos:
Por ejemplo
volatile dataAvailable = 0;
[...] other code[...]
void main (void)
{
[...] other code [...]
while (1)
{
[...] other code [...]
if (dataAvailable)
{
dataAvailable = 0;
saveData();
}
}
}
void TIMER1_IRQHandler(void)
{
if (TIM_GetIntStatus(LPC_TIM1, TIM_MR1_INT)== SET)
{
[...] other code [...]
dataAvailable = 1;
TIM_ClearIntPending(LPC_TIM1, TIM_MR1_INT);
}
}
turbo j