TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: rnelson en 12 de Enero de 2006, 18:44:00

Título: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 12 de Enero de 2006, 18:44:00
Estaba intentando censar el puerto A para ejecutar algo en el puerto B y lo hice de la siguiente manera:

   LIST P=16F628A
   #INCLUDE<P16F628A.INC>

R0C   equ   0CH   
R0D   equ   0DH   
R0E   equ   0EH

   ORG   00H
   GOTO   INICIO

INICIO:
   MOVLW    .7       
   MOVWF    CMCON                
                BSF   STATUS,5   
   CLRF   TRISB      
   movlw   b"00001111"
   movwf   TRISA      
   BCF   STATUS,5
   CLRF    PORTB
   CLRF   PORTA

CICLO:   MOVF   PORTA      
   CALL   TABLA      
   MOVWF    PORTB      
   GOTO   CICLO      
   
;****************************
TABLA   ADDWF   PCL,1      
   RETLW   .0   
   RETLW   .1
   RETLW   .2
   RETLW   .3
   RETLW   .4
   RETLW   .5
   RETLW   .6
   RETLW   .7
   RETLW   .8

END

Pero el mismo no funciona, quisiera que me dieran una mano para ver donde esta el error, en si lo que quiero es habilitar los pines del PortB dependiendo de el binario de 4 bits que tenga en el PortA (RA0, RA1, RA2 y RA3), por ejemplo:
Si el binario es "0100" solo debe encenderse el pin RB2, si el binario es "0000" solo debe encenderse el pin RB0, etc.

Gracias por la ayuda que me puedan prestar.

Atte. Nelson
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: Chaly29 en 12 de Enero de 2006, 19:01:00
Hola rnelson, para empezar tienes un problemita acá:

CICLO: MOVF PORTA,W <------ le tienes que poner la W
CALL TABLA
MOVWF PORTB
GOTO CICLO

y en ves de usar esa trama no te conviene esta:

CICLO
clrf PORTB
btfsc PORTA,0
bsf PORTB,0
btfsc PORTA,1
bsf PORTB,1
btfsc PORTA,2
bsf PORTB,2
btfsc PORTA,3
bsf PORTB,3
goto CICLO

y reemplazas la rutina y la tabla por este pedacito y arias todo lo demás.

Fíjate si te sirve, si no avísame

Suerte

Atte. CARLOS


Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 12 de Enero de 2006, 19:12:00
Gracias por la rapides de tu repuesta Chaly, eso que me aclaras lo pense, pero de esa manera no tengo que chequear pin por pin????, yo pense que si hacia el Movf Porta cargaba automaticamente el W con todo el puerto A??

De todas formas voy a probar con la modificacion que sugieres lo unico que veo es que como son muchos bit que se van a recibir por el pueto A el programa va hacer kilometrico, pero bueno lo importante es que funcione.

Lo pruebo y te cuento Chaly

Gracias nuevamente y un saludo desde Venezuela
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 12 de Enero de 2006, 19:19:00
Escrito originalmente por rnelson
Gracias por la rapides de tu repuesta Chaly, eso que me aclaras lo pense, pero de esa manera no tengo que chequear pin por pin????, yo pense que si hacia el Movf Porta cargaba automaticamente el W con todo el puerto A??

De todas formas voy a probar con la modificacion que sugieres lo unico que veo es que como son muchos bit que se van a recibir por el pueto A el programa va hacer kilometrico, pero bueno lo importante es que funcione.

Lo pruebo y te cuento Chaly

Gracias nuevamente y un saludo desde Venezuela


otra cosa que vi es que con tu rutina no lo voy a poder chequear los 4 bits como tal porque si el bits es "1010" tengo que habilitar es el RB5, no se si me explico???

Saludos y gracias Carlos
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 12 de Enero de 2006, 20:51:00
Aloha, si creo que entendi lo que queres, aca te paso el programa que corresponde:

LIST P=16F628A
#INCLUDE<P16F628A.INC>

R0C equ 0CH
R0D equ 0DH
R0E equ 0EH

ORG 00H
GOTO INICIO

INICIO:
MOVLW .7
MOVWF CMCON
BSF STATUS,5
CLRF TRISB
movlw b"00001111"
movwf TRISA
BCF STATUS,5
CLRF PORTB
CLRF PORTA

CICLO: MOVF PORTA ,W
CALL TABLA
MOVWF PORTB
GOTO CICLO

;****************************
TABLA ADDWF PCL,1
RETLW .0
RETLW .1
RETLW .2
RETLW .4
RETLW .8
RETLW .16
RETLW .32
RETLW .64
RETLW .128

END

Exitos. Bruno.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: Chaly29 en 12 de Enero de 2006, 21:15:00
Hola rnelson, mil disculpas te pido el problema fue de interpretación, ahora después de la explicación que diste te entendí, el programa correcto seria él de BrunoF, lo único a tener en cuenta con el programa de BrunoF es que como tu tienes 4 bits, la posibilidad de combinaciones es de 16 de 0 a 15 y la tabla solo llega a 9, por lo tanto te convendría completar con 6 retlw mas por si el dato de entrada supera los 9 , con esto evitarías que el programa se pierda.

