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

CRC-8bit example with USART

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

CRC-8bit example with USART
PostPosted: Fri Jan 18, 2008 1:28 am     Reply with quote

HI to everyone!!!
i have a wireless transmitter and receiver 433MHz , AM-HRR3-433, AM-RT4-433 from R. F. Solutions Ltd.
Need to make one way link
sending data from one pic to an'other with USART and #int_rda.
As i was searching for long time this forum i have find a lot of examples but did'nt fint any example how to use CRC-8bit with USART #int_rda!!!
This thread have alot of info on CRC but not CRC with Usart...

http://www.ccsinfo.com/forum/viewtopic.php?t=17170&highlight=crc

Code:

transmitter code

Code:

#include <18F452.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_C0,rcv=PIN_C1,errors)
#fuses XT, NOPROTECT, PUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT


}
void main()
{

while(1)
{
putc('1');                         //Repeat data out
output_high(PIN_C0);
delay_ms(300);
putc('2');                       //Repeat data out
output_low(PIN_C0);
delay_ms(300);
}
}



Code:
simple Receiver code

Code:

#include <18F452.h>
#use delay(clock=4000000)
#use i2c(Master, SDA=PIN_C2, SCL=PIN_C3)
#use
rs232(baud=9600,xmit=PIN_C0,rcv=PIN_C1,errors)
#fuses XT, NOPROTECT, PUT, NOWDT, BROWNOUT, NOLVP, NOCPD, NOWRT

#include <lcd_4x20.c>

unsigned int data;

#INT_RDA
rda_isr() {
data = getc();
}

void main()
{

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

lcd_init();

while(true) {
lcd_gotoxy(1,1);
if(data == '1')
printf(lcd_putc,"data==1");
else if(data == '2');
printf(lcd_putc,"data==2");
}
}






This one was a easy and small code of CRC8-bit 1wire dallas I found ON that thread but dont now how to use this code???

Quote:
you could use the dallas onewire CRC algorithm -- quick to run, easy to implement, very few instructions, no ROM space lost, very little RAM required, no fuss, no muss, It Just Works...

Code:

