TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: groundman en 14 de Diciembre de 2013, 17:22:37

Título: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 14 de Diciembre de 2013, 17:22:37
hola.estoy buscando una rutina en ensamblador para el calculo del crc del sensor de temperatura DS18B20.
pero todo lo que encuentro esta en ccs

hay dos formas de generar los CRC.con tabla y sin tabla.con tabla es mas rapido pero ocupa mas memoria.y sin tabla es mas lento pero
ocupa menos espacio.

seria bueno tener las dos opciones.pero por el momento necesito velocidad asi que necesito la rutina con tabla.
ya hice un codigo de CRC A001 para MODBUS pero me costo mucho trabajo.

si pudiera ahorrarme el trabajo,mucho mejor.ya que el tiempo no es de lo que mas dispongo.

he encontrado un codigo en ccs que quisiera saber si alguien puede convertirlo.

Código: [Seleccionar]
Practice:
Here the table driven crc-8 we use. Not sure what the polynomial is.
First is the table:

const int8 crc8_Table[ ] =
{
     0,  94, 188, 226,  97,  63, 221, 131, 194, 156, 126,  32, 163, 253,  31,  65,
   157, 195,  33, 127, 252, 162,  64,  30,  95,   1, 227, 189,  62,  96, 130, 220,
    35, 125, 159, 193,  66,  28, 254, 160, 225, 191,  93,   3, 128, 222,  60,  98,
   190, 224,   2,  92, 223, 129,  99,  61, 124,  34, 192, 158,  29,  67, 161, 255,
    70,  24, 250, 164,  39, 121, 155, 197, 132, 218,  56, 102, 229, 187,  89,   7,
   219, 133, 103,  57, 186, 228,   6,  88,  25,  71, 165, 251, 120,  38, 196, 154,
   101,  59, 217, 135,   4,  90, 184, 230, 167, 249,  27,  69, 198, 152, 122,  36,
   248, 166,  68,  26, 153, 199,  37, 123,  58, 100, 134, 216,  91,   5, 231, 185,
   140, 210,  48, 110, 237, 179,  81,  15,  78,  16, 242, 172,  47, 113, 147, 205,
    17,  79, 173, 243, 112,  46, 204, 146, 211, 141, 111,  49, 178, 236,  14,  80,
   175, 241,  19,  77, 206, 144, 114,  44, 109,  51, 209, 143,  12,  82, 176, 238,
    50, 108, 142, 208,  83,  13, 239, 177, 240, 174,  76,  18, 145, 207,  45, 115,
   202, 148, 118,  40, 171, 245,  23,  73,   8,  86, 180, 234, 105,  55, 213, 139,
    87,   9, 235, 181,  54, 104, 138, 212, 149, 203,  41, 119, 244, 170,  72,  22,
   233, 183,  85,  11, 136, 214,  52, 106,  43, 117, 151, 201,  74,  20, 246, 168,
   116,  42, 200, 150,  21,  75, 169, 247, 182, 232,  10,  84, 215, 137, 107,  53
} ;

To use the table:

crc = initial_Value ;
// The initial value is usually zero, but non-zero values are better.
// You can pick any byte you want, just be sure it's the same every time.

for ( each byte_Value in the message or file )
{
   crc = crc8_Table[ crc ^ byte_Value ] ;
}

// Some CRC implementations xor the final value with some other value.
crc = crc ^ xor_Value
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 15 de Diciembre de 2013, 11:23:47
pues la verdad es que estoy un poco pegado en C.pero creo poder entender lo que dice el codigo.corregirme si me equivoco.

en esta direccion: http://ghsi.de/CRC/index.php?Polynom=100110001&Message=0087

tenemos un generador de CRC online.introduciendo el polinomy "00110001" =0x131 y poniendo los datos 0087 el crc obtenido es 0xed.asi que realizo la practica:


en la linea crc =[crc ^ xor_value]

valor inicial de rcr=0x00

si tenemos los valores 0x00,0x87. el primer calculo seria crc=[0x00 xor 0x00] = 0X00

el valor en la tabla de la posicion 0x00= .0

en el segundo calculo                                     crc=[0x00 xor 0x87] =crc[87] que en la tabla corresponde al valor 0x0f= 15 decimal.

