0% found this document useful (0 votes)
133 views6 pages

Char CRC5

This C code implements the 1-Wire protocol to communicate with iButton devices over a single data line. It includes functions to reset the 1-Wire bus, transmit and receive bytes, and calculate the CRC checksum. When run, it reads the 64-bit ID from any present iButton and checks the received CRC matches the calculated value.

Uploaded by

ZBC1927
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
133 views6 pages

Char CRC5

This C code implements the 1-Wire protocol to communicate with iButton devices over a single data line. It includes functions to reset the 1-Wire bus, transmit and receive bytes, and calculate the CRC checksum. When run, it reads the 64-bit ID from any present iButton and checks the received CRC matches the calculated value.

Uploaded by

ZBC1927
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

1.

char CRC5(long value, char poly, char init_value, char


exit_value){
2.
3.

char i;

4.

long res;

5.
6.

res=value;

7.
8.

res^=init_value;

9.
10.

//reacomodado para 11bits de trama


for(i=0;i<11;i++){

11.

if(res & 1){

12.

res>>= 1;

13.

res^=poly;

14.

}else{

15.

res>>= 1;

16.
17.

}
}

18.
19.

res^=exit_value;

20.
//solo quedarse con el byte bajo(solo
sirven los 5 bits de menor peso, el resto deberian ser ceros)
21.

return (int8)res;

22.

23.
24. A simple C implementation of the above polynom is shown in the following code.
Again, you can directly copy the source snippet to your code (distributed under
LGPL):
25.
26. //
=============================================================
=============
27. // CRC Generation Unit - Linear Feedback Shift Register
implementation
28. // (c) Kay Gorontzi, GHSi.de, distributed under the terms of
LGPL
29. //
=============================================================
=============
30. char *MakeCRC(char *BitString)
31.
{
32.
static char Res[9];
//
CRC Result
33.
char CRC[8];
34.
int i;
35.
char DoInvert;
36.
37.
for (i=0; i<8; ++i) CRC[i] = 0;
//
Init before calculation
38.
39.
for (i=0; i<strlen(BitString); ++i)
40.
{
41.
DoInvert = ('1'==BitString[i]) ^ CRC[7];
//
XOR required?
42.
43.
CRC[7] = CRC[6];
44.
CRC[6] = CRC[5];
45.
CRC[5] = CRC[4] ^ DoInvert;
46.
CRC[4] = CRC[3] ^ DoInvert;
47.
CRC[3] = CRC[2];
48.
CRC[2] = CRC[1];
49.
CRC[1] = CRC[0];
50.
CRC[0] = DoInvert;
51.
}
52.
53.
for (i=0; i<8; ++i) Res[7-i] = CRC[i] ? '1' : '0'; //
Convert binary to ASCII
54.
Res[8] = 0;
//
Set string terminator
55.
56.
return(Res);
57.
}

58.
59. // A simple test driver:
60.
61. #include <stdio.h>
62.
63. int main()
64.
{
65.
char *Data, *Result;
// Declare two strings
66.
67.
Data = "1101000101000111";
68.
Result = MakeCRC(Data);
// Calculate CRC
69.
70.
printf("CRC of [%s] is [%s] with P=[100110001]\n", Data,
Result);
71.
72.
return(0);
73.
}

/*Includes of system
headers------------------------------------------------------------*/
#include <pic18.h>
/*Includes of local
headers-------------------------------------------------------------*/
#include "iButton.h"
#include "Display.h"
#include "Timer.h"
#include "Misc.h"
/*Type and constant
definitions---------------------------------------------------------*/
/*Global
variables---------------------------------------------------------------------*/
unsigned char LlaveID[8];
//64bits (8bytes) de ROM
unsigned char LlaveIDHex[17]; //16nibles de texto hexa + null
unsigned char cOneWireCRC;
unsigned char cOneWireCRChex[3];
bit OneWirePresent;
bit OneWireTrigger=0;
/
*Functions----------------------------------------------------------------------------*/

void OneWireMonitor (void);


