|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Usart problem |
Posted: Wed Nov 16, 2005 2:04 pm |
|
|
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
|
|
Posted: Wed Nov 16, 2005 3:00 pm |
|
|
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
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 16, 2005 3:50 pm |
|
|
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
|
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 16, 2005 4:19 pm |
|
|
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
|
|
Posted: Wed Nov 16, 2005 4:23 pm |
|
|
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:
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
|
|
Posted: Wed Nov 16, 2005 4:27 pm |
|
|
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
|
|
Posted: Wed Nov 16, 2005 4:32 pm |
|
|
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
|
|
Posted: Wed Nov 16, 2005 4:41 pm |
|
|
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
|
|
Posted: Wed Nov 16, 2005 5:44 pm |
|
|
... It also helps when you hook up your MAX232 correctly.
Thanks for all of your help, everyone. |
|
|
Guest
|
|
Posted: Wed Nov 16, 2005 5:47 pm |
|
|
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: 1908
|
|
|
Guest
|
|
Posted: Wed Nov 16, 2005 11:28 pm |
|
|
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. |
|
|
|
|
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
|