y esto es lo que no me cuadra.ya que el valor que da el generador es 0xed

Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 15 de Diciembre de 2013, 15:21:41
al final me veo haciendo el codigo a mano.y no precisamente lo de las tablas.ya que no lo entiendo.no se que relacion hay entre los numeros y
el indexado a las tablas.

he tenido que aprenderme el procedimiento de generacion del CRC.asi que lo explicare para el que le haga falta:

GENERACION DE CRC PARA POLINOMIO 0X131

generaremos el CRC de dos valores exagesimales. 0xB1 y 0xA2

                0xB1      0xA2   0x00   <-    valor inicial"0x00"

  
Código: [Seleccionar]
 principio ->      101100011010001000000000
    polinomio  0x0131   100110001
_________
    XOR                 001010010
                          101001001      ->eliminamos los ceros de la izquierda.y bajamos del principio dos cifras porque son dos ceros los eliminados
    polinomio             100110001
                          _________
                xor       001111000
                            111100000    ->eliminamos 2 ceros bajamos 2 siguienes cifras
           polinomio        100110001
                            _________
                xor         011010001
                             110100010   ->eliminamos 1 cero bajamos 1 cifra
              polinomio      100110001
                             _________
                  xor        010010011
                              100100111      ->eliminamos 1 cero bajamos 1 cifra
               polinomio      100110001
                              __________
                     xor      000010110
                                  101100000       ->eliminamos 4 ceros bajamos 4 cifras
                   polinomio      100110001
                                  _________
                       xor        001010001
                                    101000100         ->eliminamos 2 ceros bajamos 2 cifras
                      polinomio     100110001
                                    _________
                           xor      001110101
                                      111010100          ->eliminamos 2 ceros bajamos 2 cifras
                        polinomio     100110001
                                      _________
                              xor     011100101
                                       111001010           ->eliminamos 1 cero bajamos 1 cifra
                        polinomio      100110001
                                       _________
                               xor     011111011           resultado: 0xFB


esta operacion es para calcular el crc de dos bytes.pero no se como hacer para calcular una cadena mas larga.haber si lo veo.

Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: tapi8 en 15 de Diciembre de 2013, 16:34:58
Grounman has visto este hilo de Brunof:

http://www.todopic.com.ar/foros/index.php?topic=25627.0;wap2

A ver si te sirve de algo.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: BrunoF en 15 de Diciembre de 2013, 17:01:12
Hola groundman.

La tabla se usa como el código explica.

Asumiendo que tenés que generar el CRC de la cadena, por ejemplo: [63, 128, 254]

Teniendo la tabla sólo te resta hacer:
crc= 0
crc = crc8_Table[ crc xor 63 ] = crc8_Table[0 xor 63] = crc8_Table[63] = 255
crc = crc8_Table[ crc xor 128 ] = crc8_Table[255 xor 128] = crc8_Table[127] = 185
crc = crc8_Table[ crc xor 254 ] = crc8_Table[185 xor 254] = crc8_Table[71] = 197

Por lo tanto, el crc de la cadena [63, 128, 254] para el polinomio 0x131 sería 197. Algunos suelen hacer una XOR al final del valor resultante con 255 (u otro valor), eso tendrás que verlo en la implementación del dispositivo en cuestión.

Saludos.








Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 15 de Diciembre de 2013, 20:51:17

muchas gracias por el ejemplo.ya tengo medio hecha la rutina.pero necesito una trama de crc correcta para comparar valores.
la trama mas correcta que se me ocurre es la que he cogido del DS18b20 en las practicas que estoy haciendo.he cogido dos tramas del Scratchpad

el Scratchpad tiene 9bytes. el ultimo es el crc de los 7primeros bytes.almenos es lo que he entendido del datasheet.

trama1: 5C,01,1E,19,7F,FF,04,10,9E
trama2: 00,02,FF,FF,7F,FF,0C,10,D5

y esta trama de identidad 28,30,c5,b8,00,00,00,8e

pero en el generador online que puse antes.no salen los datos que debieran.no se donde esta el error.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: Picuino en 16 de Diciembre de 2013, 06:23:53
La tabla es distinta para cada polinomio.
Tienes que generar una tabla para tu polinomio para que el código funcione correctamente.

