Electronic – Using CH376 module with PIC 18f520

microcontrollerpicuartusb

I am trying to read data from a USB using CH376 module with PIC 18f4520 microcontroller.

The name of the file I am trying to read is "ABC.txt" and it contains "hello".

// 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);

I am able to set up and instruct the module to open and start reading the file. But the problem is that I am stuck on the first byte. I cannot make it to read the second byte. How can I do so?

Thanks, I will really appreciate any help.

Best Answer

You cannot use RCREG in this way. You must read-it into a buffer then use the buffer for other tests.

I see you use:

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

On the second usage RCREG will be the next byte received or the uart unit will show an error because there is no data in the RCREG register.

Also , pic 16f4520 does not have a receive FIFO, long delays you use lead to buffer overflow and all bytes received are lost.

Use a temporary buffer to read all bytes without delay then process the data

The right way is to:

  • read the RCIF flag to see if there is data available in RCREG
  • read RCREG into a buffer and again to first step until you read all bytes expected.
  • process the received data.

Or use a software UART buffer, if you use MPLABX then use mplab code configurator and functions generated , do not read the RCREG directly

Update. As you use SerialTransmit that waits for the TX buffer to be empty before sending a character use also SerialReceive which waits for a character to be received.

You have a combination of faults here, in the code shown above you are reading twice and the second byte read is faulty leading to a receive overrun

Then, even at my advice you buffered the RCREG , after that you have a long delay but the receive buffer of UART can hold only one byte and all other bytes are lost.

Use SerialReceive (which waits for a byte to be available before returning as you see above) and buffer all expected data before making any processing:

for(i=0;i<number_of_bytes_expected;i++)
  {
   buffer[i] = SerialReceive();
  }
// do whatever you need with the data