void OneWireReset (void);
void OneWireTXbyte (unsigned char cByte);
unsigned char OneWireRXbyte (void);
void OneWireCRCcheck(unsigned char cByte);
void OneWireMonitor (void)
{
unsigned char i;
OneWireReset();
if (OneWirePresent) {
GotoXY(3,0);
PutString("Llave presente:");
}
else {
GotoXY(3,0);
PutString("Llave AUSENTE!:");
}
GotoXY(4,0);
OneWireTXbyte(READ_ROM);
cOneWireCRC=0;
for(i=0;i<8;i++) {
LlaveID[i]=OneWireRXbyte();
Char2Hex(LlaveID[i],&LlaveIDHex[2*i]);
if(i<7) OneWireCRCcheck(LlaveID[i]);
}
PutString(LlaveIDHex);
GotoXY(5,0);
PutString("CRC: ");
Char2Hex(cOneWireCRC,cOneWireCRChex);
PutString(cOneWireCRChex);
OneWireTrigger=0;
}
void OneWireReset (void)
{
GIE=0;
OneWireHI();
OneWirePresent=0;
//inicializo flag
OneWireLO();
//mando un low por 500us (tRSTL)
DelayUS(250);
//OneWireHI();
//OneWireLO();
//DelayUS test
DelayUS(250);
OneWireHI();
//levanto el low
DelayUS(70);
//espero 70us (tPDL)
if(!OneWireRXPORT) OneWirePresent=1; //si me responde con low hay llave
DelayUS(200);
//completo con 430us (tRSTH)
DelayUS(230);
GIE=1;
}
void OneWireTXbyte (unsigned char cByte)
{
unsigned char i;
GIE=0;
for(i=0;i<8;++i) {
//8 bits a enviar

OneWireLO();
//mando un low por 3us (tLOW1)
DelayUS(3);
//REVISAR MACRO PARA CLOCK 8MHZ= Ciclos de .5us
(@10MHz= .4us)
if (cByte&0x01) OneWireHI();
//si el 1er bit es '1' mando un '1'
DelayUS(60);
//mantengo el low por 60us (tLOW0)
OneWireHI();
//levanto del low
DelayUS(2);
//REVISAR MACRO PARA CLOCK 8MHZ= Ciclos de .5us
(@10MHz= .4us)
cByte>>=1;
//despazo para enviar siguiente bit
}
GIE=1;
}
unsigned char OneWireRXbyte (void)
{
unsigned char i;
unsigned char cByte=0;
GIE=0;
for(i=0;i<8;++i) {
OneWireLO();
//mando un low por 6us (a partir del low hasta (*) no
deben pasar ms de 15us)
DelayUS(6);
OneWireHI();
//levanto el low
DelayUS(4);
//espero 4us
cByte>>=1;
//desplazo el bit a la derecha
if(OneWireRXPORT) cByte|=0x80; //(*) si leo un '1' lo almaceno (los bits
entran de izq a der)
DelayUS(50);
//espero 50us (tSLOT)
}
GIE=1;
return cByte;
}
//Calcula CRC-8 byte a byte.
//La variable cOneWireCRC se debe incializar el principio del clculo con
el valor '0'.
//El polinomio se carga LSb-first (al revs), y adems como
//el XOR solo se ejecuta cuando el bit ms pesado es '1', el 9no bit del
polinomio
//se elimina porque se sabe que el resultado es '0' (1^1=0); con lo que
el polinomio
//CRC-8-Dallas/Maxim (DOW CRC)= X^8 + X^5 + X^4 + 1 nos queda 10001100
#define POLYNOMIAL 0x8C
void OneWireCRCcheck(unsigned char cByte)
{
unsigned char cbit;
cOneWireCRC ^= cByte;
for (cbit = 0; cbit < 8; cbit++) {
if (cOneWireCRC & 0x01)
//si el 1er bit es 1
cOneWireCRC = (cOneWireCRC >> 1) ^ POLYNOMIAL;//hacer el XOR y desplazar
else cOneWireCRC = (cOneWireCRC >> 1);//no hacer nada y desplazar
}
}
/*
Esto d 0xD0:
#define POLYNOMIAL 0x8C

void OneWireCRCcheck(unsigned char cByte)


{
unsigned char cbit;
cOneWireCRC ^= cByte;
for (cbit = 0; cbit < 8; cbit++) {
if (cOneWireCRC & 0x80)
//si el 1er bit es 1
cOneWireCRC = (cOneWireCRC << 1) ^ POLYNOMIAL;//hacer el XOR y desplazar
else cOneWireCRC = (cOneWireCRC << 1);//no hacer nada y desplazar
}
}
Y esto tambin d 0xD0:
#define POLYNOMIAL 0x8C
void OneWireCRCcheck(unsigned char cByte)
{
unsigned char cbit;
cOneWireCRC ^= cByte;
for (cbit = 0; cbit < 8; cbit++) {
if (cOneWireCRC & 0x01)
//si el 1er bit es 1
cOneWireCRC = (cOneWireCRC >> 1) ^ POLYNOMIAL;//hacer el XOR y desplazar
else cOneWireCRC = (cOneWireCRC >> 1);//no hacer nada y desplazar
}
}
*/

You might also like