Saludos
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: Tisco en 16 de Diciembre de 2013, 07:47:21
Si te sirve de ayuda, te pongo el código que uso para generar el CRC para ese dispositivo.
Está en C, pero te puede servir para comprobar que tus cálculos son correctos.

Código: C
  1. uint8_t OWCRC(uint8_t *data, uint8_t lengh)
  2. {
  3.     uint8_t i, j;
  4.     uint8_t aux, CRC=0;
  5.     for (i = 0; i < lengh; i ++) {
  6.         aux = data[i];
  7.         for (j=0; j<8; j++) {
  8.             if ((aux&0x01) ^ (CRC&0x01)) {
  9.                 CRC ^= 0x18;
  10.                 CRC >>= 1;
  11.                 CRC |= 0x80;
  12.             }
  13.             else CRC >>= 1;
  14.             aux >>= 1;
  15.         }
  16.     }
  17.     return CRC;
  18. }

Para usarla en C:
Código: C
  1. OWCRC(OWdata, 8);
donde OWdata hace referencia a los datos sobre los que calcular el CRC.

Espero que te sirva.

Un saludo.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 16 de Diciembre de 2013, 11:07:58
mirare el codigo.pero mi intencion es usar tablas porque le ahorro tiempo al pic.se supone que la tabla que he encontrado es para el polinomio 0x131
que es el que usa el DS18B20. pero ya estoy en duda.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: tapi8 en 16 de Diciembre de 2013, 15:21:35
Vereis es que tengo una preguntonta  :lol: :lol:

¿Que es y para que sirve el CRC?
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: tapi8 en 16 de Diciembre de 2013, 15:46:46
Bueno ya decia que era una preguntonta, ayer busque y no encontre una respuesta simple, todas eran muy complicadas, pero la wikipedia si trae una respuesta para tontos como yo  :D

http://es.wikipedia.org/wiki/Detecci%C3%B3n_y_correcci%C3%B3n_de_errores

Perdonad la interrupcion.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: BrunoF en 16 de Diciembre de 2013, 16:47:32
Hmmm me parecía ya haberlo visto a esto.

Estás de suerte groundman, mirá este post: http://www.todopic.com.ar/foros/index.php?topic=23605

Saludos.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 16 de Diciembre de 2013, 19:04:41
muchas gracias a todos por la ayuda.estoy implementado lo que exponeis pero tengo algunas dudas.

en la rutina CALC_CRC8 hay una linea movlw   POLY .que aparte de que el compilador me da error en   #DEFINE POLY  0X8C

no entiendo para que es ese numero.si es que el polinomio es 0x131.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: BrunoF en 16 de Diciembre de 2013, 19:13:07
Qué compilador te da error? El MPASM?

Para calcular el CRC8 mediante el método que utiliza ese algoritmo, se utiliza lo llaamdo polinomio invertido, que del polinomio 0x131 resulta ser el 0x8C.

Saludos.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 16 de Diciembre de 2013, 20:48:09
ha sido error mio.tenia un registro con el mismo nombre.
encuanto a la generacion del crc el programa que hicistes ya me funciona.

he hecho varias pruebas con diferentes codigos y no me han funcionado.pero al final he encontrado uno que si.

28
30
c5
b8
00
00
00
8e

que en tu codigo me da crc 8e. aunque por el momento el crc on line no me da esos valores.haber si mañana hago mas pruebas.o si encuentro
otra pagina para generar codigos correctos.

y si encontrara la forma de usar la tabla,mucho mejor.ya que tengo memoria suficiente en el 18F2550 pero me falta velocidad.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: BrunoF en 16 de Diciembre de 2013, 22:54:52
A la tabla la podés generar a partir del  código que estás usando.

Tenés que iterar desde el 0 al 255 e ir guardando cada resultado en la tabla.

la tabla digamos que viene de hacer:

crc_table[0] = crc(0);
crc_table[1] = crc(1);
crc_table[2] = crc(2);
...
crc_table[255] = crc(255);

Saludos.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: Picuino en 17 de Diciembre de 2013, 05:55:16
¿Por qué no haces el algoritmo primero con una hoja excel?
Cuando te dé los resultados que quieres, lo codificas en ensamblador.

