Hola a todos, amables foristas de esta pagina.
Llevo un tiempo trabajando en la comunicación entre un botón "ibutton" de Maxim y un pic. Hasta ahora todo me había marchado muy bien , y ya he logrado implementar la comunicación entre el botón y el pic. Se que ya he leído bien el botón , por que cuando comparo los resultados que captura el ICD2 con los que me da un lector para la pc , ambos coinciden.
Publicare mi programa al final de este mensaje , para los que anden buscando un ejemplo de como lograr esto.
Mi problema es a la hora de tratar de implementar el calculo del DOW(CRC).
El DOW(CRC) Se utiliza para verificar si los datos del ROM quedaron bien en el PIC. Para calcularlo se usa el siguiente diagrama:
De ahí creo entiendo lo siguiente:
Primero que nada el diagrama es la representación a nivel hardware y creo que el polinomio de arriba es la representación matemática , pero según entiendo se usa una u otra manera para explicarlo. No las 2 juntas.
Hablando del polinomio encontré una pagina
http://www.employees.org/~surendra/asic/crc.htmldonde explica los cálculos de CRC como una división , donde el polinomio es interpretado como el el lugar que ocupan los bits 1 en el numero binario.
Ejemplo
Si el polinomio fuera = (x^3 + x^2 + x^0)
El numero binario seria 1101
mas adelante explica que el CRC es una división con este numero como el divisor y los datos a chekar como el dividendo y al final lo que queda de residuo es el CRC. (No he conseguido que eso funcione). En el caso del polinomio de la imagen entiendo que quedaría un numero de 10bits
1001100001
Poniendo atención al diagrama intente lo siguiente:
El diagrama mas bien me da a entender que lo que se necesita es una serie de operaciones para cada bit a revisar. Empezando por una operacion XOR entre el bit de entrada y X8 . Lo cual asumi que era el bit de salida. Despues entendi que cada etapa era un shift del shift register , y las operaciones XOR despues de X4 y X5 entendi que eran entre el resultado del primer XOR y el bit donde estubiera en ese momento el LSB del shift register. Denuevo al final quedan bits de mas ya que son 9 etapas .
Bueno ojala que alguien me pueda dar una mano con esto. Estoy realmente muy atorado desde hace tiempo.
De antemano muchas gracias .
"P3" ESTE ES UN BUEN PROGRAMA DE EJEMPLO EN ENSAMBLADOR PARA IMPLEMENTAR COMUNICACIONES ENTRE UN IBUTTON DE DALLAS SEMICONDUCTORS Y UN PIC .
;P3.ASM********************************************************************************
;
;**************************************************************************************
;ENCABEZADO
#INCLUDE <P16F88.INC>
LIST P = 16F88
ERRORLEVEL - 302
ERRORLEVEL - 305
;**************************************************************************************
;VARIABLES
cblock 0x20
IOBYTE
TMPO
COUNT
TEMP
TEMP1
TEMP2
PDBYTE
DATO1
DATO2
DATO3
DATO4
DATO5
DATO6
DATO7
DATO8
endc
;**************************************************************************************
;CONSTANTES
;CONSTANTES DE PROGRAMA
constant DQ=.0
;CONSTANTES DE 1 WIRE
constant RDROM=0x33
constant CONVERT=0x44
constant SKPROM=0xCC
;**************************************************************************************
;VECTORES
ORG 0X00
GOTO INICIO
;ORG 0X04
;GOTO INTERRUPCION
;*************************************************************************************
;LIBRERIAS EXTRA
#INCLUDE <1WIRE.INC>
;===================================================================================
INICIO
;===================================================================================
;-----------------------------------------------------------------------------------
CONFIGURACION
;-----------------------------------------------------------------------------------
BCF STATUS,RP0 ;BANCO 0
CLRF PORTA ;INICIALIZA PUERTO A
CLRF PORTB ;INICIALIZA PUERTO B
BSF STATUS,RP0 ;BANCO 1
CLRF ANSEL ;TODOS LOS PINES EN MODO DIGITAL
MOVLW B'11111111' ;LITERAL A W
MOVWF TRISA ;CONFIGURA TODO EL PUERTO A COMO ENTRADAS
MOVWF TRISB ;CONFIGURA TODO EL PUERTO B COMO ENTRADAS
BCF TRISB,3 ;CONFIGURA RB3 COMO SALIDA
BCF STATUS,RP0 ;BANCO 0
;-----------------------------------------------------------------------------------
;CICLO DE ESPERA (*** SUBSTITUIR CON SLEEP MAS INTERRUPCION AL FINAL ***)
;-----------------------------------------------------------------------------------
BTFSC PORTB,0 ;ESPERA UN CAMBIO EN RBO (DESPUES USARE UNA INTERRUPCION POR FLANCO DE CAIDA)
GOTO $-1 ;REGRESA UNA INSTRUCCION
;-----------------------------------------------------------------------------------
;POSIBLE BOTON EN EL LECTOR
;-----------------------------------------------------------------------------------
CALL RESET ;Busca una respuesta de precencia de algun boton(esta en 1WIRE.INC)
MOVLW 0x33 ;Literal a w (33h = Read ROM)
CALL TXBYTE ;Manda la instruccion 33h al boton (parte de 1WIRE.INC)
CALL RXBYTE ;Recibe la primer respuesta del boton "Family Code"
;(en el caso de ibutton DS1904 deberia ser 24h))
MOVF IOBYTE,W;Mueve el dato a w
MOVWF DATO1 ;Guarda el dato en "DATO1"
CALL RXBYTE ;Recibe segunda respuesta
;(primeros 8 bit de numero de serie)
MOVF IOBYTE,W;Mueve dato a W
MOVWF DATO2 ;Guarda el dato en "DATO2"
CALL RXBYTE ;Resibe tercer respuesta
;(bits 8-16 del numero de serie del boton)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO3 ;Guarda el dato en "DATO3"
CALL RXBYTE ;Recibe cuarto byte de respuesta
;(bits 16-24 de numero de serie)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO4 ;Guarda el dato en "DATO4"
CALL RXBYTE ;Recibe cuarto byte de respuesta
;(bits 24-32 de numero de serie)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO5 ;Guarda el dato en "DATO5"
CALL RXBYTE ;Recibe cuarto byte de respuesta
;(bits 32-40 de numero de serie)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO6 ;Guarda el dato en "DATO6"
CALL RXBYTE ;Recibe cuarto byte de respuesta
;(bits 40-48 de numero de serie)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO7 ;Guarda el dato en "DATO7"
CALL RXBYTE ;Recibe cuarto byte de respuesta
;(bits 1-8 de CRC)
MOVF IOBYTE,W;Mueve el dato a W
MOVWF DATO8 ;Guarda el dato en "DATO8"
NOP
NOP
NOP
;-----------------------------------------------------------------------------------
;====================================================================================
END
;====================================================================================
LIBRERIA 1WIRE.INC
; *******************************************************
;
; Protocolo de comunicación 1-Wire de Dallas para PIC16F88
;
; *******************************************************
; *******************************************************
; MACROS
; *******************************************************
ALTO:MACRO ; DECLARA UNA NUEVA MACRO "ALTO"
BSF STATUS,RP0 ; BANCO 1
BSF TRISB,0 ; PON AL PIN DQ(RB0) EN ESTADO DE ALTA IMPEDANCIA
; (ALTA IMPEDANCIA = ENTRADA CON PULLUP)
BCF STATUS,RP0 ; BANCO 0
ENDM ; FIN DE MACRO "ALTO"
; --------------------------------------------------------
BAJO:MACRO ; DECLARA UNA NUEVA MACRO "BAJO"
BCF STATUS,RP0 ; BANCO 0
BCF PORTB, 0 ; LIMPIA PIN(RB0)
BSF STATUS,RP0 ; BANCO 1
BCF TRISB, 0 ; RBO COMO SALIDA CON 0
BCF STATUS,RP0 ; BANCO 0
ENDM ; FIN DE MACRO "BAJO"
; --------------------------------------------------------
WAIT:MACRO TIME ;DECLARA MACRO "WAIT" CON PARAMETRO DE ENTRADA "TIME"
;ESTE MACRO ES UN RETARDO QUE DURA
;UN TIEMPO "TIME" EXPRESADO EN MICROSEGUNDOS
;QUE DEBEN SER MULTIPLOS DE 5µs
;***Esta macro se me hace increible***
;¿Como es que el parametro "TIME" puede ser mayor a 255?
;¿Como es que funciona la division con el assembler?
;Ojala alguien pudiera darme alguna info de como funciona "victor.terr@gmail.com"
MOVLW (TIME/5)-1 ;1µs
MOVWF TMPO ;1µs
CALL WAIT5U ;2µs
ENDM ;termina la macro "WAIT"
; *******************************************************
; Dallas Semiconductor 1-Wire ROUTINES
; *******************************************************
WAIT5U:
;RETARDO 5µs
NOP ;1µs
NOP ;1µs
DECFSZ TMPO,F ;1µs o 2µs cuando sale del ciclo
GOTO WAIT5U ;2µs
RETLW 0 ;2µs REGRESA
;(***No se por que no se usa RETURN***)
; -------------------------------------------------------
RESET: ;RUTINA RESET(ES EL INICIO DE CUALQUIER COMUNICACCION CON EL BOTON
ALTO ;NORMALMENTE YA ESTA EN ESTADO DE ALTA IMPEDANCIA EL BUS
CLRF PDBYTE ;LIMPIA EL BYTE DONDE SE GUARDARA EL BIT DE PRECENCIA(PD)
BAJO ;PON RB0 CON UN ESTADO DE SALIDA CON 0
WAIT .500 ;ESPERA 500µs EN ESE ESTADO
ALTO ;REGRESA AL ESTADO DE ALTA IMPEDANCIA
WAIT .70 ;ESPERA 70µs EN ESE ESTADO
BTFSS PORTB,0 ;BUSCA LA RESPUESTA DE PRECENCIA DEL BOTON
INCF PDBYTE,F;SI EL BOTON ESTA PRESENTE INCREMENTA PD BYTE
WAIT .400 ;ESPERA 400µs
RETLW 0 ;REGRESA
;(***No se por que no se usa RETURN***)
; --------------------------------------------------------
RXBYTE: ;RUTINA PARA LA LECTURA DE 1 BYTE DE INFO DEL BOTON
MOVLW .8 ;MUEVE VALOR LITERAL "8 decimal" A REGISTRO W
MOVWF COUNT ;MUEVE EL VALOR A LA VARIABLE CUENTA
ALTO ;RB0 YA DEBERIA DE ESTAR EN ALTA IMPEDANCIA
RXLP: ;CICLO DE LECTURA
BAJO ;ESTADO DE BAJA IMPEDANCIA EN RB0
;(LE INDICARA AL BOTON QUE EL PIC ESTA LISTO PARA RECIBIR DATOS)
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us; MANTIENE EL ESTADO DE BAJA IMPEDANCIA
NOP ;NO OPERA ESPERA 1us; DURANTE 6us
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us;
ALTO ;ESTADO DE ALTA IMPEDANCIA EN RB0
;(EL BOTON SE CARGARA DURANTE DESPUES MANDARA RESPUESTA)
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us;
NOP ;NO OPERA ESPERA 1us; 4µs
BCF STATUS,C;LIMPIA EL BIT DE ACARREO
BTFSC PORTB,0 ;VE SI RB0 ESTA EN 0
BSF STATUS,C ;SI ESTA EN 0 PON EN 1 EL BIT DE ACARREO
RRF IOBYTE,1 ;CARGA EL RESULTADO DEL BIT DE ACARREO EN IOBYTE
WAIT .50 ;ESPERA 50us
ALTO ;YA DEBERIA DE ESTAR EN ALTA IMPEDANCIA
DECFSZ COUNT,F ;DECREMENTA LA CUENTA DE BITS
GOTO RXLP ;VE AL CICLO DE LECTURA
RETLW 0 ;REGRESA
; --------------------------------------------------------
TXBYTE: ; ENVIA UN BYTE AL BOTON (CARGAR PRIMERO EL BYTE EN W)
MOVWF IOBYTE ; MUEVE W AL BYTE DE ENTRADA SALIDA (IOBYTE)
MOVLW .8 ; INICIA UNA CUENTA DE BITS EN 8 DECIMAL
MOVWF COUNT ; MUEVE EL 8 A VARIABLE CUENTA
TXLP: ; CICLO ESCRITURA
BAJO ; ESTADO DE BAJA IMPEDANCIA
NOP ; NO OPERA ESPERA 1us;
NOP ; NO OPERA ESPERA 1us;
NOP ; NO OPERA ESPERA 1us; ESPERA 3µs
RRF IOBYTE,F ; ROTA A LA DERECHA EL BIT DE ENTRADA SALIDA "IOBYTE"
BSF STATUS,RP0 ; BANCO 1
BTFSC STATUS,C ; REVISA EL BIT DE ACARREO
BSF TRISB,0 ; ESTADO DE ALTA IMPEDANCIA EN RB0 SI ACARREO ES 1 (MANDA UN 1)
BCF STATUS,RP0 ; BANCO 0
WAIT .60 ; ESPERA 60us
ALTO ; ALTA IMPEDANCIA EN RB0 (MANDA UN 0)
NOP ; NO OPERA ESPERA 1us;
NOP ; NO OPERA ESPERA 1us; ESPERA 2µs
DECFSZ COUNT,F ; DECREMENTA LA CUENTA DE BITS
GOTO TXLP ; VE AL CICLO DE ESCRITURA
RETLW 0 ; REGRESA
; --------------------------------------------------------