TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Pepe en 30 de Noviembre de 2014, 10:27:27
-
Buenas Dias amigos
Estoy realizando un proyecto es la primera vez que trabajo con pic el proyecto es el siguiente tengo tres pulsadores los conecto al PORTA del Pic cada uno debe de contar hasta un numero cualquiera cuando llega al numero deseado debe activar una salida del PortB y así sucesiva mente con cada pulsador cuando tengo las tres salidas activadas se debe activar una cuarta salida lo tengo que realizar en ensamblador Mplab pero no me sale nada.
Muchas gracias por sus aportes
-
Por favor, no repitas mensajes, esta en contra de las reglas del foro.
http://www.todopic.com.ar/foros/index.php?topic=43791.msg362854#msg362854
Alli ya te habian contestado.
Tenes varias formas de encarar el proyecto, pero ASM exige que sepas en profundidad del microcontrolador. Es decir aprenderte el datasheet. Te podria decir que busques acerca de:
- Demoras ( hay programitas incluso que te generan el codigo de las demoras )
- Configuracion de los puertos ( esto lo buscas en la hoja de datos, te dice cuales registros modificar )
- Tener a mano la lista de instrucciones asi como tambien su explicacion de como funciona, tambien se encuentra en el datasheet del micro.
- Y deberias tener un antirebote externo, asi no te complicas con el programa
Tu codigo seria algo asi:
Declaracion de variables
Configuracion inicial
MAin:
Se activo entrada 1 ? SI -> voy a la funcion de salida 1 // Esto son 2 instrucciones en ASM
Se activo entrada 2 ? SI -> voy a la funcion de salida 2
Se activo entrada 3 ? SI -> voy a la funcion de salida 3
Estan activas todas las entradas ? SI -> voy a la funcion que enciende la salida 4 // Esta te llevaria un poco mas, 3 instrucciones.
vuelvo a Main
salida1:
Asigno valores Demora
Cambio salida
vuelvo
salida2:
Asigno valores Demora
Cambio salida
vuelvo
salida3:
Asigno valores Demora
Cambio salida
vuelvo
salida4:
Cambio salida
vuelvo
Demora:
Realizo demora
vuelvo
Tambien depende del micro que estes usando.
-
Hola amigos estuve revisando el proyecto y lo interprete mal los tres pulsadores son un pulsador de conteo, uno de reset y uno de enter entonces escojo un numero empiezo a presionar el pulsador hasta llegar a el, presiono el enter y continuo con el segundo numero y así hasta tener cuatro números cada vez que llego al numero deseado se activa una salida del PortB
Cualquier aporte Muchas gracias
-
Entonces mi pseudocogido tampoco esta tan errado:
Declaracion de variables
Configuracion inicial
MAin:
Se activo entrada Reset ? SI -> voy a la funcion de Reset // Esto son 2 instrucciones en ASM
Se activo entrada Enter ? SI -> voy a la funcion de salida 2
Se activo entrada Contar ? SI -> voy a la funcion de salida 3
vuelvo a Main
Reset:
Puerto=0
Contador=0
Posicion=0
vuelvo
Contar:
w = valorviejopuerto XOR portx // Estoy revisando que no me cuente muchas veces el mismo valor, siempre y cuando teniendo el antirebote externo.
Si es distinto de 0
{
Si la entrada esta en alto hacer {
valorviejopuerto = portx
Contador + 1
}
}
vuelvo
Enter:
w = valorviejopuerto XOR portx
Si es distinto de 0
{
valorviejopuerto = portx
Numero + 1
Si Contador es igual al x numero
Activo salidax
Sino // Aca depende de vos si queres resetear todo por no cumplir con los valores.
}
vuelvo
Como te dijeron si ya tenes un codigo mejor. Es mas facil de poder ayudarte, por que nadie se va a poner a hacer el codigo de tus proyectos. O presentas el codigo y pregunta por que no funciona X cosa. Y de seguro que te responden rapido.
-
Buenas este es el codigo que tengo pero no me funciona solo es la parte de conteo y encendido de salida todavia sin el enter pero lo que me hace es cuenta hasta 4 y enciende una salida pero el siguiente numero es 6 y no me empieza de nuevo en cero sino que sigue contando y me enciende la segunda salida a los pulsos
list p=16f84a
include P16F84a.INC
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
org 0
inicio
bsf STATUS,RP0
movlw b'00000000'
movwf TRISB
movlw b'11111'
movwf TRISA
movlw b'00111000'
movwf OPTION_REG
bcf STATUS,RP0
clrf TMR0
clrf PORTA ; inicialización del puerto A
clrf PORTB ; inicialización del puerto B
bucle
movf TMR0,W
xorlw .4
btfsc STATUS,Z
goto encender
goto bucle
encender
bsf PORTB,2
segundoled
movf TMR0,W
xorlw .6
btfsc STATUS,Z
goto INSTRU
goto segundoled
INSTRU
bsf PORTB,3
clrf TMR0
goto bucle
end
-
Bueno veo que estas usando el TMR0 para contar los pulsos.
movlw b'00111000'
movwf OPTION_REG
Con esa configuracion tenes el prescaler activado, que en el TMR el minimo es de 1:2 , es decir 2 pulsos de entrada para que cuente 1. a no ser que pongas el bit PSA en 0, Te esta contando bien los pulsos de esa forma ?
bucle
movf TMR0,W
xorlw .4
btfss STATUS,Z
goto bucle
bsf PORTB,2 ; No necesitas la bandera encender
clrf TMR0
Podes cambiar tu codigo por esto, y cambiar la condicion de si es 0 BTFSC, y si no es 0 BTFSS, ahorrandote un salto. Aunque esto es solamente para acortar el codigo.
Tambien notaras que borre el registro TMR0 para que vuelva a comenzar de 0 antes de comenzar a contar para el segundo led.
segundoled
movf TMR0,W
xorlw .6
btfss STATUS,Z
goto segundoled
bsf PORTB,3 ; No necesitas la bandera INSTRU
clrf TMR0
goto bucle
Y con este ya tendrias tu segundo led. Y comenzarias de nuevo. pero te quedarian los 2 leds prendidos y ya no verias mas cambios hasta que lo resetees.
Debo aclarar que esto no tiene el boton "Enter" ni "Reset" que vos pedis, sino que solo cuenta la cantidad de pulsos y cuando llega a cierta cantidad prende los leds, pone a 0 el contador y cuando llega a cierta cantidad vuelve a prender los leds.
Si no deberias seguir masomenos mi pseudocodigo. Es decir una rutina principal que lea los botones y de ahi que vaya a otra rutina segun que boton se presiono.
Otra de las cosas es que tenes que acostumbrarte es que tenes el vector de interrupcion en 0x04 a pesar que no lo uses mejor tenerlo
Asi que el comienzo de programa deberia ser:
org 0x00 ; Vector de reset
goto inicio
org 0x04 ; Vector de interrupcion
goto inicio
inicio
;Aca tu programa
-
gracias por su ayuda killerjc tuve dos problemas cuando cambie el codigo ahora las dos salidas se activan de una vez a penas lo corro en proteus
este es el codigo
list p=16f84a
include P16F84a.INC
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
org 0X00
goto inicio
org 0x04
goto inicio
inicio
bsf STATUS,RP0
movlw b'00000000'
movwf TRISB
movlw b'11111'
movwf TRISA
movlw b'00111000'
movwf OPTION_REG
bcf STATUS,RP0
clrf TMR0
clrf PORTA ; inicialización del puerto A
clrf PORTB ; inicialización del puerto B
bucle
movf TMR0,W
xorlw .4
btfsc STATUS,Z
goto bucle
bsf PORTB,2
clrf TMR0
segundoled
movf TMR0,W
xorlw .6
btfsc STATUS,Z
goto segundoled
bsf PORTB,3
clrf TMR0
goto bucle
end
como puedo solucionarlo.
el boton de reset pensaba hacerlo así
1. un pulsador a tierra que va conectada a una r de 100 y al otro extremo a la patilla mclr y en paralelo una r de 10k conectada a vdd esto lo tome de un libro que estoy estudiando
y lo otro del pulsador de enter trate de hacerlo con subrutinas pero no funciono y no tengo idea de como hacerlo
-
Vamos a enumerar las respuestas:
1-
list p=16f84a
include P16F84a.INC
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
org 0X00
goto inicio
org 0x04
goto inicio
inicio
bsf STATUS,RP0
movlw b'00000000'
movwf TRISB
movlw b'11111'
movwf TRISA
movlw b'00111000'
movwf OPTION_REG
bcf STATUS,RP0
clrf PORTA ; inicialización del puerto A
clrf PORTB ; inicialización del puerto B
bucle
movf TMR0,W
xorlw .4
btfsc STATUS,Z
goto bucle
bsf PORTB,2
clrf TMR0
segundoled
movf TMR0,W
xorlw .6
btfsc STATUS,Z
goto segundoled
bsf PORTB,3
clrf TMR0
goto bucle
end
Te olvidaste cambiar los BTFSC STATUS,Z por BTFSS STATUS,Z
2-
Con respecto al circuito para el antirebote podes usar cualquiera de estos (en especial para el boton "Enter"):
(http://perso.wanadoo.es/pictob/imagenes/antireb.gif)
En el primero vas a tener un 1 cuando este presionado y en el segundo un 0 cuando lo presiones, generalmente el primero es el mas usado.
Tu reset puede ser el que vos quieras. O que te resetee el micro completamente. Es decir un reset a nivel hardware. Me imagino tu circuito como en esta imagen ( la de la izquierda, o si hiciste el cricuito que recomienda el datasheet podes agregar solo el pulsador ):
http://what-when-how.com/wp-content/uploads/2011/06/tmp997_thumb_thumb.jpg
O que sea mediante software y solo pongas los puertos en 0 y pongas al programa a la espera del primero numero.
Por eso mi pregunta en una de las respuestas que te di fueron:
Que ocurre cuando presionas Enter y el "codigo" o la cantidad que presionaste no coincide con lo que queres. Ejemplo presione 5 veces y en la primera era 4, y luego presiono Enter. Que ocurriria en ese caso ?
Depende de como me respondas la ultima pregunta es como hacerlo. Al principio pense en el uso de 3 pulsadores pero no usar el TMR0 para contar. Sino algo asi:
list p=16f84a
include P16F84a.INC
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
PORTVIEJO EQU 0x0C
NUMERO EQU 0x0D
CUENTA EQU 0x0E
org 0X00
goto configuracion
org 0x04
goto configuracion
configuracion
bsf STATUS,RP0
movlw b'00000000'
movwf TRISB
movlw b'11111'
movwf TRISA
clrf OPTION_REG
bcf STATUS,RP0
clrf TMR0
clrf PORTA ; inicialización del puerto A
clrf PORTB ; inicialización del puerto B
clrf PORTVIEJO ; inicializo mis variables a 0
clrf NUMERO
clrf CUENTA
principal ;Rutina principal donde verificamos todos los botones
BTFSC PORTA,0 ;Primer boton, supongo Enter
CALL enter
BTFSC PORTA,1 ; Segundo boton Reset
CALL reset
BTFSC PORTA,2 ; Tercer boton contador
CALL contar
; Si suelta actualizo mi variable portviejo, esto esta medio mal ya que si presionas justo sobre la actualizacion no entraria a la funcion
; y deberias de buscar una mejor alternativa
MOVF PORTA,W
MOVWF PORTVIEJO ;Actualizo el valor de mi variable por si se pone a 0
GOTO principal
contar
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z ;Si entro por 2da o mas veces aca por que se mantuvo presionado entonces que no cuente otra ves
RETURN
INC CUENTA ;Sumo a la cuenta
RETURN
reset ; Aca no importa si entra 20 veces xD
CLRF PORTB ; Limpio todas las variables usadas y el puerto lo pongo a 0
CLRF NUMERO
CLRF CUENTA
RETURN
enter
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z
RETURN
;Aca lo podes hacer de distintas formas con tablas, o con bit test y GOTO etc.
CALL tabla
SUBWF CUENTA,W ; Reviso que la cantidad presionada sea la correcta, resto y si da cero entonces es correcto
BTFSS STATUS,z
GOTO error
BSF PORTB,NUMERO ; Pongo a 1 la salida RB0,1,2 segun lo que valga NUMERO. Esto exige q la salidas esten ordenadas. si las queres desordenadas tenes que preguntar por cada valor o utilizar otra tabla :3 + goto
INC NUMERO ; Paso al siguiente numero, es decir 6 segun la tabla.
MOVLW 0x03
SUBWF NUMERO,W ; Le resto 3 a Numero y lo guardo en W para saber si numero llego a 3, es decir ya pasaron 0,1 y 2
BTFSS STATUS,z
RETURN ; Si no llego a 4 entonces que vuelva al principal
BSF PORTB,NUMERO ; Por ultimo pongo en alto la ultima salida. RB3
CLRF NUMERO ; Si llega al 4to valor que resee los valores de numero y cuenta, el portb quedaria encendido
CLRF CUENTA ; y con el reset lo borrarias o presionando enter y con un numero mal tambien.
RETURN
error ; Si al presionar enter la cantidad no es correcta, limpio todo y vuelvo a 0 ?
CLRF PORTB
CLRF NUMERO
CLRF CUENTA
RETURN
; En la tabla tenes todos tus valores a comparar, podes agregar mas y cambiar el limite de NUMERO en la ruina de "enter"
tabla
MOVF NUMERO,W
ADDWF PCL ; PCL <- PCL + numero
RETLW 0x04 ; Tu primer valor a contar
RETLW 0x06 ; Tu segundo valor
RETLW 0x02 ; Tu tercer valor
Tambien podes definir las variables o lugares de memoria como
CBLOCK 0x0C
PORTVIEJO
NUMERO
CUENTA
ENDC
Asi no te preocupas por darle la direccion a cada uno. Y es mas simple para muchos registros. Pero eso depende del gusto de cada uno.
El 0x0C es por que ahi comienza los registros de uso general que posee el PIC16F84A fijate en el datasheet en organizacion de memoria
-
BUENAS una vez mas muchas gracias por su ayuda tengo un duda cuando lo copilo me sale estos errores
Error[122] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 55 : Illegal opcode (CUENTA)
Error[113] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 73 : Symbol not previously defined (error)
Warning[202] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 74 : Argument out of range. Least significant bits used.
Warning[207] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 75 : Found label after column 1. (INC)
Error[122] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 75 : Illegal opcode (NUMERO)
Warning[202] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 80 : Argument out of range. Least significant bits used.
Warning[205] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 85 : Found directive in column 1. (error)
Error[128] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 85 : Missing argument(s)
Message[305] F:\KAREN MORA CHAVES\DESKTOP\EXAMEN 1\PRUEBA 15.ASM 96 : Using default destination of 1 (file).
que pueden ser
eso que es como una libreria
-
con la respuesta a la pregunta que pasa si se pasa de numero no especifica el proyecto pero seria que no se activa la salida
-
Buenas lo cambie algunas partes del codigo para eliminar errores pero creo que le provoque :? y me copilo pero lo pongo en proteus y no hace nada
list p=16f84a
include P16F84a.INC
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
PORTVIEJO EQU 0x0C
NUMERO EQU 0x0D
CUENTA EQU 0x0E
ORG 0X00
GOTO configuracion
ORG 0x04
GOTO configuracion
configuracion
BSF STATUS,RP0
MOVLW b'00000000'
MOVWF TRISB
MOVLW b'1111111'
MOVWF TRISA
CLRF OPTION_REG
BCF STATUS,RP0
CLRF PORTA ; inicialización del puerto A
CLRF PORTB ; inicialización del puerto B
CLRF PORTVIEJO ; inicializo mis variables a 0
CLRF NUMERO
CLRF CUENTA
principal ;Rutina principal
BTFSC PORTA,0 ;Primer boton, Enter
CALL enter
BTFSC PORTA,1 ; Segundo boton Reset
CALL reset
BTFSC PORTA,2 ; Tercer boton contador
CALL contar
MOVF PORTA,W
MOVWF PORTVIEJO ;Actualizo el valor de mi variable por si se pone a 0
GOTO principal
contar
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z ;Si entro por 2da o mas veces por que se mantuvo presionado entonces que no cuente otra ves
RETURN
MOVF PORTA,W
MOVWF PORTVIEJO ;Actualizo el valor de mi variable
INCF CUENTA,W ;Sumo a la cuenta
RETURN
reset
CLRF PORTB ; Limpio todas las variables usadas y el puerto lo pongo a 0
CLRF NUMERO
CLRF CUENTA
RETURN
enter
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z
RETURN
CALL tabla
SUBWF CUENTA,W ; Reviso que la cantidad presionada sea la correcta, resto y si da cero entonces es correcto
BTFSS STATUS,Z
GOTO error1
BSF PORTB,NUMERO ; Pongo a 1 la salida RB0,1,2 segun lo que valga NUMERO.
INCF NUMERO,W ; Paso al siguiente numero, es decir 6 segun la tabla.
MOVLW 0x04
SUBWF NUMERO,W ; Le resto 4 a Numero y lo guardo en W para saber si numero llego a 4, es decir ya pasaron 0,1,2 y 3
BTFSS STATUS,Z
RETURN ; Si no llego a 4 entonces que vuelva al principal
BSF PORTB,NUMERO ; Por ultimo pongo en alto la ultima salida. RB4
CLRF NUMERO ; Si llega al 4to valor que desee los valores de numero y cuenta, el portb quedaria encendido
CLRF CUENTA ; y con el reset se borra o presionando enter y con un numero mal tambien.
RETURN
error1 ; Si al presionar enter la cantidad no es correcta, limpio todo y vuelvo a 0 ?
CLRF PORTB
CLRF NUMERO
CLRF CUENTA
RETURN
; En la tabla se encuentran todos tus valores a comparar, podes agregar mas y cambiar el limite de NUMERO en la ruina de "enter"
tabla
MOVF NUMERO,W
ADDWF PCL ; PCL <- PCL + numero
RETLW 0X04 ; primer valor a contar
RETLW 0X06 ; segundo valor
RETLW 0X02 ; tercer valor
RETLW 0X03
END
-
lo hice medio rapido, pero... Los INCF y el ADDWF deberia guardar el valor en el registro, es decir:
INCF CUENTA,F
INCF NUMERO,F
ADDWF PCL,F
Tambien no me di cuenta que
reset y error
parecen ser palabras reservadas, asi que deberias cambiarla y ponerle otro nombre.
Acabo de compilarlo y solo da 2 warning en donde usa la variable NUMERO para indicar la salida. diciendo que va a utilizar lo bits menos significativos, asi que no hay problema.
Ya que tenes el proteus podes debugearlo tambien si cargas el archivo .cof
con la respuesta a la pregunta que pasa si se pasa de numero no especifica el proyecto pero seria que no se activa la salida
Yo tome que si se pasa de numero, y se presiona Enter, como que falle y vuelva a comenzar todo. Como si hubieras presionado reset.
Me imagine una combinacion, como una clave para que se activen las salidas. si quisiera que solo el que sepa la clave la use, entonces cuando ponga mal la clave que se resetee. Si este fuera el caso no lo habria hecho asi xD, sino de otra forma xD. Pero bueno al menos deberia andar. Cambiale los INCF y agregale el F a esas 3 instrucciones y probalo. Y sino simulalo como te dije xD
Por ultimo debuggeandolo con el MPLAB, me encontre que los
BSF PORTB,NUMERO
No funcionan como yo queria, cuando NUMERO era 0 me activo RB5 creo y no RB0. Asi que hay que modificar esa parte del codigo, es decir la comprobacion y el encendido de cada numero xD, Por lo demas deberia andar correctamente.
Te dejo el ultimo codigo con el que probe:
configuracion
BANKSEL TRISA
MOVLW b'00000000'
MOVWF TRISB
MOVLW b'11111'
MOVWF TRISA
CLRF OPTION_REG
BANKSEL PORTA
CLRF PORTA
CLRF PORTB
CLRF PORTVIEJO
CLRF NUMERO
CLRF CUENTA
principal
BTFSC PORTA,0
CALL enter
BTFSC PORTA,1
CALL rest
BTFSC PORTA,2
CALL contar
MOVF PORTA,W
BTFSC STATUS,Z
MOVWF PORTVIEJO
GOTO principal
contar
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z
RETURN
INCF CUENTA,F
RETURN
rest
CLRF PORTB
CLRF NUMERO
CLRF CUENTA
RETURN
enter
MOVF PORTVIEJO,W
XORWF PORTA,W
BTFSC STATUS,Z
RETURN
CALL tabla
SUBWF CUENTA,W
BTFSS STATUS,Z
GOTO error1
BSF PORTB,NUMERO ;Esto a cambiar por algo que funcione.
INCF NUMERO,F
MOVLW 0x03
SUBWF NUMERO,W
BTFSS STATUS,Z
RETURN
BSF PORTB,NUMERO ; Esta tambien
CLRF NUMERO
CLRF CUENTA
RETURN
error1
CLRF PORTB
CLRF NUMERO
CLRF CUENTA
RETURN
tabla
MOVF NUMERO,W
ADDWF PCL,F
RETLW 0x04
RETLW 0x06
RETLW 0x02
END
Como dije solo falta arreglar eso... es decir la parte de la activacion de las salidas, eso ya depende de vos. Te termine dando el codigo completo por que hacia mucho que no tocaba ASM y pense que era una buena forma para no olvidarme xD.
Pero en fin, no copies pegues y compiles y probes asi nomas, trata de entender cada una de las secciones del codigo, el por que hago una cosa, o por que hago otra. Y tambien el como solucionar el problema del prendido de los leds.
Eso queda a tu deber y obviamente podes preguntar lo que sea.
-
muchas gracias por la ayuda, estaba pensando en utilizar un goto para cada una de las salidas que vuelva a leer w , sume y si es igual imprima la salida
así por cada uno.
-
muchas gracias por la ayuda, estaba pensando en utilizar un goto para cada una de las salidas que vuelva a leer w , sume y si es igual imprima la salida
así por cada uno.
Solamente deberias verificar que "Numero" es y prender la salida acorde a ese numero
-
Buenas Amigo
Estoy realizando otro proyecto en el cual utilizo un lcd 16 x 2 en este tengo cuatro pulsadores los cuales son incremente, decremente , derecha y izquierda entonces con esto gobierno el lcd ejemplo en la primera fila aparece la letra a pulso incrementa y pasa a b pulso derecha y pasa a otro carácter.pulso izquierda y se regresa al carácter anterior.
estuve leyendo y encontré una tabla
Instrucción. CODIGO Descripción
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1
Modo de 0 0 0 0 0 0 0 1 I/D S Donde I/D=0 Decremente la posición del cursor, I/D=1 incrementa la posición del cursor,. S=0 El texto de de entrada pantalla no se de desplaza, S=1 El texto de la pantalla se desplaza en el momento que se escribe uncarácter
caracteres
Lo que interpreto esque si yo pulso decremento a la salida de PortB deberia activarse las salidas B1 a B7 con ese codigo
la tabla la tome de esta pagina http://platea.pntic.mec.es/~lmarti2/practic9.htm