Quiero usar un microcontrolador y un convertidor A/D para realizar un registro de datos de alta frecuencia (~100 kHz) a largo plazo (mínimo de cinco segundos de búfer, en bucle hasta que se active). Parece que una buena forma de hacerlo es con una tarjeta SD. Sé que hay diferentes formas de acceder a una tarjeta SD, incluso directamente a través de SPI. También creo que se puede escribir en un sistema de archivos o directamente en la tarjeta sin un sistema de archivos. También me preocupa que las escrituras tengan que cubrir sectores completos en lugar de byte por byte, o que las escrituras interfieran con la operación continua de A/D, pero es posible que esas no sean preocupaciones válidas.
Actualmente estoy usando chips dsPIC 33, lo que me da velocidades de instrucción de ~60 MIPS; Estoy dispuesto a cambiar a una familia de controladores diferente si es necesario.
Es posible que no pueda hacer esto con un PIC33, y casi seguro que no con cualquier PIC33. Algunas tarjetas flash 'desaparecen' durante largos períodos de tiempo (decenas de milisegundos o más) a pesar del alto rendimiento, esta latencia puede matarlo con un pequeño microcontrolador porque se quedará sin memoria RAM.
Si permite el almacenamiento en búfer durante 200 ms (lo que debería ser seguro), necesitará 20 000 palabras de memoria, que es posible que un PIC33 no tenga (los miembros más grandes de la familia tienen 48 000 x 8, por lo que si su ADC toma dos bytes, son 40 000, y presumiblemente su programa necesita algo de RAM.
A 100,000 muestras/segundo, tampoco podrá procesar mucho los datos, solo tómelos. Sugiero usar RAM. Y tendría potencia de procesamiento de sobra si usara un ARM con una SDRAM externa o incluso una RAM en serie.
He hecho esto antes, pero no recuerdo todos los detalles. Usé el sistema de archivos Fat y hubo algún tipo de enfoque diferente, solía transferir un bloque de datos de 512 bytes. Pero puedo decirle lo que necesita con seguridad: un búfer circular, el mío era de 16k bytes. Cuando muestrea en ISR, escribe en un búfer y luego incrementa el puntero de escritura, cuando la diferencia entre el puntero wr y el rd supera los 512 bytes, escribe esos bytes en una SD e incrementa el puntero rd. De todos modos, esto es antiguo, sin uso de transferencia DMA, solo un ejemplo. Al crear el búfer curcular, use el tamaño del búfer con potencia de 2, busque las matemáticas que se usan con los punteros rd y wr, se simplifica gracias a la propiedad de transferencia de números binarios, en cualquier cálculo necesita aplicar máscara: & ( tamaño-1) que es 2^N-1, en mi caso N=14 -> tamaño del búfer circular=2^14=16384.
void AddBuffer (char data)
{
CircBuffer[WR_Pointer]=data;
WR_Pointer++;
WR_Pointer= WR_Pointer & 16383;
if (WR_Pointer==RD_Pointer)
{
printf("\r\nBuffer overrun\r\n",0);
stat0_off();
stat1_on();
VICIntEnClr = 0xFFFFFFFF; //clear all interrupts
fat_flush();
while(1);
}
}
char GetBuffer()
{
char res;
if (WR_Pointer==RD_Pointer)
{
res=0; // no data available
printf("\r\nError calling GetBuffer()\r\n",0);
stat0_off();
stat1_on();
VICIntEnClr = 0xFFFFFFFF; //clear all interrupts
fat_flush();
while(1);
}
else
{
res=CircBuffer[RD_Pointer];
RD_Pointer++;
RD_Pointer=RD_Pointer & 16383;
}
return(res);
}
void SD_Card_Log(void)
{
int j;
BufferLength = WR_Pointer-RD_Pointer;
BufferLength = BufferLength & 16383;
if (BufferLength>=512)
{
for (j = 0; j < 512; j++) {
RX_array1[j] = GetBuffer();
}
stat0_off();
stat1_off();
if (fat_write(handle,RX_array1, 512) < 0)
{
while(1) // card failure
{
}
}
tubo
Eugenio Sh.
Asmyldof
semaj
Esteban Collings