La tabla quedaría algo como esto:

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 En las X colocas el numero que quieras
RETLW .X
RETLW .X
RETLW .X  

Suerte con le prueba

Att. CARLOS



Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 13 de Enero de 2006, 15:14:00
Muchas gracias a los dos (Bruno y Carlos) por su dedicacion y paciencia, pero tengo aun una duda con la tabla que creo que no la vieron.

Primero si el binario en el puerto A es "0011" = 3 en decimal, deberia solamente habilitarse el RB3, si lo vemos en la tabla seria:

TABLA   
ADDWF   PCL,1 ;Suma "0011" + 0 = 3 deberia saltar a la instruccion RETLW .3???  
RETLW   .1
RETLW   .2
RETLW   .3
RETLW   .4
RETLW   .5
RETLW   .6
RETLW   .7

Lo que yo veo es que en sus tablas no se estan tomando en cuenta los numeros 3, 5, 6 y 7??? porque si el binario del puerto A es "0111" osea 7,a que instruccion va a saltar??.

Saludos y gracias de antemano.

Atte. Nelson
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 13 de Enero de 2006, 18:49:00
Sonrisa GiganteSonrisa GiganteHola nelson, andas algo perdido amigo!Sonrisa GiganteSonrisa GiganteSonrisa Gigante
Voy a utilizar tu tabla CharlySonrisa GiganteSonrisa Gigante

TABLA ADDWF PCL,1
RETLW .0           ;SI RA=.0 ejecuta esta linea
RETLW .1           ;SI RA=.1 salta y ejecuta esta linea
RETLW .2           ;SI RA=.2 salta y ejecuta esta linea
RETLW .4           ;SI RA=.3 salta y ejecuta esta linea
RETLW .8           ;SI RA=.4 salta y ejecuta esta linea
RETLW .16         ;SI RA=.5 salta y ejecuta esta linea
RETLW .32         ;SI RA=.6 salta y ejecuta esta linea
RETLW .64         ;SI RA=.7 salta y ejecuta esta linea
RETLW .128       ;SI RA=.8 salta y ejecuta esta linea
RETLW .X           ;SI RA=.10 salta y ejecuta esta linea
RETLW .X           ;SI RA=.11 salta y ejecuta esta linea
RETLW .X           ;SI RA=.12 salta y ejecuta esta linea
RETLW .X           ;SI RA=.13 salta y ejecuta esta linea
RETLW .X           ;SI RA=.14 salta y ejecuta esta linea
RETLW .X           ;SI RA=.15 salta y ejecuta esta linea
                          ;SI RA =16 se va a la proxima posicion de memoria del PIC y vas a tener un menudio lio...por lo tanto debes forzar al puerto a a contener un valor <16.

Te recomiendo:
MOVF      PORTA,W
ANDLW   0x0F
CALL TABLA

Agregale esa linea ANDLW para asegurarte que no ocurra un desbordamiento en la tabla. Lo demas lo dejas como estaba. Quema el PIC y veras que funciona correctamente. Exitos.


Lo que hace es sumar el valor de W al contador del programa(PC). Si W = 0, entonces el programa se ejecuta normalmente (PC= PC+1 = RETLW   .0). Lo demas es lo mismo, salta tantas instrucciones como el valor cargado en el acumulador(W). Saludos.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 14 de Enero de 2006, 13:16:00
Hola brother.
Si bruno ando bastante perdido, lo que pasa es que soy bastante nuevo en la programacion de pic y me he llevado bastantes trancasos porque mal interpreto las cosas, te pido mil disculpas por mi ignoracia pero creo que si no me atrevo no aprendo, gracias nuevamente por tu paciencia.
Lo que entiendo de la tabla es que si W=1 se va a ejecutar retlw .0??? si W=3 se va a ejecutar retlw .2???, si W=4 se va a ejecutar retlw .4, y asi sucecivamente, ahora porque colocan valores 1,2,4,8,16,32,64, etc??? esto no lo entiendo...

Voy a probar quemar el pic con lo que me estas planteando y les cuento, igual los valores en el puerto A no van a pasar de 16 asi que por lo demas no debemos preocuparnos

Saludos y gracias por soportar mi fastidio.

Atte. Nelson
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 15 de Enero de 2006, 03:28:00
Hola! Iba en broma!No me fastidia para NADA!!SonrisaSonrisaSonrisa. Nadie nace sabiendo! Mejor asi y no que te quedes con las dudas.

Escrito originalmente por rnelson

Lo que entiendo de la tabla es que si W=1 se va a ejecutar retlw .0??? si W=3 se va a ejecutar retlw .2???, si W=4 se va a ejecutar retlw .4, y asi sucecivamente



Vamos a comenzar por el PC (Program Counter). Este registro contiene un numero: La posicion de memoria que se va a ejecutar actualmente.

Por ejemplo:

ORG   0x0000  ;este es el vector de la primera posicion de memoria de todo PIC. Cero. EL PIC cuando lo enciendes(por ej.) arranca con este valor. CERO.
NOP                 ;al compilar este codigo, esta instruccion se graba en la posicion cero del PIC.
NOP                 ;esta se graba en la posicion 1
GOTO INICIO   ;esta se graba en la posicion 2

