TODOPIC

Microcontroladores PIC => Primeros pasos - Iniciación a los microcontroladores => Mensaje iniciado por: avumadden en 31 de Marzo de 2015, 05:59:10

Título: Ayuda: Limpiar Buffer UART!
Publicado por: avumadden en 31 de Marzo de 2015, 05:59:10
Que tal, me gustaría saber si existe alguna función similar a "fflush" de C para borrar el buffer de la UART del Pic.

Mi problemática es la siguiente:
Si durante la función de retardo, "inesperadamente" recibo otro carácter este se anexa y se guarda en el buffer, el cual posteriormente se posiciona en la primer localidad del siguiente array. Estoy buscando la manera para antes de empezar a leer la segunda cadena borrar cualquier valor que se encuentre en este previamente.

Código MPLAB X, usando XC8:
Código: [Seleccionar]
#include <string.h>

char cadena1[5];
char cadena2[5];
char cadenaref1[5]="hello";
char cadenaref2[5]="hella";
int x, y;

UART_Read_Text(cadena1,5);
x = strcmp(cadena1,cadenaref1);
__delay_ms(500);
if (x == 0){
    - Función para limpiar el buffer aquí -
    UART_Read_Text(cadena2,5);
    y = strcmp(cadena2,cadenaref2);
    if ( y == 0){
        -Haz Algo-
    }
}


Anexo una imagen demostrativa de mi problemática, en la cual cito "h", como un carácter introducido de manera inesperada.
(http://i.imgur.com/teffhrx.png)

En teoría creo que limpiando el registro RCREG podría solucionar mi problema, mas no logro conseguirlo.

Agradecería realmente si alguien puede ayudarme.
Saludos
Título: Re: Ayuda: Limpiar Buffer UART!
Publicado por: KILLERJC en 31 de Marzo de 2015, 06:29:54
La unica forma de limpiar el buffer de recepcion es leyendo el registro, pero tu mayor problema es el delay y como estas manejando los datos.

Tenes dos formas si quieres seguir haciendo lo que estas haciendo, simplemente coloca 5 instrucciones que hagan un dummy read:

Citar
variable_sin_importancia = RCREG;
variable_sin_importancia = RCREG;
variable_sin_importancia = RCREG;
variable_sin_importancia = RCREG;
variable_sin_importancia = RCREG;

Eso limpiaria tu buffer. El principal problema ahora es... que pasa si recibis el comienzo de la otra palabra durante el delay.. ejemplo una "h". Lo podes solucionar de 2 formas, una es limpiando antesdel delay al buffer, pero volvemos al mismo tema de ahora, que existan 2 palabras durante el delay (y perder el sincronismo de los 5 caracteres, mas delante me explico con el ejemplo de "elloh"). Y la otra es usar interrupciones.

Para mi la unica y efectiva solucion es usar interrupciones. No se exactamente cuanto se puede setear la interrupcion, algunos se puede setear cuando se completa el buffer , otros a la mitad. otros apenas recibis un dato.

Si se puede hacer a buffer completo seria bueno desde el punto de vista ideal, pero eso significa que si envias solo una parte nunca entraria a la interrupcion, por ejemplo enviar "hell" y nada mas
Lo que me lleva a otra cosa. vos esperas que los datos entren en ese orden pero puede que llegue el punto que estes enviando esto: "elloh" donde la h es de la siguiente palabra.

Yo a mi criterio haria interrupcion por caracter. Con un caracter en especial para indicar comienzo y si es variable el mensaje ( es decir no siempre tiene 5 caracteres y tiene mas ) pondria otro caracter para indicar un final ( distinto al primero, o que el segundo caracter sea la cantidad de caracteres que van )

Ej:

0x1D H E L L O 0x1C  (inicion y finall)
o
0xFF 0x05 H E L L O  (inicio y contador)

o si siempre es de 5 caracteres, con uno solo basta

0xFF H E L L O

Esto te va a permitir que a pesar que estes en un delay, apenas reciba un dato entre a la interrupcion y comienze a llenar la variable cadena[] ya sea cadena1 o cadena2. Y te permite conocer claramente el largo/inicio de la transmision
Y en tu programa en ves de "leer" con el UART_Read_Text , simplemente preguntas por una flag(que indique ya se completo todo de la cadena1 o cadean2) o te quedas preguntando por si la cadena es esa. Cuando se llene va a cumplir o no la condicion de igualdad y va a seguir con el programa.