Recibir bytes de la cámara UART

3

Estoy usando un dsPIC33E MUC para conectar una cámara UART (VGA) a 115.2 Kbps. El propósito es guardar una imagen en una tarjeta SD.

El programa que escribí funciona bien, excepto que está dentro de un bucle que comprueba si el búfer (el búfer de 512 bytes es para un sector) está lleno o no. Si el búfer está lleno, se escribirá en una tarjeta SD. Me pregunto cómo puedo adaptar este código a un proyecto de adquisición de datos de tiempo crítico. Como se trata de una interrupción UART, no estoy seguro de si la mejor manera de guardar imágenes en una tarjeta SD es usar una bandera. Aquí está el código con el indicador de comprobación de bucle para ver si el búfer está lleno.

unsigned char buff[512];//buffer to store bytes comming from the camera
unsigned int bufferPtr=0;//pointer for the buffer. It will be incremented for each byte
while(1){
    if(bufferPtr==512){Write_Sector(SectorNumber,Buff);}//if the buffer is full, Write a it to SD card
    bufferPtr=0;//reset buffer Pointer so next byte will be save to the beginning of the buffer
}

rutina de interrupción

void ISR(){
    Uart.FlagBit=0;//clear flag bit first
    buffer[bufferPtr++]=UART_Read();//read a byte and put it into the buffer
}

Como puede ver, el programa está esperando que lleguen los bytes y los guarde en un búfer. Funciona muy bien, pero tengo una pregunta sobre el tiempo. En términos de velocidad de escritura, necesita aproximadamente 3.6 segundos para 2000 sectores (cada sector 512 bytes). Así que escribir un sector necesita 3600/2000 = 1.8ms. La velocidad en baudios me dice que 115200/10 = 11520Byte / Sec, lo que significa 11.52 Bytes / ms. ¿Cómo es posible escribir un sector en la tarjeta SD (necesita 1,8 ms) sin desbordar el búfer UART FIFO? Durante ese período de 1.8 ms, habrá 11.52 * 1.8 = 20.736 bytes entrando.

    
pregunta Timtianyang

2 respuestas

2
  

Buffer = sector RAM buffer.   UART buffer = UART buffer interno.

"Solo es cuestión de programación" :-)

No he visto los detalles finos de su método o recursos específicos del dispositivo; la siguiente solución general se aplica siempre que la RAM disponible no esté limitada de manera crucial:

La tasa de llegada es aproximadamente 1,000,000 / 115,200 uS / bit = 8,68 uS / bit u 87 uS / byte

La velocidad de escritura de la tarjeta SD es 1800 uS / 512 bytes ~ = 3.5 uS / byte.

A largo plazo, si no hay otros gastos generales importantes, tiene una tasa de escritura mucho más rápida que la tasa de llegada. El único problema es tratar de caminar y masticar chicle mientras se almacena el búfer.

Si puede escribir SD y leer UART fácilmente al mismo tiempo, puede usar un búfer de tamaño exacto. Siempre que obtenga el primer byte del búfer dentro de los 87 uS de su escritura, el UART nunca sabrá que está allí.

Si el código es muy crítico en otros lugares, es posible que pueda desactivar las interrupciones y colocar una marca de "hable conmigo" cuando tenga tiempo. Siempre que pueda hacer esto y responder antes de que se llene el búfer de UART cada vez que pueda ganar

Un método de cable alto que desafía a la muerte es resolverlo cuando el búfer está lo suficientemente lleno como para que si comienzas a transferir el THEN, el UART entregará el último byte del búfer según lo requiera la tarjeta SD. Buena suerte logrando eso. Tiene la ventaja de no requerir ningún recurso adicional de búfer SI puede administrarlo 'justo'.

Un método mucho más fácil (suponiendo que se trata de un búfer envolvente) es aumentar el tamaño del búfer con suficientes bytes más un poco más, de modo que cuando el búfer tiene suficientes datos para una escritura SD, comience a escribir datos SD mientras el UART escribe El espacio de almacenamiento "extra". Cuando el escritor de búferes llega al tope del búfer, simplemente se reinicia en el fondo del búfer, felizmente inconsciente de que está cargando bloques de 512 bytes cuando están listos. Esto requiere que se vuelvan a ubicar los punteros superior e inferior del lector de búferes y que se administre el puntero o el contador "búfer lleno", etc., pero de otra manera es "trivialmente fácil" [tm].

Otra vez más fácil es usar dos buffers y voltear el escritor al otro cuando el onbe actual esté lleno. Esto duplica la memoria RAM del búfer necesaria, lo que puede o no ser un problema.

    
respondido por el Russell McMahon
3

Bueno, el código se ve casi bien. Pero, mientras almacena el búfer en la tarjeta SD, si llega un nuevo byte, tendrá un problema. Para estar seguro, puede crear un búfer de anillo de mayor tamaño de búfer necesario y vaciarlo cada xy valores.

int head = 0, tail = 0, cnt = 0;
bool overflow = false;
#define BUFFSIZE 1024
char buff [BUFFSIZE];
#define MEMBUFSIZE 512
char memoryBuff[MEMBUFSIZE];

void appendToBuff(char a_byte)
{
   buff[head++] = a_byte;
   if (head >= BUFFSIZE) {
       head = 0;
       }
   if (head == tail) {
       overflow = true;
       flushBuffer();
       }
}
void flushBuffer ()
{
    while (tail != head || overflow){
        overflow = false;
        memoryBuff[cnt++] = buff[tail++];
        if (tail >= BUFFSIZE) tail = 0;
        if (cnt >= MEMBUFSIZE) {
             Write_Sector(SectorNumber,Buff);
             cnt = 0;
             }
        }
}
void main() 
{
    while (1) {
       flushBuffer();
       }
}

No he probado este código, por lo que podría tener un error o dos, pero te ayudará con una descripción general de lo que deberías manejar ...

    
respondido por el Gossamer

Lea otras preguntas en las etiquetas