Entonces, sabemos que en la programacion, tal como la conocemos, el codigo se ejecuta de arriba hacia abajo siempre y cuando no haya una instruccion que genere un desvio (ejemplos: CALL GOTO RETURN RETLW RETFIE UNA INTERRUPCION etc)

Entonces el PC (PCL en este caso para la explicacion...La L es de Low, ya que la parte alta del PC se carga en el registro PCLATH...pero ese es otro rollo)
El PC se autoincrementa, es decir, luego de ejecutarse una instruccion, se suma a si mismo el valor 1.
Entonces, siguiendo con el ejemplo anterior:

ORG   0x0000   ;esto es SOLO un vector. lo unico que haces es indicarle al compilador, donde deseas que comiencen a ser posteriormente ubicadas las instrucciones que le siguen a esta linea. Esta linea NO se graba en el PIC.
NOP                ;aqui el PC = 0
NOP                ;luego de ejecutarse la NOP, el PC se autoincrementa, y vale 1, entonces ejecuta esta linea.
GOTO INICIO ; lo mismo aqui.se autoincrementa y pasa a valer 2.Cabe destacar que la instruccion GOTO interrumpe el normal incremento del PC. El GOTO es un salto incondicional, quiere decir que carga al PC con el valor de memoria en el cual se encuentre la instruccion inmediatamente debajo o a la derecha de la etiqueta INICIO.De esta manera se logra que el programa esquive lineas de codigos que no deseamos se ejecuten.

al inicio de tu tabla, el PC tiene un determinado valor, ok? eso depende de el codigo. Si deseas ver exactamente en que posicion de memoria esta una instruccion, no tienes mas que compilar el archivo ASM en el MPLAB, y luego ir al menu View--> Program Memory.

Entonces, te lo explico asi:

TABLA ADDWF PCL,1   ;aqui PC = X
RETLW .0                    ;aqui PC = X+1
RETLW .1                    ;aqui PC = X+2
RETLW .2     ;aqui PC = X+3
RETLW .4  ;aqui PC = X+4
RETLW .8 ;aqui PC = X+5
RETLW .16 ;aqui PC = X+6
RETLW .32 ;aqui PC = X+7
RETLW .64 ;aqui PC = X+8
RETLW .128 ;aqui PC = X+9
RETLW .X ;aqui PC = X+10
RETLW .X ;aqui PC = X+11
RETLW .X ;aqui PC = X+12
RETLW .X ;aqui PC = X+13
RETLW .X ;aqui PC = X+14
RETLW .X ;aqui PC = X+15
RETLW .X ;aqui PC = X+16

Si PORTA = 0, entonces al hacer MOVF PORTA,W W se carga con el valor cero. Cuando llamas a la tabla, al adicionarle cero al PC, el PC vale lo mismo que antes: X. Pero recuerda que mencione que el PC se autoincrementa(pues si no lo hiciese, pues no corriria nuestro codigo...) entonces en realidad si W vale cero, se ejecuta la linea siguiente al ADDWF PCL,1, que es RETLW .0
Si W = 1 entonces, en realidad,el PCL va a sumarse una posicion porque W vale 1, y otra mas porque el PC SIEMPRE se autoincrementa, en total va a sumarse 2, ejecutandose por lo tanto: RETLW .1
idem para los demas valores de W.
Entonces, resumiendo, en realidad, el PCL siempre se agregara uno mas que el valor de W, ok? ejemplo: si W= 0, PCL = X+1 si W= 1, PCL = X+2...etc...
En resumen: en este caso que sumas W al PCL:
PCL = PCL+W+1


Escrito originalmente por rnelson
ahora porque colocan valores 1,2,4,8,16,32,64, etc??? esto no lo entiendo...


Ok. el Puerto B es un registro de 8 bits, lo que quiere decir, que nos ofrece 256 valores distintos (del 0 al 255 en nuestro sistema decimal).
Cada Pin del Puerto B esta asignado a un bit del registro 0x06 (PORTB).
El PIN cero del puerto B esta asignado al bit cero del registro PORTB
El PIN uno del puerto B esta asignado al bit uno del registro PORTB
y asi los 6 restantes...
Suponte que colocas 8 leds en modo fuente(lo normalmente utilizado) en los 8 pines del puertoB del pic(un led por pin).

el valor .1 es en binario "00000001"
Un 1 en un bit indica que el led conectado al pin correspondiente, encendera.
Entonces si cargas al puertoB con el valor 1, entonces, enciende el led en RB0 y los demas permanecen apagados.

el valor .2 es en binario "00000010"
En este caso, el bit que se pone en uno es el bit 1, asignado al pin RB1, entonces enciende el led en RB1 y los 7 restantes permanecen apagados.

el valor .4 es en binario "00000100"
En este caso, el bit que se pone en uno es el bit 2, asignado al pin RB2, entonces enciende el led en RB2 y los 7 restantes permanecen apagados.

Idem para los demas valores( hace la conversion de decimal a binario y comprobalo)

