CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Usart problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Usart problem
PostPosted: Wed Nov 16, 2005 2:04 pm     Reply with quote

Hello.
I'm having problem with hardware AND software USART on a PIC16F877A (With CCS compiler version 3.236). I have to send a 6 byte tag to a serial device and receive (from the serial device) an 11 byte response. Here's my code:

Code:
#include <16F877A.H> //16F877A pic


#fuses HS,NOWDT,NOPROTECT,NOLVP

#define TX_DATA PIN_C6
#define RX_DATA PIN_C7

#use delay(clock=10000000)
#use rs232(baud=38400, xmit=TX_DATA, rcv=RX_DATA, PARITY=E, bits=8,ERRORS)

/******************************************************************************\
*                            M A I N   R O U T I N E                                                     *
\******************************************************************************/
#pragma zero_ram                     // Interesting command ....

void main( void )
{
  int i=0;
  char c;

  delay_ms(3000); //need to wait til device is on.
  lcd_putc("\f");
  delay_ms(1);
  putc(0x06);
  delay_ms(1);
  putc(0xFF);
  delay_ms(1);
  putc(0x21);
  delay_ms(1);
  putc(0x01);
  delay_ms(1);
  putc(0x2A);
  delay_ms(1);
  putc(0xA5);
 
    for (i=0;i<11;i++) {
      c = getc();
      putc(c);
     
    }
 
//  }
}


When I use force_sw, I get all zeroes. When I use the hardware UART, I get two (usually first wrong) characters and the PIC halts.
I am using a MAX232 driver, and it's hooked up correctly. I'm not really sure what's going on here. Can anyone help?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 3:00 pm     Reply with quote

Quote:
I have to send a 6 byte tag to a serial device

What is the "serial device" ?
Who is the manufacturer ?
What is the part number of the device ?
Give a link to the webpage for the product and to its data sheet.
Guest








PostPosted: Wed Nov 16, 2005 3:06 pm     Reply with quote

The serial device is an RFID reader (model S6500, RI-STU-650A) by TI.
Here's the datasheet:
http://www.ti.com/rfid/docs/manuals/pdfSpecs/RI-STU-650AdataSheet.pdf
And here's the host protocol:
http://www.ti.com/rfid/docs/manuals/refmanuals/S6000ConfigurationHost_FW_3-10.PDF