Saludos.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 17 de Diciembre de 2013, 18:17:26
hola.pues sigo con las mismas.

la trama del numero de identificacion del DS18B20 si que me da correctamente el CRC con la rutina de BrunoF.

28
87
d8
e6
03
00
00
b5-crc.          son 7 bytes los que se toman para calcular el crc en el DS18B20.

y en estas tramas recien leidas con el ICD2.fisicamente sobre un sensor,no me salen bien los crc.

51
01
1e
19
7f
ff
0f
10-    no se usa
c1-    crc



56
01
1e
19
7f
ff
0a
10-no se usa
ee- crc


55
01
1e
19
7f
ff
0b
10- no se usa
ef- crc


no tengo manera de saber si los crc son correctos para estas tramas.o quizas el orden de los bytes no se calculan de esta forma.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: Tisco en 17 de Diciembre de 2013, 18:36:24
¿estás seguro de que son 7 bytes? Hablo de memoria, pero creo recordar que eran 8.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 17 de Diciembre de 2013, 20:10:45
The ROM code CRC is calculated from the first 56 bits of the ROM code and is contained in the most significant byte of the ROM

es lo que dice el datasheet. ademas el codigo de BrunoF calcula el CRC a partir de 7bytes.

si lo raro es que la trama del numero de serie si que funciona.en el ejemplo que pone y en mi numero de serie de mi sensor.tengo 5 sensores mas.podria hacer
la prueba.y si los numeros de serie si que funcionan.igual no estoy leyendo bien algunos de los bytes del Scratchpad del sensor.

probare con el simulador del proteus en vez de hacerlo con el ICD2 haber si va a haber una mala interpretacion de datos.....
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: Tisco en 18 de Diciembre de 2013, 04:43:35
Echándole un ojo al datasheet:

Citar
Byte 8 of the scratchpad is read-only and contains the CRC code for bytes 0 through 7 of the scratchpad.
...
Citar
CRC bytes are provided as part of the DS18B20’s 64-bit ROM code and in the 9th byte of the scratchpad
memory. The ROM code CRC is calculated from the first 56 bits of the ROM code and is contained in the
most significant byte of the ROM. The scratchpad CRC is calculated from the data stored in the
scratchpad, and therefore it changes when the data in the scratchpad changes
...
Citar
This circuit consists of a shift register and XOR gates, and the
shift register bits are initialized to 0. Starting with the least significant bit of the ROM code or the least
significant bit of byte 0 in the scratchpad, one bit at a time should shifted into the shift register. After
shifting in the 56th bit from the ROM or the most significant bit of byte 7 from the scratchpad, the
polynomial generator will contain the re-calculated CRC. Next, the 8-bit ROM code or scratchpad CRC
from the DS18B20 must be shifted into the circuit.

Lo que tú estás buscando es el scratchpad CRC.

Un saludo!
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 18 de Diciembre de 2013, 18:21:35
en el Scratchpad es donde se gestionan todos los datos del DS18B20.y tiene 9bytes que van desde el byte0 al byte8.
el crc esta contenido en el byte 8.y su calculo se realiza con los primeros 7bytes.

eso es lo que he entendido del datasheet y todos los calculos los hago en base a esta informacion.

tanto cuado hago el calculo de la identidad como de la temperatura u otros comandos. espero no estar equivocado.
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 21 de Diciembre de 2013, 15:45:06
bueno.sigo atrancado en esto del calculo crc.sigo haciendo pruebas con esta pagina: http://ghsi.de/CRC/index.php?Polynom=100110001&Message=021cb801000000

y he aprendido algo de lo que son los polinomios.pero los calculos no me cuadran.

respecto a la formula ya la entiendo. P(x) = x8+ x5+ x4+ x0 que es el polinomo 131 ='100110001' lo que indica es el bit que va a estar a 1.
asi que '11111111'= P(x) = x7+ x6+ x5+ x4+ x3+ x2+ x1+ x0

esto lo veo sencillo.y tambien veo sencillo conseguir el crc de 2bytes.pero no se como hacerlo con 3 o mas.y he probado todas las combinaciones.