Si por ejemplo cargas el valor .255 en el puertoB, en binario 255 = "11111111". Esto hara que enciendan los 8 leds conectados a los 8 pines del puertoB.
Espero haya quedado claro. Exitos. Bruno.


Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 15 de Enero de 2006, 13:25:00
Muchas gracias Bruno, mas claro no canta un gallo, lo entendi perfectamente me imagino que debes ser profesor en algun instituto porque tienes buena pedagogia.

Queme el Pic y funciona de maravilla con el unico detalle que si Porta vale "0000" no hace nada, si Porta vale "0001" me ejecuta Retlw .0, y asi sucesivamente, pero igual asi como esta tambien me sirve, solo te lo comento porque la explicacion que me distes si W=0 debia ejecutarse Retlw .0.

Ahora bien eso es solo el comienzo de lo que necesito, lo unico es que me gusta hacer las cosas por partes para entenderlas mejor, porque como te explique soy nuevo en esto y la idea es comprender de donde sales las cosas.

En el puerto B van a ir conectados 8 reles (RB0-RB7) deben activarse y desactivarse dependiendo del binario que alla en el PortA, por ejm: si Porta = "0001" debe activarse RB0, hasta aqui ya se hizo y funciona perfecto, ahora el detalle esta en que RB0 debe permanecer activo hasta que se vuelva a recibir en el Porta "0001" no se si me explico??? indistintamente que se envien otros datos tales como "0111", "0010", "0011", etc. y por supuesto si se envia 0010 debe activarse RB1 y permanecer activo hasta recibir nuevamente "0010" igual que el paso anterior, y esto debe repetirse para todos los reles.

Pense que se podia hacer colocando comparaciones en el programa:

CICLO:
MOVF PORTA ,W
XORWF "0001",W
BTFSC STATUS,Z
GOTO IGUAL

El problema esta en que no se como identificar cuando un pin del portb esta activo y cuando no, porque inicialmente va estar inactivo, cuando llegue el dato se activara y si vuelve a llegar se desactivara, y asi sucecivamente con todos los pines del Portb.

Espero que me alla explicado bien.

Gracias y disculpa tanta joda.

Saludos Nelson

   
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 15 de Enero de 2006, 19:59:00
Hola rnelson:

Escrito originalmente por rnelson
Queme el Pic y funciona de maravilla con el unico detalle que si Porta vale "0000" no hace nada, si Porta vale "0001" me ejecuta Retlw .0, y asi sucesivamente, pero igual asi como esta tambien me sirve, solo te lo comento porque la explicacion que me distes si W=0 debia ejecutarse Retlw .0.


La explicacion que te di es lo que realmente deberia suceder. Procura que entre la instruccion ADDWF PCL,1 y la RETLW .0 NO HAYA NINGUNA OTRA INSTRUCCION. Tal como comentas el comportamiento del programa, o bien tienes una linea que esta desplazando todos los valores de la tabla en una unidad, o bien estas enviando mal los valores al puerto a. Eso que te explique es LEY.


Escrito originalmente por rnelson
En el puerto B van a ir conectados 8 reles (RB0-RB7) deben activarse y desactivarse dependiendo del binario que alla en el PortA, por ejm: si Porta = "0001" debe activarse RB0, hasta aqui ya se hizo y funciona perfecto, ahora el detalle esta en que RB0 debe permanecer activo hasta que se vuelva a recibir en el Porta "0001" no se si me explico??? indistintamente que se envien otros datos tales como "0111", "0010", "0011", etc. y por supuesto si se envia 0010 debe activarse RB1 y permanecer activo hasta recibir nuevamente "0010" igual que el paso anterior, y esto debe repetirse para todos los reles.

Pense que se podia hacer colocando comparaciones en el programa:

CICLO:
MOVF PORTA ,W
XORWF "0001",W
BTFSC STATUS,Z
GOTO IGUAL

El problema esta en que no se como identificar cuando un pin del portb esta activo y cuando no, porque inicialmente va estar inactivo, cuando llegue el dato se activara y si vuelve a llegar se desactivara, y asi sucecivamente con todos los pines del Portb.





Bien...creo que comprendi la idea que tenes de como queres que funcione el programa. He aqui un detalle que debes tener en cuenta. Este programa que estas realizando es bastante rapido. Por lo que si envias un valor por ejemplo "0001" al puertoA, es probable que el PIC ejecute el codigo mas de una vez antes que el dato de entrada varie, y el PIC encienda y apague el rele sucesivas veces, y ni siquiera con ningun tipo de certeza que el rele termine  en el estado correcto.

Por lo tanto, el codigo que necesitarias para tu programa, es el siguiente:

LIST P=16F628A
#INCLUDE<P16F628A.INC>

R0C equ 0CH
R0D equ 0DH
R0E equ 0EH


TMP equ 0x20
FLAG equ 0x21


ORG 00H
GOTO INICIO

INICIO:
MOVLW .7
MOVWF CMCON
BSF STATUS,5
CLRF TRISB
movlw b"00001111"
movwf TRISA
BCF STATUS,5
CLRF PORTB
CLRF PORTA


MOVLW b"11111111"  ;inicializar byte flag todos los bits a 1
MOVWF FLAG


CICLO: MOVF PORTA ,W
ANDLW  0x0F   ;agrega esta linea para no tener dolores de cabeza...
CALL TABLA

