Hola de nuevo.
Tu codigo esta bien orientado, y es el metodo mas simple, a costa de desperdiciar bastante memoria FLASH del PIC.Pero igual es una posibilidad, y esta bien planteado, asi que vale!.
No me entendiste lo de las variables...
No utilice la misma posicion de memoria para 2 variables.
Lo que hice fue almacenar 2 numeros del codigo de seguridad por byte(posicion de memoria).
Fijate que si separas un byte en dos grupos de 4 bits(esto se llama nibble) obtenes algo asi:
XXXX XXXX
entonces, cada grupo ,considerandolo por separado, contiene 16 posibilidades(del .0 al .15).
Entonces, si el codigo de seguridad que elegis vos es: 1234567
podes almacenarlo asi:
Digit1y2code = 0x12
mirando mas cerca a sus nibbles:
0001 0010
Entonces, siguiendo con la misma logica:
Digit3y4code = 0x34
mirando mas cerca a sus nibbles:
0011 0100
Digit5y6code = 0x56
mirando mas cerca a sus nibbles:
0101 0110
Digit7 = 0x70
mirando mas cerca a sus nibbles:
0111 0000
Así decidi yo guardar el codigo de seguridad para ahorrar variables.
Errores que veo en tu codigo:
1)
movlw b"00001111"
movwf TRISA
No configuraste a entrada el RA4 como te ADVERTI!!!
Bueno..! Menos mal que no lo probaste! Sino ibas a generar cortocircuitos...
2)
digito1:
BTFSS PORTA,4
Goto digito1
Movf porta, W
movwf Digi1
digito2:
BTFSS PORTA,4
Goto digito2
Movf porta, W
movwf code2
Si entra un alto en RA4, es 99% probable que tu programa no funcione.
Pensemos en lo que sucederia mirando el comportamiento del circuito terminado en "camara lenta".
Entra un alto en RA4 supongamos que el valor que esta enviando el 8870 a los pines RA0-RA3 es el 0110(.6)
Tu programa va a correr como loco.
Digi1 va a valer .22
code2 va a valer .22
Digi3 va a valer .22
....
Incluso rele es muy probable que valga .22
¿Por que .22?
No filtraste el 1 del RA4, entonces estas guardando en realidad 00010110 = PORTA.RA4 ESTA EN ALTO..PENSA QUE ES LA CONDICION QUE IMPUSISTE 2 LINEAS ANTES...
¿Por que en todas las variables el mismo valor?
No pusiste una condicion de STOP. La duracion del puslo del StD, seguramente va a ser mas larga que una pasada de tu codigo.
Lo correcto seria:
digito1:
BTFSS PORTA,4
Goto digito1
Movf porta, W
movwf Digi1
BTFSC PORTA,4
GOTO $-1
digito2:
BTFSS PORTA,4
Goto digito2
Movf porta, W
movwf code2
3)
MOVF Digi1,W
XORWF "0001",W
BTFSC STATUS,Z
Call resetall
...
y los 7 restantes semejantes...
LA INSTRUCCION QUE TENES QUE UTILIZAR AHI ES LA XORLW, NO LA XORWF. Estas comparando el codigo ingresado con los registros especiales!Menudo lio!
Fijate : XORWF b"0001",W
ES LO MISMO QUE HACER XORWF TMR0,W
Porque el formato de la instruccion XORWF es asi:
[Label] XORWF registro(file),destino
4)
...
MOVF Digi7,W
XORWF "0111",W
BTFSC STATUS,Z
Call resetall
Movf tmp,w
ANDWF FLAG,W
XORWF PORTB,F
COMF TMP,W
MOVWF FLAG
GOTO digito1
Fijate, por mas que el codigo ingresado sea incorrecto, el programa hace exactamente lo mismo que si fuese correcto...
5)
resetall
clrf digi1
clrf code2
clrf digi3
clrf code4
clrf digi5
clrf code6
clrf digi7
Te falto el return. Si no lo pones, en cuanto la resetall sea llamado, el PIC no hace mas nada hasta que lo resetees o apagues y prendas.
Mira, me tome 5 min y te escribi esto, si te gusta, utilizalo. Lo unico que le faltaria es configurar el timer, y no lo hice porque antes
queria saber a que velocidad estas haciendo oscilar el PIC y de cuanto tiempo te parece que deberia ser el TIMEOUT.
Igualmente apoyo a que sigas utilizando tu codigo, simplemente porque TU lo programaste.
Codigo:
LIST P=16F628A
#INCLUDE<P16F628A.INC>
ERRORLEVEL -302
TMP equ 0x20
FLAG equ 0x21
Digit1y2code equ 0x22 ;estos 4 registros DEBEN ubicarse de manera
Digit3y4code equ 0x23 ;consecutiva en la memoria GPR del PIC.
Digit5y6code equ 0x24
Digit7 equ 0x25
DIGITOSREST equ 0x26
AUX equ 0x27
METHOD equ 0x28
IGUALES equ 0x29
ORG 00H
GOTO INICIO
ORG 04H
;AQUI IRIA EL CODIGO SI EL TIMER SE DEBORDA.
ORG 10H
INICIO MOVLW .7
MOVWF CMCON
BSF STATUS,5
CLRF TRISB
MOVLW b"00011111"
MOVWF TRISA
BCF STATUS,5
CLRF PORTB
CLRF PORTA
MOVLW b"11111111"
MOVWF FLAG
;FALTA SETEAR TIMER
CALL GETCODE
CALL RESETALL
WAITNEXT BTFSS PORTA,4
GOTO $-1
;FALTARIA RESETEAR TIMER ACA.
MOVF PORTA,W
ANDLW 0X0F
DECFSZ DIGITOSREST,F
GOTO FALTAN
INCF METHOD,F
FALTAN CALL COMPARA
BTFSC PORTA,4
GOTO $-1
GOTO WAITNEXT
COMPARA MOVWF AUX
MOVF METHOD,W
ADDWF PCL,F
GOTO NIBBLEALTO
GOTO NIBBLEBAJO
RELE MOVF IGUALES,F
BTFSS STATUS,Z
GOTO DISTINTOS
MOVF AUX,W
CALL TABLA
MOVWF TMP
ANDWF FLAG,W
XORWF PORTB,F
COMF TMP,W
MOVWF FLAG
DISTINTOS CALL RESETALL
RETURN
NIBBLEBAJO MOVLW 0X0F
ANDWF INDF,W
XORWF AUX,W
IORWF IGUALES,F
INCF FSR,F
CLRF METHOD
RETURN
NIBBLEALTO SWAPF INDF,W ;DAR VUELTA LOS NIBBLES( NIBBLE = GRUPO DE 4 BITS = MEDIO BYTE)
ANDLW 0X0F
XORWF AUX,W
IORWF IGUALES,F
INCF METHOD,F
RETURN
GETCODE MOVLW 0X12
MOVWF Digit1y2code
MOVLW 0X34
MOVWF Digit3y4code
MOVLW 0X56
MOVWF Digit5y6code
MOVLW 0X70
MOVWF Digit7
RETURN
RESETALL CLRF IGUALES
CLRF METHOD
MOVLW 0X22 ;debe ser siempre igual a la posicion de memoria de Digit1y2code
MOVWF FSR
MOVLW 0X08
MOVWF DIGITOSREST
RETURN
TABLA ADDWF PCL,1
RETLW .0
RETLW .1
RETLW .2
RETLW .4
RETLW .8
RETLW .16
RETLW .32
RETLW .64
RETLW .128
; RETLW .X
; RETLW .X
; RETLW .X
; RETLW .X
; RETLW .X
; RETLW .X
; RETLW .X
END
Ya con un poco de suerte, dentro de poco tiempo, voy a subir al foro un e-book que estoy escribiendo sobre programacion en ASM para PICs.
En cuanto lo termine, te aviso.
Exitos.
Hola.
Cita:
Hola nuevamente, ya lo que doy es pena Sinceramente Bruno te pido mil disculpa por hacerte perder tanto tiempo, que se que debe ser valiosisimo, y disculpa mi ignorancia de verdad me doy cuenta que de esto no se un carajo, y me tocara hacer un curso o cualquier otra cosa antes de participar porque como te dije antes lo que doy es pena.El software que hice tiene mas errores que instrucciones buenas, y el tuyo hay cosas que no entiendo, pero no importa dejemoslo asi te agradezco sinceramente tu dedicacion que se que lo hicistes si esperar nada a cambio, pero tampoco hay que abusar. Te felicito por tu sabiduria y te deseo muchos exitos. Atte. Nelson
No das pena, yo creo que esta muy bien tu codigo. Mira, si estoy ayudandote es porque no tengo problema en gastar mi tiempo en ayudar
. Nadie obliga a nada aqui!
Dime que es lo que no entiendes en mi codigo.
Seguramente no entenderas la funcion COMPARA , y lo del indirect file adressing(FSR e INDF)
COMPARA:
Te dije que estaba guardando dos digitos de codigo de seguridad por cada posicion de memoria:
Ej: tomando el primer registro que contiene los 2 primeros digitos del codigo de seguridad:
digit1y2code = 0x12 = 0001 0010
cuando Std envia el alto, leo el dato, lo filtro (solo me quedo con el valor RA0-RA3),
decremento la cantidad de digitos restantes,e ingreso a la funcion COMPARA.
Aqui, el tono presionado, debe ser comparado con el 1 de Digit1y2Code.
Por lo tanto, el primero tono que ingresa se compara con el nibble alto(0001), el segundo tono con el nibble bajo(0010),el tercero con el nibble alto pero del registro siguiente, que es el digit3y4code, y asi sigue hasta el septimo tono ingresado.
El octavo tono, el del rele, produce que la instruccion DECFSZ DIGITOSREST,F se cumpla, incrementando el valor del METHOD, por lo que METHOD = 2.
Al entrar a la funcion compara con el valor 2, vas a ver que va a ejecutar la rutina de encendido y apago de rele.
Lo del FSR e INDF es asi:
FSR contiene el valor de la posicion de memoria del registro a acceder indirectamente.
INDF accede y contiene el valor del registro correspondiente al valor que contenga FSR.
Un ejemplo,creo,va a simplificar la comprension:
Codigo:
mi1erReg equ 0x20
mi2doReg equ 0x21
mi3erReg equ 0x22
org 0x00
goto inicio
0rg 0x05
inicio movlw 0x80
movwf mi1erReg
movlw 0xa0
movwf mi2doReg
movlw 0xF1
movwf mi3erReg
movlw 0x20 ;cargo el valor 0x20 en w
movwf FSR ;al cargar el valor 0x20 en FSR, automaticamente
;INDF contiene el contenido que la posicion de memoria
;0x20, que es mi1erReg.
;por lo tanto, en este punto, INDF = 0x80.
incf INDF,F ;incremento el valor de la posicion de memoria 0x20
;ahora mi1erReg= 0x81 = INDF
incf FSR,F ;FSR = 0x20 +1 = 0x21 que corresponde al registro
;mi2doReg
;ahora, al hacer esto, INDF contiene ahora el contenido del
;registro ubicado en 0x21, entonces INDF = 0xa0
clrf INDF ;limpio el contenido de la posicion de memoria contenida en FSR.
;como FSR = 0x21, entonces, al hacer esto, ,mi2doReg = 0x00 ahora.
end
Si necesitas ayuda, fijate que tengo mi correo en mi perfil. No tengo drama en explicarte ni enseñarte ok? Saludos y que no te venza la depre!!!

