Usando el módulo CH376 con PIC 18f520

Estoy tratando de leer datos de un USB usando el módulo CH376 con microcontrolador PIC 18f4520.

El nombre del archivo que intento leer es "ABC.txt" y contiene "hola".

// Instructing module which file to read

SerialTransmit(0x57);
SerialTransmit(0xAB);
SerialTransmit(0x2f);
SerialTransmit(0x2f);
SerialTransmit('A');
SerialTransmit('B');
SerialTransmit('C');
SerialTransmit('.');
SerialTransmit('T');
SerialTransmit('X');
SerialTransmit('T');
SerialTransmit(0x00);

init_lcd();
lcd_string("fn");
function_int(RCREG);
DelayMS(1); 

// Opening the File

SerialTransmit(0x57);
SerialTransmit(0xAB);
SerialTransmit(0x32);

init_lcd();
lcd_string("open");
function_int(RCREG); 
DelayMS(2000);

if(RCREG!=0x14)
   {
    init_lcd();
    lcd_string("open not ok");
    while(1);
    }

 else
    {   
        init_lcd();
        lcd_string("open ok");
        DelayMS(1);
     }
 i=0;

  // Setting to read 5 bytes 

  SerialTransmit(0x57);
  SerialTransmit(0xAB);
  SerialTransmit(0x3A);
  SerialTransmit(0x05); // here
  SerialTransmit(0x00);

 i++;
 init_lcd();
 lcd_string("dl");
 function_int(RCREG);
 DelayMS(2);

 if(RCREG!=0x1D)
{   
   init_lcd();
   lcd_string("dl not ok");
   while(1);
 }

 else   
 {  
    init_lcd(); 
    lcd_string("dl ok");    
    DelayMS(1);
  }

// Reading

SerialTransmit(0x57);
SerialTransmit(0xAB);
SerialTransmit(0x27);

// It reads the first byte here, first byte is a waste byte i.e. 
// it returns 0x05 (The number of bytes we want to read)

init_lcd(); 
lcd_string("0read");
function_int(RCREG);    
DelayMS(3000);

// It reads the first byte here, i.e. H

init_lcd();
lcd_string("1read");
function_int(RCREG);
lcd_string("==");
lcd_data(RCREG);    
DelayMS(3000);

// It is supposed to read 'E' here, but it still reads 'H'

init_lcd();
lcd_string("2read");
function_int(RCREG);
lcd_string("==");
lcd_data(RCREG);
DelayMS(3000);

// It is supposed to read 'L' here, but it still reads 'H'

init_lcd();
lcd_string("3read");
function_int(RCREG);
lcd_string("==");
lcd_data(RCREG);
DelayMS(3000);

while(1);

Puedo configurar e indicar al módulo que abra y comience a leer el archivo. Pero el problema es que estoy atascado en el primer byte. No puedo hacer que lea el segundo byte. ¿Como lo puedo hacer?

Gracias, realmente agradeceré cualquier ayuda.

¿función_int hace qué?
@Dorian Muestra el valor hexadecimal del byte, lcd_data muestra el carácter real
¿Qué compilador estás usando?
@Dorian, estoy usando MPLAB con el compilador Hi-Tech.
Ver más detalles en el chat

Respuestas (1)

No puede usar RCREG de esta manera. Debe leerlo en un búfer y luego usar el búfer para otras pruebas.

Veo que usas:

function_int(RCREG);
lcd_string("==");
lcd_data(RCREG);    

En el segundo uso, RCREG será el siguiente byte recibido o la unidad uart mostrará un error porque no hay datos en el registro RCREG.

Además, la imagen 16f4520 no tiene un FIFO de recepción, los retrasos prolongados que utiliza conducen al desbordamiento del búfer y se pierden todos los bytes recibidos.

Use un búfer temporal para leer todos los bytes sin demora y luego procese los datos

La forma correcta es:

  • lea la bandera RCIF para ver si hay datos disponibles en RCREG
  • lea RCREG en un búfer y de nuevo al primer paso hasta que lea todos los bytes esperados.
  • procesar los datos recibidos.

O use un búfer UART de software, si usa MPLABX, luego use el configurador de código mplab y las funciones generadas, no lea el RCREG directamente

Actualizar. A medida que usa SerialTransmit que espera a que el búfer TX esté vacío antes de enviar un carácter, use también SerialReceive que espera a que se reciba un carácter.

Tiene una combinación de fallas aquí, en el código que se muestra arriba, está leyendo dos veces y el segundo byte leído es defectuoso, lo que lleva a un desbordamiento de recepción.

Luego, incluso siguiendo mi consejo, almacenó en búfer el RCREG, después de eso tiene un retraso prolongado, pero el búfer de recepción de UART puede contener solo un byte y todos los demás bytes se pierden.

Use SerialReceive (que espera a que un byte esté disponible antes de regresar como se ve arriba) y guarde en el búfer todos los datos esperados antes de realizar cualquier procesamiento:

for(i=0;i<number_of_bytes_expected;i++)
  {
   buffer[i] = SerialReceive();
  }
// do whatever you need with the data 
Gracias. Probaré esto y te dejaré saber si esto funciona.
Lo probé usando el búfer pero aún está atascado en el primer byte. (¿Podemos mover esta conversación al chat?)
@prog_SAHIL Por supuesto, deje 30 minutos para llegar a una PC, estoy en el móvil en este momento