MOVWF TMP
ANDWF FLAG,W
XORWF PORTB,F

COMF TMP,W
MOVWF FLAG


GOTO CICLO

;****************************
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

Las lineas en azul, son las que he agregado al programa anterior

Ok, el comportamiento que deseabas parece simple de llevar a codigo, pero a la hora de plantearlo se puede complicar...loco
El puerto b lo tienes configurado como salida, y, en teoria, no deberia leerlo o comparado, pero si no recuerdo mal igualmente funciona este codigo...Sonrisa GiganteSonrisa GiganteSonrisa GiganteSonrisa Gigante
Espero que comprendas la logica y comportamiento del codigo que hice para tu proyecto. Exitos...
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 15 de Enero de 2006, 23:06:00
Escrito originalmente por rnelson
Muchas gracias Bruno, mas claro no canta un gallo, lo entendi perfectamente me imagino que debes ser profesor en algun instituto porque tienes buena pedagogia.


Sonrisa GiganteSonrisa GiganteSonrisa GiganteSonrisa Gigante imaginas bien...Sonrisa GiganteSonrisa GiganteSonrisa GiganteSonrisa Gigante

Si tienes dudas o problemas con el codigo, pues hazmelo saber. Bytes!
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 17 de Enero de 2006, 13:34:00
Hola Bruno
Brother muchas gracias por tu dedicacion, y disculpa tanta ladi...., pero lo ultimo que me hicistes no lo entendi, mas aun cuando se para que se utiliza cada instruccion, lo que pasa es que no entendi la sintaxis del programa.

Saludos...

Nelson.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 17 de Enero de 2006, 17:58:00

TMP equ 0x20
FLAG equ 0x21

 
Declaro dos variables que voy a utilizar para:

TMP = guarda el valor recibido de la TABLA(W) para posterior utilizacion
FLAG = Guarda los valores de autorizacion que cree yo cada bit del PuertoB.
Un bit en 1 del FLAG indica que tiene autorizacion para invertir el estado de ese bit del PuertoB.


MOVLW b"11111111" ;inicializar byte flag todos los bits a 1
MOVWF FLAG


Inicializo como que todos los bits del PuertoB con el valor 1. Esto quiere decir, que todos los pines del puertoB que reciban un 1 de la tabla, van a cambiar su estado de salida.


ANDLW 0x0F ;agrega esta linea para no tener dolores de cabeza...


Esto filtra el PuertA impidiendo que solamente ingresen a la TABLA valores entre .0 y .15


MOVWF TMP
ANDWF FLAG,W
XORWF PORTB,F

COMF TMP,W
MOVWF FLAG


Este codigo es el que genera el comportamiento que tu me dijiste que quieres que el programa realice.

MOVWF TMP
Guardo el valor obtenido de la TABLA en TMP(los valores que devuelve,recuerda, pueden ser .0 , .1, .2, .4, .8, .16, .32, etc...)

ANDWF FLAG,W
Realizo una comparacion logica AND. Esto sirve de filtro. Si W contiene un bit(o mas) en 1 y FLAG tambien tiene ese bit(o mas) en 1, entonces, todos esos bits son guardados en W, para luego ser comparados con el valor actual de las salidas(pines) del PuertoB.

XORWF PORTB,F
Si la pregunta anterior carga en W algun bit(o mas) en 1, entonces quiere decir que debo invertir el valor de todos los bits en 1 que posea W.
Esto hace la XOR.

COMF TMP,W  
MOVWF FLAG

Invertir el valor leido desde la tabla, e invertir su valor. Todos los bits que esten en 1 en TMP, pasan a 0 y viceversa.Guardo el resultado en FLAG.

Ejemplo:

Inicialmente se cofiguran:
PUERTOB = b"00000000"
FLAG = b"11111111"
TMP = No interesa

Comienza el loop:

Supongamos que leo el PuertoA y el valor leido es : "XXXX0000" donde X es: No interesa
ANDLW 0x0F
Ahora el valor que va ingresar a la tabla es: b"00000000" ; el AND filtró las X...

MOVWF TMP ;aqui W contiene el valor devuelto por la TABLA(.0 en este caso). Guardo el valor en TMP

ANDWF FLAG,W ; comparo los bits recibidos con la tabla con mi byte de autorizacion(FLAG)

W = b"00000000"
AND
FLAG = b"11111111"
Resulta en b"00000000". Almaceno el resultado en W.

XORWF PORTB,F

W = b"00000000"
XOR
PORTB = b"00000000"

Resulta en b"0000000". Expulso el resultado en el PuertoB (no hubo variaciones)

COMF TMP,W
MOVWF FLAG
TMP = b"00000000"
COM
Resulta en W = b"11111111"
Copio W en FLAG


Ahora el programa vuelve al loop y...

Supongamos que leo el PuertoA y el valor leido es : "XXXX0001" donde X es: No interesa
ANDLW 0x0F
Ahora el valor que va ingresar a la tabla es: b"00000001" ; el AND filtró las X...

MOVWF TMP ;aqui W contiene el valor devuelto por la TABLA(.1 en este caso). Guardo el valor en TMP