(this stuff has taken me a while to understand, hence I'm making my request more general)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 3:39 pm     Reply with quote

You are sending these bytes: 0x06, 0xFF, 0x21, 0x01, 0x2A, 0xA5

This T.I. webpage lists several documents for that product.
Which document, and what page number, tells you to send those
exact bytes ?
http://www.ti.com/rfid/docs/products/readers/RI-STU-650A.shtml
Ttelmah
Guest







PostPosted: Wed Nov 16, 2005 3:50 pm     Reply with quote

First problem. You are sending a character to the device, for each character read. As far as I can see, once you have sent the 'header', you only need to read. Writing these extra characters, may cause unexpected results.
Second thing, you need a 'trap' at the end of your code, to stop the processor falling of the end, and putting the processor to sleep.
Now, why pause between the characters?. This is not needed, the device is capable of handling continuous data.
I'd start by ensuring that the serial transmit line is idling, and waiting for a moment at the start, then just send the data stream, and read the responses.
You don't say what compiler version?. There have been odd serial problems with some versions.
Try:
Code:

void main( void )
{
  int i=0;
  char c;
  //Ensure serial line goes to it's idle state.
  putc(0xff);
  delay_ms(3000); //need to wait till device is on.
  lcd_putc("\f");
  //Ensure input buffer is empty
  while (kbhit) i=getc();

  //Send string
  putc("\x06\xFF\x21\x01\x2A\xA5");
 
  //Now wait for packet back
  for (i=0;i<11;i++) {
      c = getc();
      lcd_putc(c);
  }
 
  while (true);
}

Are you sure your 'command' is right?. It appears correctly to start with '6' (6 bytes in the packet), then use 'FF' as an address (which should make any unit reply with it's own address), but then '21', does not appear in the command list on the data sheets you give...
I'd suspect the two wrong characters you are getting back, are two garbage characters left in the UART input buffer, and the unit is not recognising your command.

Best Wishes
Guest








PostPosted: Wed Nov 16, 2005 3:57 pm     Reply with quote

http://www.ti.com/rfid/docs/manuals/refmanuals/S6000ConfigurationHost_FW_3-10.PDF

That's the document I got the information from.
It's a read buffer command, 0x21. The command is right, because I'm getting the correct information from the RFID (directly hooked up to the PC's serial)
The problem really must be something with the PIC.
Ttelmah
Guest







PostPosted: Wed Nov 16, 2005 4:19 pm     Reply with quote

Anonymous wrote:
http://www.ti.com/rfid/docs/manuals/refmanuals/S6000ConfigurationHost_FW_3-10.PDF

That's the document I got the information from.
It's a read buffer command, 0x21. The command is right, because I'm getting the correct information from the RFID (directly hooked up to the PC's serial)
The problem really must be something with the PIC.

It carefully does not list that in the Index....
It mentions it in the text, but leaving it out of the index, worried me that it might not be right (or your calculation of the checksum might be wrong)...
Also this command does not work, till the unit has been configured to do this.
Have you checked with a scope/logic analyser, that the data sent is correct, and what the line levels are at the PIC?.
There are a couple of running threads at the moment, where on some compiler versions, the TRIS bit for the receive input, is incorrectly being programmed as an 'output'. I have seen this on a 18F1320, and another user had seen this on a 16F88. I have just suggested to another poster with a serial problem, that they try overriding this to see if they too are seeing this. This was why I asked after your compiler version?.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 4:23 pm     Reply with quote

In that document, on page 16, it shows the Protocol Frame.
It shows the MSB of the CRC comes first, and then the LSB.
On page 18 of the document, they show the CRC16 algorithm.
I re-wrote that code for CCS, as shown below and ran it on
your data bytes. I got a CRC16 result of:
Quote:
crc = A52A

That shows the MSB is 0xA5 and the LSB is 0x2A.

So the order of the CRC16 bytes should have 0xA5 come first, like this:
Quote:
0x06, 0xFF, 0x21, 0x01, 0xA5, 0x2A;

But you have it coming last.

Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use RS232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) 

#define CRC_PRESET 0xFFFF
#define CRC_POLYNOM 0x8408

// cnt = number of protocol bytes without CRC
int16 calculate_crc16(int8 DATA[], int8 cnt)
{
int8 i;
int8 j;
int16 crc;

crc = CRC_PRESET;

for(i = 0; i < cnt; i++)
   {
    crc ^= DATA[i];
    for(j = 0; j < 8; j++)
       {
        if(crc & 0x0001)
           crc = (crc >> 1) ^ CRC_POLYNOM;
        else
           crc = (crc >> 1);
       }
   }
return(crc);
}


//=============================

void main()
{
int8 data[6] = {0x06, 0xFF, 0x21, 0x01, 0x00, 0x00};   
int16 crc;

crc = calculate_crc16(data, sizeof(data) -2);
printf("crc = %LX", crc);
while(1);
}
Guest








PostPosted: Wed Nov 16, 2005 4:27 pm     Reply with quote

I'm working with CCS version 3.236 on MPLAB 7.2. I'm getting no response with the code you posted, so I'm really not sure what's going on.
I am getting the correct response from the RFID reader, so I know the command I have is correct, and the RFID reader flashes an LED indicating so as well... it's not a problem with the command, so it's either a problem with my MAX232CPP or it's a problem with the PIC code.
Guest








PostPosted: Wed Nov 16, 2005 4:32 pm     Reply with quote

Quote:
That shows the MSB is 0xA5 and the LSB is 0x2A.

So the order of the CRC16 bytes should have 0xA5 come first, like this:
0x06, 0xFF, 0x21, 0x01, 0xA5, 0x2A;

But you have it coming last.


Yeah, I talked to a TI representative about that. He gave me a CRC calculator that is actually correct. The MSB and LSB should be swapped.
I did test it just to make sure, and I get no response from the RFID the other way, so I know it's right.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 4:41 pm     Reply with quote

Quote:

I talked to a TI representative about that. He gave me a CRC calculator
that is actually correct.

So their documentation is bogus.

We recently had that problem too, with the T.I. TVP5150A video
decoder. The documentation is incorrect with respect to extracting
Closed Captioning data. When I complained, they emailed me
a revised version of VBI Quick Start (sleu046a.pdf). I told them
to post the new version so they don't screw people up, but I checked
just now (two months has past) and they still haven't posted the
new version. I think T.I. is going downhill.
Guest








PostPosted: Wed Nov 16, 2005 5:44 pm     Reply with quote

... It also helps when you hook up your MAX232 correctly. Embarassed
Thanks for all of your help, everyone.
Guest








PostPosted: Wed Nov 16, 2005 5:47 pm     Reply with quote

One final question... say I have two separate things that can appear on the receive line - a 11 byte tag and a 6 byte "fail" tag. I only want to pay attention to the 11 byte one and ignore the 6 byte one. How would you propose doing that?
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Wed Nov 16, 2005 5:52 pm     Reply with quote

Look at the receiver code in this post: http://www.ccsinfo.com/forum/viewtopic.php?t=23953

It uses a "combination lock" to detect the message you want/expect. Other messages and/or garbage simply reset the lock.
Guest








PostPosted: Wed Nov 16, 2005 11:28 pm     Reply with quote

This is my last hope now... If I can't get this working, I really don't know what I'm going to do.
Same compiler, same PIC, same interface. Here's the code:

Code:
#include <16F877A.H> //16F877A pic


#fuses HS,NOWDT,NOPROTECT,NOLVP

#define TX_DATA PIN_C6
#define RX_DATA PIN_C7

   
#use delay(clock=10000000)
#use rs232(baud=38400, xmit=TX_DATA, rcv=RX_DATA, PARITY=E, bits=8)
#include "lcd.c"


/******************************************************************************\
*                            M A I N   R O U T I N E                                                     *
\******************************************************************************/
#pragma zero_ram                     // Interesting command ....

void main( void )
{
int i=0;
  char buf[17]={23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23};
  char c;
lcd_init();
delay_ms(3000);
  putc(0x06);
  putc(0xFF);
  putc(0x21);
  putc(0x01);
  putc(0x2A);
  putc(0xA5);

   for (i=0;i<17;i++) {
       buf[i] = getc();
   }
   // Transmit the 16 bytes we got
   for (i=0;i<17;i++) {
       putc(buf[i]);
    }
}



I'm at a loss here. Everything should be transmitting correctly. The RFID reader is sending the following code to the PIC:

Code:
11 00 21 00 01 01 03 e0
07 00 00 01 bc c5 a8 f1
47


The PIC, however, sends the following back:
Code:
11 00 21 00 01 01 03 e0
07 00 00 01 bc c5 a8


Is there a reason why I'm not getting all the data I'm asking for? Is this a limit on the hardware USART?

Ultimately, I really need to do this:

Get the information off the serial: 11 00 21 00 01 01 03 e0 07 00 00 01 bc c5 a8 f1 47...
Take bytes 8 through 15 out and store them in a buffer for later.

I've fought with this thing for hours and hours. Can anyone help? You've all been a tremendous help so far... do I need to know something else about the getc() command that I don't know?... or is there another method of doing this?

Thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group