en el anterior calculo:

  
Código: [Seleccionar]
     0xB1      0xA2   0x00   <-    valor inicial"0x00"

    principio ->      101100011010001000000000
    polinomio  0x0131   100110001
_________
    XOR                 001010010
                          101001001      ->eliminamos los ceros de la izquierda.y bajamos del principio dos cifras porque son dos ceros los eliminados
    polinomio             100110001
                          _________
                xor       001111000
                            111100000    ->eliminamos 2 ceros bajamos 2 siguienes cifras
           polinomio        100110001
                            _________
                xor         011010001
                             110100010   ->eliminamos 1 cero bajamos 1 cifra
              polinomio      100110001
                             _________
                  xor        010010011
                              100100111      ->eliminamos 1 cero bajamos 1 cifra
               polinomio      100110001
                              __________
                     xor      000010110
                                  101100000       ->eliminamos 4 ceros bajamos 4 cifras
                   polinomio      100110001
                                  _________
                       xor        001010001
                                    101000100         ->eliminamos 2 ceros bajamos 2 cifras
                      polinomio     100110001
                                    _________
                           xor      001110101
                                      111010100          ->eliminamos 2 ceros bajamos 2 cifras
                        polinomio     100110001
                                      _________
                              xor     011100101
                                       111001010           ->eliminamos 1 cero bajamos 1 cifra
                        polinomio      100110001
                                       _________
                               xor     011111011           resultado: 0xFB


vuelvo a realizar el calculo con 3 bytes:


   
Código: [Seleccionar]
0xb1        0xa2       0xa3       0x00
       principio   ->          10110001101000101010001100000000
         poli                  100110001
                               _________
                               00101001001
                                 100110001
                                 _________
                                 00111100000
                                   100110001
                                   _________
                                   0110100010
                                    100110001
                                    _________
                                    0100100110
                                     100110001
                                     _________
                                     0000101111010
                                         100110001
                                         _________
                                         00100101110
                                           100110001
                                           _________
                                           0000111110011
                                               100110001
                                               _________
                                               0110000100
                                                100110001
                                                _________
                                                0101101010
                                                 100110001
                                                 _________
                                                 00101101100
                                                   100110001
                                                   _________
                                                   00101110100
                                                     100110001
                                                     _________
                                                     00100010100
                                                       100110001
                                                       _________
                                                       000100101  = 0x25
asi que no me cuadra el valor final de crc.cuando en la pagina del enlace el resultado es 0xC7
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 21 de Diciembre de 2013, 18:33:43
                                               
por finnnn he encontrado el problema. :-/ :-/ :-/ :-/ :-/ :-/

resulta que para calcular el crc de la rom del DS18b20 se usan los 7 primeros bytes del Scratchpad.por eso salian bien los calculos que se hacian con
la rutina de BrunoF.
pero para calcular el crc de la temperatura y quizas otros comandos.hay que hacer el calculo con los 8bytes primeros del Scratchpad.

modificare la rutina de BrunoF para el calculo de 8bytes.y cortejar resultados.
ya que he encontrado este calculo del crc online: http://www.datastat.com/sysadminjournal/maximcrc.cgi que parece funcionar perfectmente.

y ahora.me voy de juergaaaaa.que es sabado noche. :D
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 22 de Diciembre de 2013, 14:01:08
bueno.modifique la rutina de BrunoF.que le doy las gracias por esta.y que he adaptado para la gestion del DS18b20.esta rutina genera el crc para
la lectura de la rom"identidad" del DS18B20 de 7bytes  y el  de 8bytes.

aqui pongo el enlace: http://www.todopic.com.ar/foros/index.php?topic=24397.60
Título: Re: CRC con polinomio 0x131 para DS18B20
Publicado por: groundman en 22 de Diciembre de 2013, 17:31:07
y en la misma direccion pongo la rutina para la generacion del crc con el sistema de tabla.he hecho las comprobaciones y hay notables diferencias
en cuanto a la memoria usada y el tiempo de ejecucion.

asi que en el sistema sin tabla es una rutina que ocupa 37bytes con un tiempo de ejecucion de 717uS

y por tabla ocupa 288bytes y tarda 188uS en ejecutarse.en un 18f2550 trabajando a 48Mhz.