ANDWF FLAG,W ; comparo los bits recibidos con la tabla con mi byte de autorizacion(FLAG)

W = b"00000001"
AND
FLAG = b"11111111"
Resulta en b"00000001". Almaceno el resultado en W.

XORWF PORTB,F

W = b"00000001"
XOR
PORTB = b"00000000"

Resulta en b"0000001". Expulso el resultado en el PuertoB (El rele conectado a RB0 se activóGiño

COMF TMP,W
MOVWF FLAG
TMP = b"00000001"
COM
Resulta en W = b"11111110"
Copio W en FLAG ;aqui el bit cero

Ahora el programa vuelve al loop y...

Supongamos que leo el PuertoA y el valor leido es : "XXXX0001" donde X es: No interesa
ANDLW 0x0F
Ahora el valor que va ingresar a la tabla es: b"00000001" ; el AND filtro las X...

MOVWF TMP ;aqui W contiene el valor devuelto por la TABLA(.1 en este caso). Guardo el valor en TMP

ANDWF FLAG,W ; comparo los bits recibidos con la tabla con mi byte de autorizacion(FLAG)

W = b"00000001"
AND
FLAG = b"11111110"
Resulta en b"00000000". Almaceno el resultado en W.

XORWF PORTB,F

W = b"00000000"
XOR
PORTB = b"00000001"

Resulta en b"0000001". Expulso el resultado en el PuertoB (sigo recibiendo la misma instruccion, no hubo variaciones desde la ultima vuelta)

COMF TMP,W
MOVWF FLAG
TMP = b"00000001"
COM
Resulta en W = b"11111110"
Copio W en FLAG

Ahora el programa vuelve al loop y...

Supongamos que leo el PuertoA y el valor leido es : "XXXX0000" donde X es: No interesa
ANDLW 0x0F
Ahora el valor que va ingresar a la tabla es: b"00000000" ; el AND filtro las X...

MOVWF TMP ;aqui W contiene el valor devuelto por la TABLA(.0 en este caso). Guardo el valor en TMP

ANDWF FLAG,W ; comparo los bits recibidos con la tabla con mi byte de autorizacion(FLAG)

W = b"00000000"
AND
FLAG = b"11111110"
Resulta en b"00000000". Almaceno el resultado en W.

XORWF PORTB,F

W = b"00000000"
XOR
PORTB = b"00000001"

Resulta en b"0000001". Expulso el resultado en el PuertoB (no produjo variaciones desde la ultima vuelta pero...ahora...fiijate debajo)

COMF TMP,W
MOVWF FLAG
TMP = b"00000000"
COM
Resulta en W = b"11111111"
Copio W en FLAG

El bit cero(el que afecta al RB0 vuelve a tener autorizacion para cambiar su estado si recibe otro 1 en ese bit) Por lo tanto si en una pasada posterior el la tabla devuelve un valor que contenga un 1 en su bit0, el mismo hara que el valor de salida del RB0 pase de ser 1 a 0 (desactivacion del rele) a travez de la instruccion XORWF PORTB,F

Asi sigue el programa funcionando con esta logica...Decime si te ayude a comprenderlo.
Saludos.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 18 de Enero de 2006, 08:39:00
RebotadoRebotadoRebotado Hola Bruno.

Hermano con usted si es verdad que hay que quitarse el sombrero, el que no conoce nada de pic entienede tus explicaciones, de verdad felicitaciones y muchas gracias por tu de dicacion.

Estare un par de dias ausente del foro, pero luego regresare porque este proyecto es de una materia de la universidad, y el profesor en cada clase le agrega una dificultad mas, asi que te estare molestando posteriormente ya que cada vez la cosa se hace mas complicada.

Saludos y Felicitaciones nuevamente

Muchas gracias Nelson.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 18 de Enero de 2006, 17:54:00
Sonrisa GiganteSonrisa GiganteSonrisa GiganteMuchas Gracias por los cumplidos!Sonrisa GiganteSonrisa GiganteSonrisa Gigante Aqui estamos todos para ayudarte en todo lo que podamos.
Exitos.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 24 de Enero de 2006, 20:04:00
Aqui estoy nuevamenteSonrisa GiganteSonrisa GiganteSonrisa Gigante

Esta vez el profesor se paso con lo que pidio, quiere que el circuito este identificado con numero de 8 digitos, pero solo podemos recibir por el Porta un numero de 4 bit, esto quiere decir que se debe enviar digito por digito hasta completar la cifra de 8 numeros.

Por ejemplo:
Supongamos que el circuito tiene un numero de identificacion "12017471" como el el circuito solo puede recibir hasta 16bits por el puerto A (condicion impuesta) pense en recibir numero por numero, es decir:

movf porta,w; leo puerto a
subwf "0001",w; comparo si el valor leido es igual a el almacenado
btfsc STATUS,Z
goto retardo; si no es igual el ciclo entra en un retardo de tal manera que permita  terminar la secuencia y comience de nuevo
movf porta,w; si el valor anterior valor es concuerda con el almacenado se debe ejecutar esta instruccion, repitiendo el mismo ciclo pero comparando con otro valor  
subwf "0010",w
btfsc STATUS,Z
Goto retardo; este retardo debe ser menor a el anterior

y asi sucesivamente hasta leer todos los numero de identificacion, con la diferencia que el untimo numero del identificador es el rele que se va a activar o desactivar.

No se si me explique bien, pero creo que con la rutina que expuse se puede hacer, no se que opinas los crack de esta materia???

Saludos y espero sus opiniones.

Atte. Nelson    
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 25 de Enero de 2006, 00:18:00
Hola nelson. Lo que planteas no resulta en mayor complicacion, pero decime:
Que estas utilizando para enviar los datos al puertoA? una PC? otro PIC?

Para poder elegir el metodo que pueda resultar mas óptimo en este caso.
El numero de identificacion al que te referis seria una especie de codigo de seguridad de 7 digitos entonces?

Si.Tu programa esta bien orientado si es lo que decis...pero por ahi puede haber metodos mas efectivos. Pero si funciona, vale.

Explica un poquito mas el tema de que sistema estas utilizando para enviarle los datos al PIC, o bien el que pretendes utilizar ahora que el profe te la complico...
Exitos.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 25 de Enero de 2006, 13:01:00
HOla. Bueno..segun estuve leyendo en el datasheet del 8870 vas a necesitar agregar un pin mas.
Ahora vas a tener que detectar la lectura de un "nuevo tono". Por lo que lei, a esto lo hace el pin StD (Steering Delay) del 8870.
Entonces, mi sugerencia es conectar este pin al RA4 del PIC(si es que no lo estas ya utilizando).
ADVERTENCIA! necesitas cambiar el codigo antes de conectarlo. El pin que selecciones para leer el StD debe ser configurado como entrada!!!!...Si no me haces caso vas a quemar algo...

Bueno...lo que comentas:

Se me ocurren en este momento 2 opciones factibles:

1) Esperar a que ingrese un dato. Si en algun momento el digito recibido es distinto al de seguridad, se vuelve todo a cero y se espera nuevamente los 8 digitos. Los retardos que mencionas, no veo buena opcion utilizarlos. Siendo que es discado por DTMF, si un ser humano es el que presiona las teclas y envia los 8 digitos, el tiempo de duracion de los tonos, asi como las pausas entre ellos, varian de manera muy significativa...Un retardo va a provocar,seguramente, desincronizacion.

