¿Cómo puedo escribir datos A / D de alta velocidad en una tarjeta SD?

2

Quiero usar un microcontrolador y un convertidor A / D para hacer un registro de datos a largo plazo de alta frecuencia (~ 100 kHz) a largo plazo (mínimo de cinco segundos en el búfer, en bucle hasta que se active). Parece que una buena manera 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 A / D continua, pero pueden no ser preocupaciones válidas.

Actualmente estoy usando chips dsPIC 33, que me dan tasas de instrucción de ~ 60 MIPS; Estoy dispuesto a cambiar a una familia de controladores diferente si es necesario.

    
pregunta Stephen Collings

2 respuestas

4

Es posible que no puedas hacer esto con un PIC33, y es casi seguro que no es solo un 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 matarte con un pequeño microcontrolador porque te quedarás sin memoria RAM.

Si permites el almacenamiento en búfer durante 200 ms (lo que debería ser seguro), necesitarás 20 mil palabras de memoria, que un PIC33 puede no tener (los miembros más grandes de la familia tienen 48 K x 8, por lo que si tu ADC toma dos bytes, eso es 40K y, presumiblemente, su programa necesita algo de RAM.

A 100.000 muestras / segundo, tampoco podrá realizar mucho procesamiento de los datos, solo agárrelos. Yo sugeriría usar RAM. Y tendría capacidad de procesamiento de sobra si usara un ARM con una SDRAM externa o incluso una RAM en serie.

    
respondido por el Spehro Pefhany
0

He hecho esto antes, pero no recuerdo todos los detalles. Usé Fat filesytem y había algún tipo de enfoque diferente, solía transferir un bloque de datos de 512 bytes. Pero puedo decirte lo que necesitas con seguridad: un búfer circular, el mío era de 16k bytes. Cuando muestrea en ISR se escribe en un búfer, luego se incrementa el puntero de escritura, cuando la diferencia entre el puntero de wr y rd excede los 512 bytes, se escriben esos bytes en una SD y el puntero rd de incremento. De todos modos esto es viejo, 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 utilizadas con los punteros rd y wr, se simplifica gracias a la propiedad de la transferencia de números binarios, en cualquier cálculo que necesite para aplicar la máscara: & (tamaño-1) que es 2 ^ N-1, en mi caso N = 14 - > tamaño del búfer circ = 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
                {
                }
          }
    
respondido por el Marko Buršič

Lea otras preguntas en las etiquetas