1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ function_int does what? \$\endgroup\$ – Dorian Jun 3 '18 at 13:36
  • \$\begingroup\$ @Dorian It displays the hex value of byte, lcd_data displays the actual character \$\endgroup\$ – prog_SAHIL Jun 3 '18 at 15:51
  • \$\begingroup\$ What complier are you using? \$\endgroup\$ – Dorian Jun 4 '18 at 8:50
  • \$\begingroup\$ @Dorian, I am using MPLAB with Hi-Tech compiler. \$\endgroup\$ – prog_SAHIL Jun 4 '18 at 13:20
  • \$\begingroup\$ See more details on chat \$\endgroup\$ – Dorian Jun 4 '18 at 14:40
2
\$\begingroup\$

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 
\$\endgroup\$
  • \$\begingroup\$ Thanks. I will try this and let you know if this works. \$\endgroup\$ – prog_SAHIL Jun 4 '18 at 3:00
  • \$\begingroup\$ I tried it using buffer but still it is stuck on the first byte. (Can we move this conversation the chat?) \$\endgroup\$ – prog_SAHIL Jun 4 '18 at 6:17
  • \$\begingroup\$ @prog_SAHIL Of course, let 30 min to get to a pc, I'm on mobile right now \$\endgroup\$ – Dorian Jun 4 '18 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.