Autor Tema: Como censar el Puerto A del 16f628a  (Leído 7323 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
Como censar el Puerto A del 16f628a
« 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

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
RE: Como censar el Puerto A del 16f628a
« Respuesta #1 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


La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #2 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

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #3 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

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #4 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.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
RE: Como censar el Puerto A del 16f628a
« Respuesta #5 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



La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #6 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

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #7 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.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #8 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

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #9 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.


"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #10 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

   

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #11 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...
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #12 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!
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado rnelson

  • PIC12
  • **
  • Mensajes: 53
RE: Como censar el Puerto A del 16f628a
« Respuesta #13 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.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
RE: Como censar el Puerto A del 16f628a
« Respuesta #14 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.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.


 

anything