2)Esperar a que ingresen 8 datos (no compruebo 1 a 1, simplemente los leo y almaceno en memoria hasta haber leido 8)
Luego comparar todos con el codigo de seguridad. Si no coincide, se vuelve todo a cero y se espera nuevamente los 8 digitos.

En mi opinion: el segundo metodo es mejor. Ya que en el primero, un error va a producir un arrastre del codigo.Sin embargo, ese metodo puede mejorarse para que espere su proximo "puntero" de sincronizacion:
dado por la simple formula:

punteros = 8 elevado a la x + 1 (con x perteneciente a los naturales, incluido el ceroSonrisa GiganteSonrisa Gigante


El segundo asegura, en parte(hay bastantes posibilidades(casos de uso) a tener en cuenta), la sincronizacion de 8 datos por comando.

Tambien hay que pensar en un maximo tiempo de espera, en el que, si se excede,
se debe volver todo a cero. Para esto podemos utilizar uno de los Timers del PIC.

Perooo nada complicado. Usted dira que es lo que desea hacer. Saludos.

Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 25 de Enero de 2006, 19:36:00
hola bruno.

Tienes toda la razon creo que la segunda opcion que planteas es la mas adecuada por el tema de la desincronizacion, y me parece bien utilizar el RA4 para recibir Std y asi saber cuando hay un numero nuevo.

Lo que planteas de almacenar todo en variables y luego comparar,lo podriamos hacer con el ciclo que plantie en el mensaje anterior o hay una mas efectiva de como hacerlo??? por que si es como yo lo planteo habria que crear 8 variables cierto???

Espero Respuesta y gracias nuevamente por tu dedicacion.

Atte. Nelson
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 25 de Enero de 2006, 20:02:00
Hola Nelson.

Bien.

Se me vienen a la mente muchos metodos. Veo que pareces preocupado por la cantidad de variables a utilizar. Bueno...incluso con solo 1 variable(auxiliar) se puede hacer lo que queres.
Pero,por ahi convenga, para que quede bonito y facil de entender y modificar, crear 4 variables para el codigo de seguridad.Igualmente, si lo queres hacer utilizando una sola variable(y solo para almacenar W temporalmente) se puede hacer tambien...

Entonces: si por ejemplo:
El codigo de seguridad que elegis es:1234567

Lo ubicas en las variables asi:

Digit1y2code = 0x12
Digit3y4code = 0x34
Digit5y6code = 0x56
Digit7code = 0x70 ;el cero no afecta. lo pongo pero puede ser cualquier valor.

Para el programa que compare, hay millones de maneras de hacerlo...
Fijate si se te ocurre algo a vos, y te ayudo.

Exitos..




Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 26 de Enero de 2006, 08:16:00
Hola Bruno RebotadoRebotado
Ok me parece excelente, ya tengo pensado como hacer las comparaciones, pero ahora me surge una duda, porque las variables digi y code las estas ubicando en la misma direccion??? de verdad que no sabia que eso se podia hacer hasta donde yo se tenian que ser variables en direcciones independientes??, pero bueno te planteo lo que tengo pensado hacer con las comparaciones:

LIST P=16F628A
#INCLUDE<P16F628A.INC>

R0C equ 0CH
R0D equ 0DH
R0E equ 0EH


TMP   equ 0x20
FLAG  equ 0x21
digi1 equ 0x22
code2 equ 0x23
digi3 equ 0x24
code4 equ 0x25
digi5 equ 0x26
code6 equ 0x27
digi7 equ 0x28

ORG 00H
GOTO INICIO

INICIO:
MOVLW .7
MOVWF CMCON
BSF STATUS,5
CLRF TRISB
movlw b"00001111"
movwf TRISA
BCF STATUS,5
CLRF PORTB
CLRF PORTA

MOVLW b"11111111"
MOVWF FLAG

digito1:
BTFSS PORTA,4
Goto digito1
Movf porta, W
movwf Digi1

digito2:
BTFSS PORTA,4
Goto digito2
Movf porta, W
movwf code2

digito3:
BTFSS PORTA,4
Goto digito3
Movf porta, W
movwf Digi3
"
"
"
"
Digito7
BTFSS PORTA,4
Goto digito7
Movf porta, W
movwf digi7

rele:
BTFSS PORTA,4
Goto rele
MOVF PORTA,W
ANDLW 0x0F
CALL TABLA

MOVWF TMP

MOVF Digi1,W
XORWF "0001",W
BTFSC STATUS,Z
Call resetall

MOVF code2,W
XORWF "0010",W
BTFSC STATUS,Z
Call resetall

MOVF Digi3,W
XORWF "0011",W
BTFSC STATUS,Z
Call resetall

MOVF code4,W
XORWF "0100",W
BTFSC STATUS,Z
Call resetall

MOVF Digi5,W
XORWF "0101",W
BTFSC STATUS,Z
Call resetall

MOVF code6,W
XORWF "0110",W
BTFSC STATUS,Z
Call resetall

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

;****************************
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

;****************************
resetall
clrf digi1
clrf code2
clrf digi3
clrf code4
clrf digi5
clrf code6
clrf digi7

end

No se que te parece??? creo que tiene unos errores, y por eso aun no lo he probado.

Saludos, espero tus comentarios.

Atte. Nelson
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 26 de Enero de 2006, 16:00:00
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!!!Ardiendo
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.
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 27 de Enero de 2006, 09:09:00
Hola nuevamente, ya lo que doy es penaLlorandoLlorandoLlorando

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
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 27 de Enero de 2006, 13:49:00
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 ayudarMuchas risas. Nadie obliga a nada aqui!Sonrisa Gigante
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!!!RollEyesSonrisa GiganteRebotado
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: rnelson en 28 de Enero de 2006, 16:48:00
Gracias bruno, lo que sucede es que me da impotencia no entender las cosas, y eso me deprime un poco.

Lo que voy a hacer es a comentar el programa tuyo y te lo paso a tu correo para que me explique las lineas que no entiendo, claro si no tienes problema.

Otra cosa vos no dictais cursos a distancia???? porque de ser asi me anoto y te cancelo algo para que estemos felices todos, y asi no me siento que te estoy utilizando.

Saludos....
Título: RE: Como censar el Puerto A del 16f628a
Publicado por: BrunoF en 28 de Enero de 2006, 19:58:00
Escrito originalmente por rnelson
Gracias bruno, lo que sucede es que me da impotencia no entender las cosas, y eso me deprime un poco.


Mira...nadie nace sabiendo. Es cuestion de aprender! equivocarse forma una gran parte del proceso de aprendizaje.Asi que vamos! arriba el animo!Sonrisa GiganteSonrisa Gigante

Escrito originalmente por rnelson
Lo que voy a hacer es a comentar el programa tuyo y te lo paso a tu correo para que me explique las lineas que no entiendo, claro si no tienes problema.


Dale, lo espero. No tengo ningun problema en explicartelo.
¿Lo probaste al programa?

Escrito originalmente por rnelson
Otra cosa vos no dictais cursos a distancia???? porque de ser asi me anoto y te cancelo algo para que estemos felices todos, y asi no me siento que te estoy utilizando.


No rnelson. Nunca he dado cursos a distancia.
Si he pensado y creo que el verano proximo voy a dar cursos de ASM pero a nivel local.
Doy clases en una Universidad pero de Analisis Matematico y Algebra...(mi pasion)

Sí he ayudado a muchas personas durante dias, meses (e incluso más de un año) a desarrollar los algoritmos que necesiten y explicar via chat y/o correo electronico.

Tengo ahi a un amigo Venezolano que tambien quiere aprender de ASM hace rato y lo viene esquivando...

Tambien estoy escribiendo un e-book sobre este tema, que espero lograr terminar...este año! jaja...

Con respecto al circuiterio electronico ajeno al PIC...soy un newbie aficionado en ese tema, ya que no es lo que estudie ni profundice personalmente...por lo tanto no me meto ni atrevo a meterme mucho...¿por ahora?Sonrisa GiganteSonrisa Gigante

Exitos. Espero tu mail.