int onewire_crc(int oldcrc, int newbyte) {
// see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf

int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8; j++) { // for each bit
data_bit = (newbyte >> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}


ps, my onewire primitives library is here:
http://losdos.dyndns.org:8080/public/onewire/lib-onewire.html

regards.
jds-pic

And a last one question how does the driver
CRC.c works?
I dont understand what is "pattern".
it says in the code:
generate_8bit_crc(data, length, pattern) //Generates 8 bit crc from the data using the pattern.

Sorry for my bad english.trying to do my best
_________________
---- GREECE ----
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Fri Jan 18, 2008 12:46 pm     Reply with quote

E_KARVELAs wrote:
HI to everyone!!!
As i was searching for long time this forum i have find a lot of examples but did'nt fint any example how to use CRC-8bit with USART #int_rda!!!
This thread have alot of info on CRC but not CRC with Usart...


ok, i think you are a little confused here. let's see if we can straighten things out...

in order to check for data integrity in a received message, additional data can be appended to the message by the transmitter to allow for a check by the receiver. while this increases overhead, generally the benefits of data corruption detection outweigh the downside of slightly greater overhead and resource utilization. in general this additional transmitted data is called a checksum, but there are several ways of doing it...

as for implementing corruption detection via checksum transmission, there are simple (e.g., parity), moderate (e.g., XOR), and complex (e.g. CRC) methods. better detection usually means more resources (cycles, RAM, ROM, time, overhead) are used.

the checksum is appended to the payload by the transmitter, making a complete message. the receiver computes another checksum against the received payload, and compares it against the checksum provided by the transmitter. if they match, the payload is intact and further processing can be taken. if not, the data can not be trusted and must be discarded, with the receiver either requesting another send or simply waiting for the next message transmission.

again -- the checksum is simply data appended to the payload. the checksum, depending on the payload size, can be from 1 to many bytes. for a CRC8 implementation, it is one byte (8bits=1byte). there are mathematical limitations on how many and what type of errors can be caught by a CRC of size X used against a payload of size Y. discussing this in detail is beyond the scope of this post. nevertheless, for validating larger payloads, larger (=longer, in byte size) CRC's can be used at the expense of additional overhead.

back to your implementation. it matters not how you are collecting serial bytes from the transmitter -- via #int_rda or by polling or whatever. the CRC8 (or CRC16, or ...) is simply another byte (or 2, or ...) appended to the payload to create a message. you read that byte just like any other, but you must handle it specially. think of the CRC as a wax seal on an envelope. if the internals have been tampered with, the wax seal will be broken (i.e., the received and computed CRC's will differ.)

CRC's are generated by "seeding" the CRC algorithm with an initial value; in a lot of cases this is 0x00. the first byte in the payload is fed to the CRC algorithm, producing a new CRC value. that CRC value is used to seed the subsequent step, when the next byte in the payload is fed to the CRC algorithm. and so on.

for example, in the Dallas onewire CRC algorithm you posted above, int onewire_crc(int oldcrc, int newbyte), after initialization, you simply call that function with each received byte. the last value returned is the computed CRC of the payload. compare that to the received CRC. if it matches, you can carry on using the payload.

hope that helps.

jds-pic
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Fri Jan 18, 2008 5:43 pm     Reply with quote

Quote:

for example, in the Dallas onewire CRC algorithm you posted above, int onewire_crc(int oldcrc, int newbyte), after initialization, you simply call that function with each received byte. the last value returned is the computed CRC of the payload. compare that to the received CRC. if it matches, you can carry on using the payload.

hope that helps.

jds-pic

Hi and thanks for ur reply .
Can u please implement this to me.After receiving from transmitter a int CRC + int data i must first seperate them ,take the int data and calculate from it the (int crc ) withCRC8-1wire routine. is that right???


After this i must compare the old crc wich we received (int old_crc) and the new one (int new_crc) wich we computed from the (int data) and CRC8-1wire routine.

If this is right then i have just to compare them:
Code:

int onewire_crc(int oldcrc, int newbyte) {
// see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf

int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8>> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}




Code:

if(oldcrc==shift_reg)
                         {
          flag=1 ;                           // flag truee
                          }
else      {
          flag=0;                           //flag false           
                         }

_________________
---- GREECE ----
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Fri Jan 18, 2008 10:56 pm     Reply with quote

E_KARVELAs wrote:

Can u please implement this to me.After receiving from transmitter a int CRC + int data i must first seperate them ,take the int data and calculate from it the (int crc ) withCRC8-1wire routine. is that right???


let me simplify, (assuming everything is one byte long):

transmitter sends "data0 data1 ... dataN crc8"
receiver receives "data0 data1 ... dataN crc8"

at this point the receiver recomputes the crc8 for data0 through dataN, and compares the newly computed crc8 value versus the crc8 value which was received with the message. if they differ, some portion of the data payload was corrupted in transit.

E_KARVELAs wrote:

After this i must compare the old crc wich we received (int old_crc) and the new one (int new_crc) wich we computed from the (int data) and CRC8-1wire routine.


no. the onewire_crc() algorithm is used by both the transmitter and receiver to compute the CRC8 over a given number of payload bytes. it has nothing to do with directly comparing two CRC8 values.

E_KARVELAs wrote:

If this is right then i have just to compare them:


not the way you have posted.

at the transmitter, compute the CRC8 of the ENTIRE PAYLOAD by feeding the onewire_crc() function each successive byte that is sent, and then finally send the CRC8. (don't forget to initialize the CRC algorithm to 0x00 prior to the first payload byte.)

at the receiver, compute the CRC8 of the ENTIRE PAYLOAD by feeding the onewire_crc() function each successive byte that is received, and then finally compare the computed CRC8 with the received CRC8 (which is usually the last byte received). (don't forget to initialize the CRC algorithm to 0x00 prior to the first payload byte.)

jds-pic
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Sat Jan 19, 2008 6:22 am     Reply with quote

Quote:

let me simplify, (assuming everything is one byte long):

transmitter sends "data0 data1 ... dataN crc8"
receiver receives "data0 data1 ... dataN crc8"

at this point the receiver recomputes the crc8 for data0 through dataN, and compares the newly computed crc8 value versus the crc8 value which was received with the message. if they differ, some portion of the data payload was corrupted in transit.

U sayed that i can compute an 8-bit CRC from "data0 data1 ... dataN" with this routine CrC8bit-1wire by feeding the onewire_crc() function each successive byte that is sent.
OK .but i don't understand how? when this routine as i can see return an int shift_reg (8-bit data) everytime!!!
Quote:

int onewire_crc(int oldcrc, int newbyte) {


int shift_reg, data_bit, sr_lsb, fb_bit, j;
shift_reg=oldcrc;
for(j=0; j<8>> j) & 0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8c;
}
return(shift_reg);
}




Can u please post here a small example code how to do this??
I don't understand how to use this routine for calculating 8 bit CRC from a
"data0 data1 ... dataN" .
Thanks for ur help.
_________________
---- GREECE ----
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Sat Jan 19, 2008 8:56 am     Reply with quote

E_KARVELAs wrote:

Can u please post here a small example code how to do this??
I don't understand how to use this routine for calculating 8 bit CRC from a
"data0 data1 ... dataN" .


at the transmitter, let's assume you have 6 bytes in an array called "txdata[]". compute the CRC8 of the bytes as you send them by passing each in sequence to the onewire_crc() function.

Code:
txcrc8=0;
for (i=0; i<=5; i++) {
  fputc(txdata[i],SERIAL_PORT);
  txcrc8=onewire_crc(txcrc8, txdata[i]);
  }

at this point, txcrc8 holds the CRC8 of all of the elements in the txdata array (e.g. txdata[0], txdata[1], ..., etc). so now send the computed CRC8:

Code:
fputc(txcrc8,SERIAL_PORT);


on the serial cable, you now have a byte stream that looks like this
txcrc8 txdata[5] ... txdata[1] txdata[0] ---> RX


at the receiver
, you need to capture 7 bytes: the 6 byte payload + the 1 byte CRC8. based on the first post in this thread, i'm assuming that you know how to read from the serial port. so at the receiver, get the 7 (yes, 7) bytes captured and recompute the CRC8 across the first 6 bytes:

Code:
capture_serial_data_into_rxdata_array();
rxcrc8=0;
for (i=0; i<=5; i++)
  rxcrc8=onewire_crc(rxcrc8, rxdata[i]);


now, you take the newly computed rxcrc8 and compare it to the 7th element in the received data array, that is, rxdata[6]. recall that byte was the CRC8 generated and transmitted by the source. if the two are the same, the payload was not corrupted during transmission.

Code:
if (rxcrc8 == rxdata[6])
  rxdata_valid=TRUE;


jds-pic


Last edited by jds-pic on Sun Jan 20, 2008 9:22 am; edited 3 times in total
E_KARVELAs



Joined: 14 Feb 2007
Posts: 46
Location: Greece & Cyprus

View user's profile Send private message

Re: CRC-8bit example with USART
PostPosted: Sat Jan 19, 2008 11:21 am     Reply with quote

Thanks a lot dude Cool
You realy helped me !!! Razz
I'm goind to build that code and reply back if it's working.
Again ,Thanks a lot Smile
_________________
---- GREECE ----
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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