TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: RataMetallica en 15 de Junio de 2011, 15:45:37
-
que tal, este es mi primer post soy muy nuevo usando el asm y por mas que he intentado no logro terminar mi programa, es un ejemplo sobre el pic6f84a...
;********************************** Drenado.asm *************************************
;
;Se tienen una sisterna que recolecta aguas pluviales, la sisterna cuenta con dos bombas
;para mandar el agua recolectada de la sisterna al sistema de alcantaqrillado. Tambien
;cuenta con dos snesores de niveles. Uno de nivel bajo (NB) y otro de nivel alto (NA).
;
;Se requiere un sistema de automatizacion que trabaje de la siguiente forma.
;
;1. Cuando se active el sensor de NB debe trabajar solo una bomba.
;
;2. Las bombas deben trabajar de forma alternada, para evitar el desgaste continuo en una sola de ellas.
;
;3. Si se activa el sensor NA las dos bombas deben trabajar.
;
;4. Cuando estan funcionando las 2 bombas estas se deben apagar cuando se desactiven los dos sensores.
;
; AAAAA BBBBBBBBBBBBBBBBB
; R1 R0 | R7 R6 R5 R4 R3 R2 R1 R0
; ------- |--------------------------------
; 0 0 | 0 O 0 0 0 0 0 1 (Configuración 0. Estado "Vacio").
; 0 1 | 0 1 0 0 0 0 1 0 (Configuración 1. Estado "Llenandose").
; 1 0 | 0 1 1 0 0 1 0 0 (Configuración 2. Estado "Lleno").
; 1 1 | 0 1 1 0 0 1 0 0 (Configuración 3. Estado "Lleno").
;
en este caso use RB6 y RB5 como bombas
RB3 como nivel alto y RB2 como nivel bajo
Necesitaria hacer que cuando cada ves que se realice una activacion del sensor nivel bajo este las bombas trabajen de forma alternada y por ultimo que cuando trabaje el nivel alto se desactiven las dos bombas hasta que ya no alla ningun nivel activo... les agradeceria mucho si pudieran ayuudarme!!!
;
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
; ZONA DE CÓDIGOS ********************************************************************
ORG 0 ; El programa comienza en la dirección 0.
Inicio
clrf PORTB ; Debe estar a cero cuando el puerto se configure
; como salida.
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf TRISA
bcf STATUS,RP0 ; Acceso al Banco 0.
Principal
movf PORTA,W ; Lee los sensores.
andlw b'00000011' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Configuracion0
goto Configuracion1
goto Configuracion2
goto Configuracion3
Configuracion0
movlw b'00000001' ; Estado "Vacio" (configuración 0).
goto ActivaSalida
Configuracion1
movlw b'01000010' ; Estado "Llenándose" (configuración 1).
goto ActivaSalida
Configuracion2
movlw b'01100100' ; Estado "Lleno" (configuración 2).
goto ActivaSalida
Configuracion3
movlw b'01100100' ; Estado "Lleno" (configuración 2).
goto ActivaSalida
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
-
Hace mucho que no toco ASM por lo que ya recuerdo poco, pero decirte que casi que tendrias que cambiar el algoritmo de tu programa y por ejemplo dividirlo en subfunciones, es decir, cuando detecte el primer sensor ir a un bucle "goto" y desde el hacer las combrobaciones, si sigue solo el primer sensor me quedo en este bucle e incremento un contador, cuando el contador llega a X y sigue el primer sensor cambio de bomba, y asi hasta detectar que el sensor esta apagado, entonces un goto a principal o que estan los dos sensores activados y entonces un "goto" a otro bucle activando las dos salidas y esperando a que los dos sensores esten apagados para ir de nuevo a principal.
Otro detalle que veo en tus configuraciones, creo que a la configuración 2 nunca llegaras, ya que si el sensor de "nivel alto" esta activo el de "nivel bajo" tembien tienes que estaro :) por lo que la config. 1 0 es imposible.
-
Gracias por tu pronta respuesta.... sigo trabajando en el codigo... y ya pude hacer que cuando llega al nivel algo se desactiven las bombas hasta que no alla ningun sensor activado... solo me faltaria hacer el cambio de bomba cada ves que se active el sensor nivel bajo... dejo el codigo... si me pudieran dar otra ayudadita no estaria de mas XD graciaas!!!
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
; ZONA DE CÓDIGOS ********************************************************************
ORG 0 ; El programa comienza en la dirección 0.
Inicio
clrf PORTB ; Debe estar a cero cuando el puerto se configure
; como salida.
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf TRISA
bcf STATUS,RP0 ; Acceso al Banco 0.
Principal
movf PORTA,W ; Lee los sensores.
andlw b'00000011' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Vacio
goto NivelBajo
goto NivelAlto
goto NivelAlto
Vacio
movlw b'00000001' ; Estado "Vacio"
goto ActivaSalida
NivelBajo
movlw b'01000010' ; Estado "Llenándose"
goto ActivaSalida
NivelAlto
movlw b'01100100' ; Estado "Lleno"
movwf PORTB ; Visualiza por el puerto de salida.
movlw b'00110' ; Estado "Lleno"
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA (IF W == PUERTOA)
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z (IF W==PUERTOA THEN Z=0 ELSE Z=1)
GOTO Off ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivelbajo
movwf PORTB ; Visualiza por el puerto de salida.
GOTO NivelAlto
Off
movlw b'0010' ; Estado "Vacio" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA (IF W == PUERTOA)
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z (IF W==PUERTOA THEN Z=0 ELSE Z=1)
GOTO Off2 ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivel bajo
movwf PORTB ; Visualiza por el puerto de salida.
GOTO NivelAlto
Off2
movlw b'00000' ; Estado "Vacio" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA (IF W == PUERTOA)
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z (IF W==PUERTOA THEN Z=0 ELSE Z=1)
GOTO NivelAlto ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'00000000' ;Mandamos nivel bajo
movwf PORTB ; Visualiza por el puerto de salida.
GOTO ActivaSalida
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
-
vale, ok, entendi mal lo de alternar los motores. Para esto necesitaras un sistema de banderas, utilizando los bits de una variable. Un bit para saber que motor utilizar y otro bit para saber cuando cambiar el primer bit.
el sistema a seguir podria ser este:
- Al iniciar pones todos los bits de la variable a 0
- Al entrar en "NivelBajo" pones el bit0 de la variable a 1 (Este indicará que cambiaremos de bit despues)
- Ahora leemos el bit1, si es 0 encendemos un motor, si es 1 encendemos el otro.
- Al entrar en "Vacio" leemos el bit0, si es 0 no hacemos nada (pones el portb como antes y saltas a principal)
si es 1 (lee el *) lo ponemos a 0 y leemos el bit1, si bit1 es 0 lo ponemos a 1
si bit1 es 1 lo ponemos a 0
* para lograr esto, creo que seria suficiente con hacer "swapf" a la variable.
*Rectifico: para lograr esto, negaremos los bits 0 y 1 cargando en el registro W y utilizando la instruccion xorwf
Espero entiendas lo que intento decir, un saludo
-
amigo podrias darme un ejemplo del codigo??? soy muy novato en esto, te lo agradeceria muchisisimo!!!
-
Vamos a ver que recuerdo de ASM... jejej
1º declarar la variable, eso va antes que el ORC:
CBLOCK 0x0C
Variable
ENDC
2º En principal la iniciamos a 0: clrf Variable
3º En NivelBajo
NivelBajo
movlw b'01000010' ; Estado "Llenándose" ---> motor 1 por defecto
bsf Variable,0 ; bit0 de vriable a 1
btfsc Variable,1 ; Salta si el bit1 es 0 (sino cambiara el motor)
movlw b'00100010' ; Estado "Llenándose" ---> motor 2
goto ActivaSalida
4º En Vacio:
Vacio
btfsc Variable,0 ; si el bit0 es "1" no saltara y cambiara los nibbles de la variable
swapf Variable,1
movlw b'00000001' ; Estado "Vacio"
goto ActivaSalida
Creeeo si no me equivoco que con esto deve bastar, recuerda que la alternación de las salidas sera siempre que no se apague el pic ya que tenemos la variable cargada en RAM, cada vez que se apague el pic empezara por el motor 1. Para solucionar esto tendrias que guardad la variable en la Eeprom.
Saludos
-
Amigo gracias por tu ayuda!!! solo un detalle... a la hora de compilar me manda error en Variable, sabes pq sera??
-
Asi es a mi entender como deberia de quedar el codigo con la ayuda que me diste, pero como te digo, a la hora de compilar me manda error :S!!!
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
Variable
ENDC
; ZONA DE CÓDIGOS ********************************************************************
Inicio
ORG 0 ; El programa comienza en la dirección 0.
clrf PORTB ; Debe estar a cero cuando el puerto se configure
; como salida.
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf TRISA
bcf STATUS,RP0 ; Acceso al Banco 0.
Principal
clrf Variable
movf PORTA,W ; Lee los sensores.
andlw b'00000011' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Vacio
goto NivelBajo
goto NivelAlto
goto NivelAlto
Vacio
btfsc Variable,0 ; si el bit0 es "1" no saltara y cambiara los nibbles de la variable
swapf Variable,1
movlw b'00000001' ; Estado "Vacio"
goto ActivaSalida
NivelBajo
movlw b'01000010' ; Estado "Llenándose" ---> motor 1 por defecto
bsf Variable,0 ; bit0 de vriable a 1
btfsc Variable,1 ; Salta si el bit1 es 0 (sino cambiara el motor)
movlw b'00100010' ; Estado "Llenándose" ---> motor 2
goto ActivaSalida
NivelAlto
BSF 0X0C,C
movlw b'01100100' ; Estado "Nivel Alto"
movwf PORTB ; Visualiza por el puerto de salida.
movlw b'00110' ; Estado "Nivel Alto"
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO Off ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivelbajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO NivelAlto
Off
movlw b'0010' ; Estado "Nivel" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO Off2 ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivel bajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO NivelAlto
Off2
movlw b'00000' ; Estado "Vacio" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO NivelAlto ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'00000000' ;Mandamos nivel bajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO ActivaSalida
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
-
Mmmm... a simple vista me parece correcto, ahora me tomaré algo de tiempo para revisarlo. (en que linea te da el error?)
Otra cosa que no es motivo de error pero daría un funcionamiento erratico es el "clrf Variable" que lo tienes en Principal y tiene que estar en Inicio
Voy a instalar el MPLab y te comento. Saludos
-
El error en variable es debido a que Variable es palabra reservada del ensamblador, si le pones otra b por ejemplo (Variabble) verás como no te da el error,
Para ini cializar una variable siempre es mejor ponerla en inico como dice tannke.
Saludos
-
Cuanta razón tienes! Creo que me habría costado encontrarlo, muchas gracias, jejej no recordaba las palabras reservadas. Bueno, a parte de esto, he encontrado otro gravisimo error por parte mia y es que la instrucción "swapf" intercambia los niveles alto por el bajo y al revés, y yo iva convencido... que negaba los niveles (conectado a masa estaba yo)
Por lo que lo que hay que sustituir esa instrucción por una Or Exlusiva (xorwf) cargando w con 0x03 (b'00000011) para que niegue los 2 primeros bits que son los que realmente nos interesan.
Te dejo tu codigo modificado, compilado y simulado sin aparentemente ningun error.
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
Variabble
ENDC
; ZONA DE CÓDIGOS ********************************************************************
Inicio
ORG 0 ; El programa comienza en la dirección 0.
clrf PORTB ; Debe estar a cero cuando el puerto se configure
; como salida.
clrf Variabble
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf TRISA
bcf STATUS,RP0 ; Acceso al Banco 0.
Principal
movf PORTA,W ; Lee los sensores.
andlw b'00000011' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Vacio
goto NivelBajo
goto NivelAlto
goto NivelAlto
Vacio
movlw b'00000011'
btfsc Variabble,0 ; si el bit0 es "1" no saltara y negara los bits 0 y 1
xorwf Variabble,1
movlw b'00000001' ; Estado "Vacio"
goto ActivaSalida
NivelBajo
movlw b'01000010' ; Estado "Llenándose" ---> motor 1 por defecto
bsf Variabble,0 ; bit0 de vriable a 1
btfsc Variabble,1 ; Salta si el bit1 es 0 (sino cambiara el motor)
movlw b'00100010' ; Estado "Llenándose" ---> motor 2
goto ActivaSalida
NivelAlto
BSF 0X0C,C
movlw b'01100100' ; Estado "Nivel Alto"
movwf PORTB ; Visualiza por el puerto de salida.
movlw b'00110' ; Estado "Nivel Alto"
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO Off ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivelbajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO NivelAlto
Off
movlw b'0010' ; Estado "Nivel" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO Off2 ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'01100100' ;Mandamos nivel bajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO NivelAlto
Off2
movlw b'00000' ; Estado "Vacio" .
XORWF PORTA ;COMPARAMOS W CON EL PUERTOA
BTFSS STATUS,Z ;RESULTADO DEL FLAG Z
GOTO NivelAlto ;SI Z ES IGUAL A 1 ENTONCES VAMOS A SEGUIR
MOVLW B'00000000' ;Mandamos nivel bajo
movwf PORTB ;Visualiza por el puerto de salida.
GOTO ActivaSalida
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
Por cierto que bueno volver a toquetear algo de ASM
Saludos.
-
Amigos muchas gracias por su ayuda... acabo de compilar el programa y emulado en el proteus... y quedo de maravilla exactamente lo que io necesitaba!!!! :-/ :mrgreen: ;-)!!!!GRACIAAAAAAAAAAAAAAAAAAS!!!!
-
ahora estoy tratando de pasar este codigo a un pic 18f2550 pero no pasa nada... que es lo que deberia de cambiar o que debo de hacer??? alguien podria ayudarmeeeee!!! se lo agradeceria muchooo!!!
-
Lo siento con pic 18 ya si que no tengo ni idea, y la poca esperiencia que tengo con ellos es solamente con C. Pero lo que es seguro es que tal cual no te funcionara. Tendrás que pillar el datasheet y mirartelo ya que cambian muchas cosas.
Lo siento, un saludo.
-
Te mandaron pasarlo a un 18f? Porque sino no tiene sentido, tendria sentido pasarlo a un 12f o incluso a un 10f, porque ya en el 16f84A te sobra de todo, flash, RAM, pines...y eso que es el mas pequeño de los 16f
De 18f en assembler encontraras poco, esto es de lo poco que hay, la serie 18f se programa casi siempre en C.
http://www.todopic.com.ar/foros/index.php?topic=22737.0
-
Gracias por la pronta respuesta de todos...!!! es todo un caos programar en los 18f no les entiendo nadaaaaa y hay MUUUUUY poca info...!!! ya no se ke haceeeeeeeeer!!! :5]
Alguien sabe de algun ejemplo o como poder visualizar un hola mundo en un 18f2550 con un lcd 16x2??