'codigo para leer el protocolo wiegand en 4mhz con la imprescindible ayuda de dogflu66
'autor: yo
'vresion:22/3/2013 23:38 hs
'...
' solo para simular, pero con algunas correcciones se puede grabar en el pic y esta probado, funciona!
' el codigo no tiene waitms ni otro tipo de esperas para la simulacion
Define CLOCK_FREQUENCY = 4
AllDigital
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4
Define LCD_RSREG = PORTA
Define LCD_RSBIT = 2
Define LCD_RWREG = PORTA
Define LCD_RWBIT = 1
Define LCD_EREG = PORTA
Define LCD_EBIT = 0
Define LCD_COMMANDUS = 1000
Define LCD_DATAUS = 50
Define LCD_INITMS = 39
TRISB = %00000000
TRISB.0 = 1
TRISB.1 = 1
Dim lectura_rfid As Long
Dim existe_eeprom As Bit
Dim x As Byte
'..............'estos valores son solo para simular.............................
x = 25 'la variable una vez grabado el pic debe estar a '0'
write 0, 1 ' el banco 0 indica que hay un registro en la memoria
Write 253, 93 'escribe en la eeprom los valores de la variable
Write 254, 85 'long de lectura, (solo los bytes que nos interesan
Write 255, 245 'de la trama wiegand)
lectura_rfid = %11111010101010101010111011 'valor que simula la lectura de la trama
'.......................................................................
Lcdinit
main:
Gosub lee_tag
If x = 25 Then 'si completo la lectura de la trama de bits
lectura_rfid = ShiftRight(lectura_rfid, 1) 'agrega un bit a la variable para eliminar el primer bit del protocolo
lectura_rfid.4B = 0 'pone el byte mas significativo a 0
existe_eeprom = busca_eeprom(lectura_rfid) 'busca si en la eeprom existe este registro leido.
Gosub printlcd 'imprime en la pantalla el resultado de la busqueda
x = 0 'se resetea la variable que pone al programa en espera de una nueva lectura de datos
Endif
Goto main
End
lee_tag: 'rutina que ingresa los datos por el puerto b en protocolo wiegand
If PORTB.0 = 1 Then 'solo para simular, el real valor de este condicional es "if portb.0 = 0 then
While PORTB.0 = 1 'espera forzada para que la lectura no produzca fallos de interpretacion
Wend
lectura_rfid = _bittrue(lectura_rfid, x) 'va a la funcion que pone el bit "x" a 1
x = x + 1 'aumenta el contador x
Endif
If PORTB.1 = 1 Then 'solo para simular, el real valor de este condicional es "if portb.1 = 0 then
While PORTB.1 = 1 'espera forzada para que la lectura no produzca fallos de interpretacion
Wend
lectura_rfid = _bitfalse(lectura_rfid, x) 'va a la funcion que pone el bit "x" a 0
x = x + 1 'aumenta el contador x
Endif
Return
printlcd: ' sin comentarios...................................................................
Lcdcmdout LcdLine1Home
Lcdout "Id: ", #lectura_rfid
If existe_eeprom = 1 Then
Lcdcmdout LcdLine2Home
Lcdout "ACTIVADO "
Else
Lcdcmdout LcdLine2Home
Lcdout "DESACTIVADO "
Endif
Return
'funcion de busqueda en la eeprom. los saltos de a 3 bytes permiten guardar la trama de 24 bits obtenida en la lectura
'del protocolo. el primer banco de memoria se deja libre para utilizarlo como indice y poder agregar registros en la
'direccion adecuada a medida que aumenta el numero de tags que leera el sistema.
Function busca_eeprom(valor_r As Long) As Bit 'la funcion carga en un bit, true o false segun encuentre o no el tag leido
Dim x As Byte, 'variable de la funcion que indexa la direccion de busqueda
Dim busca As Long 'alojara el resultado byte a byte de lo almacenado en la eeprom
x = 1 'se asigna este valor para saltear el banco de memoria '0'
busca.4B = 0 'se pone a '0' el byte mas significativo de la variable
While x < 254 'si x supera este numero, sale del bucle, esto puede producirse por dos motivos: 1 encontro un registro
'......................que coincide el tag leido, o 2 llego al fin de la eprom sin encontrar ninguno coincidente
Read x, busca.LB 'aloja en un byte de la variable el byte que lee de la eeprom
x = x + 1 '.........aumenta el contador para cambiar la direccion de memoria
Read x, busca.HB 'aloja en un byte de la variable el byte que lee de la eeprom
x = x + 1 '.........aumenta el contador para cambiar la direccion de memoria
Read x, busca.3B 'aloja en un byte de la variable el byte que lee de la eeprom
If valor_r = busca Then 'si encuentra el registro arroja 1
busca_eeprom = 1 ' pone a true la variable
x = 252 'pone la variable a 252, para que a continuacion, cuando se ejecute x = x + 3 supere el tope de 254 y salga del bucle
Else 'si no encuentra, arroja 0
busca_eeprom = 0 ' pone a false la variable
Endif
x = x + 3 'aumenta el contador de la variable que lee la direccion de la memoria de tres en tres, (bytes)
Wend
End Function
'funcion, exelentemente explicada por dogflu66, (nada que agregar)
Function _bittrue(_reg As Long, _bit As Byte) As Long
Dim _byte As Long
_byte = 1
_byte = ShiftLeft(_byte, _bit)
_reg = _reg Or _byte
_bittrue = _reg
End Function
'funcion, exelentemente explicada por dogflu66, (nada que agregar)
Function _bitfalse(_reg As Long, _bit As Byte) As Long
Dim _byte As Long
_byte = 1
_byte = ShiftLeft(_byte, _bit)
_byte = _byte Nand 0xffff
_reg = _reg And _byte
_bitfalse = _reg
End Function
bueh, solo me falta hacer la rutina que graba en la eeprom los tags que van a estar registrados, cuando la termine, la publicare completa y quiza con alguna mejora.
Gracias dogflu66 el codigo, y sobre todo la velocidadde procesamiento aumento infinitamente con tus aportes y consejos! gracias por todo! sobre todo, por el tiempo que has dedicado a explicar las funciones, el manejo de bits con tanta claridad.
la ultima duda que me queda, (si esto ya no es un abuso), es saber si una funcion puede arrojar dos o mas variables como resultado.
Por ejemplo si pudiera saber, (cuando encuentra un registro en la eeprom), en que posicion de la memoria lo encontro, esto permitiria que un tag especifico tenga acceso a gestionar la base de datos del sistema, altas, bajas etc..... ya seria un lujo.....
Se me ocurrio hacer una variable word en lugar de bit y utilizar un byte para saber si encontro o no, y el otro byte para saber en que banco lo encontro....(hasta ahi llega mi conocimiento).