TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: velaki en 07 de Agosto de 2007, 14:47:25
-
Hola aqui dejo el codigo en ASM de lo que yo creia que era un contador de pulsos con entrada por RA4 y que se me visualizaran los leds en RB.
osea, quiero que al primer pulso se me encienda un led en RB1 y al quinto pulso se me encienda un led en ..... RB2 por ejemplo. pero no se si algo estará mal, espero que me pongais algun codigo en ASM para poder estudiarlo gracias..
list p=16f84
status equ 0x03
trisb equ 0x06
trisa equ 0x05
portb equ 0x06
porta equ 0x05
TMR equ 0x01
org 0
goto inicio
inicio bsf status,5
movlw b'00000000'
movwf trisb
movlw b'00111000'
movwf TMR
bcf status,5
clrf TMR
programa movf TMR,0
movwf portb
goto inicio
end
-
Hola amigo:
Por mi parte me parece que te faltan un par de cosillas, que te indico:
1º En el bucle de inicio no veo que cobfigures el puerto A como entrada por ningun lado. Tienes que configurar el registro ADCON1 como entradas salidas digitales y despues configurar el puerto A como entrada en su pin A4.
2º ¿Donde se almacenan los impulsos que cuentas por RA4?
3º Estas asignando a TMR un valor, luego lo borras, y despues lo sacas por el puerto B
de todo esto deduzco que siempre tienes en el puerto B =b'0000000' por lo que los led no estaaran activados.
Espero que esto te sirva para ir avanzando en tu programa.
Fermin
-
Como continuacion a mi mensaje anterior te adjunto un pequeño programa del tmro como contador por RA4.
bsf STATUS,RP0 ; Acceso al Banco 1.
movlw b'00111000' ; TMR0 como contador por flanco descendente de
movwf OPTION_REG ; RA4/T0CKI.
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf TMR0
Principal movf TMR0,w
movwf portb
..............................
goto principal
En realidad es muy parecido al tuyo, solo que el valor:movlw b'00111000' se le asigno al registro OPTION_REG para configurar el registro del tmro y que cuente los impulsos.
Tambien te he sacado le borrado del TMRO del bucle de principal,de esta forma no se resetea el contador.
Por su puesto he obviaado la asignacion del los registros internos del micro que tienes puesto asi como la conficguracion de los puertos.
Con esto te deberia de funcionar, pero debes de tener tambien en cuenta, el tema delos rebotes cada vez que se produzca el impulso de cuenta para que no cuente impulsos que no se deben de contar.
Con........ serian otras partes de tu programa si fueran necesarias.
Fermin
-
Fer_TACA el amigo velaki esta trabajando con el 16f84a, este micro no tiene el registro ADCON1 (ya qeu no posee conversor A/D), por tanto, no hace falta:
1º En el bucle de inicio no veo que cobfigures el puerto A como entrada por ningun lado. Tienes que configurar el registro ADCON1 como entradas salidas digitales
lo agregado por Fer_TACA en su segundo post esta muy bien, a ello puedes agregar la comparación del TMR0 con 5 que es la cantidad de pulsos qeu quieres contar:
..... por aca no te polvides de los trisa y trisb
bsf STATUS,RP0 ; Acceso al Banco 1.
movlw b'00111000' ; TMR0 como contador por flanco descendente de
movwf OPTION_REG ; RA4/T0CKI.
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf TMR0
Principal movf TMR0,w
xorlw .5
btfsc STATUS,Z
goto cambio
bsf PORTB,1
bcf PORTB,2
goto principal
cambio bcf PORTB,1
bsf PORTB,2
goto principal
mas o menos algo asi, solo que debes tener en cuenta qeu aca pregunta por 5 solo 5, y si ya es 6 vuelve a la condición inicial, por tanto solo debes colocar condiciones de mayor menor, y listo, esas condiciones seguramente las encuentas por el foro, sino postea tu propuesta y te ayudamos. Espero haberte ayudado.
Un saludo, adios.
-
Gracias por la correcion. :? :? :?
No me habia dado cuenta de que era el F84, será la constumbre de trabajar con los F87x y los 18F.
Fermin
-
org 0
inicio1
bsf status,5
movlw b'00000000'
movwf trisb
movlw b'11111'
movwf trisa
movlw b'00111000'
movwf optio
bcf status,5
clrf TMR
inicio
movf TMR,w
xorlw b'11'
btfsc status,2
goto cambio
bsf portb,1
bcf portb,2
goto inicio
cambio bcf portb,1
bsf portb,2
goto inicio
end
ESTE ES EL CODIGO COMPLETO, bueno, ahora se me activa la salida a los 3 pulsos, la verdad que estaba un poco liado, jeje, a partir de aqui voy a investigar lo de las comparaciones y tal. bueno y el tema de los rebotes de momento no me preocupa porque lo estoy simulando en PROTEUS.
GRACIAS POR TODOOO¡¡¡ :-/
-
busqeu sobre el tema, pues me interesa mucho, no habia hecho ese tipo de comparaciones antes, aca te los dejo un link seguramente que funcionan las rutinas, son preguntando por el Carry y el Zero:
http://www.todopic.com.ar/foros/index.php?topic=6075.0
un saludo
-
Amigo Cryn, he estado investigando un poco y creo que por aquí andarán los tiros... supuestamente este codigo tendria que hacer lo que explico, pero... por lo menos en proteus no actua asi....aqui te dejo para que des tu opinion.
; CUENTA LOS PULSOS PRODUCIDOS EN RA4, EN EL SEGUNDO PULSO ENCIENDE
UN LED EN PORTB, LUEGO LO APAGA, Y ENCIENDE DE NUEVO EL LED AL 5º PULSO... en teoria, ya digo, no se si estará bien...
list p=16f84
status equ 0x03
trisb equ 0x06
trisa equ 0x05
portb equ 0x06
TMR equ 0x01
optio equ 0x81
org 0
inicio1
bsf status,5
movlw b'00000000'
movwf trisb
movlw b'11111'
movwf trisa
movlw b'00111000'
movwf optio
bcf status,5
clrf TMR
inicio
bcf portb,0 ;esto lo pongo porque se me enciende este led y asi lo apago, jeje
movf TMR,w ;copio el valor del TMR al w
xorlw .2 ;OR entre w y el valor 2, osea a los 2 pulsos deveria de activarse el led, si no, pues a seguir esperando
btfsc status,2
goto cambio
bcf portb,1
bcf portb,2
goto inicio
cambio
bcf portb,1
bsf portb,2
goto inicio2
inicio2
bcf status,2
movf TMR,w
xorlw .5; ; ahora una vez qe se me activó con el segundo pulso, espero al quinto pulso para hacer lo mismo
btfsc status,2
goto cambio2
bcf portb,1
bcf portb,2
cambio2
bcf portb,1
bsf portb,2
goto inicio
end
-
vi tu codigo teine algunos errores, esta algo desordenado, ya que si enceindes o apagas un led, debes asegurarte que no vueva a pasar por esa linea de codigo ya qeu lo puede apagar o encender por accidente:
inicio
bcf portb,0 ;esto lo pongo porque se me enciende este led y asi lo apago, jej
esto no se lo hace en el bucle inicio, se lo hace antes, es la inicializacion del puerto, por eso es que seguramente cuando se enciende lo vuelve a apagar.
bsf portb,2
goto inicio2
inicio2 no tiene sentido porque inicio2 esta inmediatamente
Si quieres que se encienda el led despues de los 2 pulsos y se mantenga asi por un tiempo corto debes agregarle un retardo, para poder visualizar, ya que la velocidad el micro esta a 1MHz (si usas un cristal de 4MHz) por instrucción y eso no es visible si haces:
bsf PORTB,2
bcf PORTB,2
lo correcto seria con un retardo para ver el encendido:
bsf PORTB,2
call delay ;(delay es una rutina que debe ser creada, existen programas para ello como el PICDEL, o tu deberás imprementarla si es que quieres, considerando el vaor de la frecuencia del cristal que usaras)
bcf PORTB,2
por eso me anime a cambiar la condicion qeu mencionaste, y lo hice asi: a los 2 pulsos se enciende RB2 y al 5to pulso se apaga y vuelve a empezar, osea a los 2 pulsos otra vez se enciende, para esto el codigo es:
list p=16f84a
include P16F84a.INC ; haciendo el include no hace falta definir los registros (tris,option,status,port,etc.)
; ya que estan definidos en el archivo indicado, y se usasn los nombres que ahi dicen
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ; palabra de configuración
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 ; copio el valor del TMR0 al w
xorlw .2 ; XOR entre w y el valor 2, osea a los 2 pulsos deveria de activarse el led, si no, pues a seguir esperando
btfsc STATUS,Z
goto cambio
bcf PORTB,1
bcf PORTB,2
goto bucle
cambio
bcf PORTB,1
bsf PORTB,2
cambio1
movf TMR0,W
xorlw .5 ;ahora una vez qe se me activó con el segundo pulso, espero al quinto pulso para hacer lo mismo
btfsc STATUS,Z
goto cambio2
goto cambio1
cambio2
bcf PORTB,1
bcf PORTB,2
clrf TMR0 ; vuelvo a cero a TMR0 para comenzar otra vez la cuenta de 2
goto bucle
end
es mejor que uses el INCLUDE para evitar los EQU que colocaste, te ahorra lineas de esritura que debes hacer, y el status,5 por ejemplo se ve mejor y mas entendible como status,rp0. Tampoco te olvides del CONFIG
creo que con eso esta, bueno si tienes alguna duda o se me paso algo no dudes en preguntar, un saludo adios.
-
GRACIAS DE NUEVO , eso ante todo... Bueno, he solucionado elt problemilla, lo que me pasa con el INCLUDE esque al ponerlo y seleccionarlo en PROTEUS me dá 13 errores, no se porque me pasa eso pero de ahi que ponga las direcciones a mano, otra cosa, esto para que es? se que son los "FUSES" pero exactamente no se su fuincionamiento en el pic.
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ;
-
que bueno que hayas solucionado el tema, quisiera ver como lo hiciste si es que no te molesta, y como va eso del proteus?, yo lo compile y lo simule asi como esta arriba y no tube ningun problema, si puedes mandame tu simulacion (con el error), vale?
el CP es proteccion de codigo de programa, es decir si lo activas no podras leer el codigo en el programador
PWRTE significa POWER UP TIMER, creo qeu es un fuse que sirve para esperar un tiempo (muy corto) antes de ejecutar el programa para esperar que la fuente de alimentacion se estabilice.
WDT para activar o desactivar el perro guardian, que si esta activo retea al pic cuando desborda
XT_OSC selecciona el tipo de oscilador qeu usaras, xt indica que sera cristal maximo de 4Mhz (los rangos en la hoja de datos)
y si es que existiera otros fuses en la hoja de datos los encuentras todos
un saludo
-
GRACIAS DE NUEVO , eso ante todo... Bueno, he solucionado elt problemilla, lo que me pasa con el INCLUDE esque al ponerlo y seleccionarlo en PROTEUS me dá 13 errores, no se porque me pasa eso pero de ahi que ponga las direcciones a mano, otra cosa, esto para que es? se que son los "FUSES" pero exactamente no se su fuincionamiento en el pic.
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC ;
el FUSE creo que es inventado por el ccs (no se del C18) , el término correcto es configuration word, que se encuentra en una dirección aparte de programación y que es grabada por el grabador de micros.
-
Vale, concepto captado jeje, antes me equivoqué donde puse "proteus" quise decir Mplab, con tanto programilla se hace uno un lio a veces, el problema que tenia en mplab era que al poner el include siempre me daba porque no lo reconocia, y esque, yo lo estaba poniendo mal #include..., pero al ponerlo tal y como tu lo tienes en tu ejemplo ya no me dá problemas asi que me olvido de los "equ", aqui te dejo mi codigo por si quieres hecharle un vistazo no se si será lo que tu necesitas, porque yo no utilizo retardos, para lo que quiero utilizarlo no me hacen falta, pero supongo que con ponerselos vastaria, este es...
;ENCIENDE UN LED EN RB2 CUANDO SE DETECTA EL PRIMER PULSO EN EL CONTADOR
;QUE SE VA INCREMENTANDO CON RA4,CUANDO LLEGA A 5 PULSOS ACTIVA EL LED
;DE RB3.
;SI EL INTERRUPTOR DE RA1 ESTÁ ACTIVADO SOLO ACTIVARÁ EL LED DE RB2
;EN EL PRIMER PULSO DESCARTANDO LOS DEMAS PULSOS Y LA ACTIVACION
;DE RB3.
; ----SI PULSAMOS EL PULSADOR DE RA1 EL CONTADOR SE PONE A CERO---
by Velaki...
list p=16f84
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
status equ 0x03
trisb equ 0x06
trisa equ 0x05
portb equ 0x06
porta equ 0x05
TMR equ 0x01
optio equ 0x81
org 0
inicio1
bsf status,5
movlw b'00000000'
movwf trisb
movlw b'11111'
movwf trisa
movlw b'00111000'
movwf optio
bcf status,5
clrf TMR
principal
btfsc porta,1
goto inicio
clrf TMR
clrf portb
bsf portb,7
goto inicio
inicio
bcf portb,0
movf TMR,w
xorlw .1
btfsc status,2
goto cambio
bcf portb,1
bcf portb,2
goto principal
cambio
bcf portb,1
bsf portb,2
btfss porta,0
goto inicio
inicio2
btfss porta,1
clrf TMR
bcf status,2
movf TMR,w
xorlw .5
btfsc status,2
goto cambio2
bcf portb,1
bsf portb,2
goto inicio2
cambio2
bcf portb,1
bsf portb,3
bcf status,2
movf TMR,w
xorlw .6
btfss status,2
goto cambio2
clrf TMR
clrf portb
goto principal
end
COMO YA TE DIJE, este es el codigo que hace lo que necesito, ahora me toca cambiar los equ.. y depurar varias cosillas mas para dejarlo mejor.
SALU2
-
cuando se usa el Pxxxxx.inc nos ahorramos escribir el EQU, el EQU se escribe cuando usamos directamente el compilador, mpasm.exe / mpasmwin.exe porque hay que declarar los SFR, es decir, declarar los registros que usemos. Con el macro cblock nos ahorramos el equ para los GPR
SFR = Registro de Funciones eSpeciales.
GPR = Registro de Propósito General.
a mi gusto prefiero usar el IDE mplab, ya para los mas antiguos que se acostumbraron a la línea de comandos, la siguen usando, en fin es cuestión de gustos.
-
Buenas noches he estado leyendo todo lo relacionado como medir el tiempo por ra4, como se puede hacer en un 16f877a medir el tiempo en que se activa un
sesnsor,ejmplo:
se activo el sensor: de aqui en adelante cuanto se tardo en activarse nuevamente, todo esto es pq quiero hacer un pov led pero no com tiempos fijos definidos en el programa ya que voy a usar un motor y me gustaria variar la velocidad del motor, al momento de variar la velocidad del motor el tiempo de que se active el sensor varia y de alli obtener el tiempo de encendido y apagado de los leds......
tiempo final=tiempo obtenido(tmr0)/255 donde 255 es la cantidad de leds q va a tener el radio donde van a girar......
una manito con esto por favor....
-
Buenas noches he estado leyendo todo lo relacionado como medir el tiempo por ra4, como se puede hacer en un 16f877a medir el tiempo en que se activa un
RA4 es para contar pulsos no tiempo.
Para contar tiempos, creo que lo mejor es, detectar cuando cambia de estado el sensor (puedes hacerlo por interrupcion externa en PORTB) al hacer ese cambio de estado poner a contar un TIMER y cuando vuelva a cambiar lees ese timer, esta lectura sera el tiempo que el sensor estuvo activo o inactivo, tendras que descontar unas millonesimas que demoras en entrar en interrupcion, cargar TIMER etc.
¿Cuanto tiempo aproximado va a ser? ¿Que precision quieres? para esto si quieres mucha precision mejor usar TIMER1
-
tapi8...Gracias por responder..
¿Cuanto tiempo aproximado va a ser?
El tiempo es definido por la velocidad en que gire el motor, me explico si el motor va a 2500 rpm el tiempo en que pase por el sensor es bastante rapido a comparacion a 700 rpm.
¿Que precision quieres? para esto si quieres mucha precision mejor usar TIMER1
La mejor precision que se pueda, puesto que espara un pov y el tiempo de enceder y apagar los leds debe ser aceptable para que la imagen no se distorsiones a bajas y altas velocidades del motor.
He leido que lo mejor es con timer1 y un oscilador de 20 mhz, no me importaria usar otro pic solo para que me calcule el tiempo y al obtener el tiempo enviarlo al contolador principal donde v a estar cargado el codigo para mostrar las imagenes......
-
¿Cuanto tiempo aproximado va a ser?
El tiempo es definido por la velocidad en que gire el motor, me explico si el motor va a 2500 rpm el tiempo en que pase por el sensor es bastante rapido a comparacion a 700 rpm.
A 2500RPM no tienes problema te va a pasar cada 24ms, pero a 700RPM son 11.67Hz es una frecuencia baja , te va a pasar cada 85.69ms, TIMER0 solo cuenta hasta 65535ms, TIMER1 con un preescaler alto te puede valer, TIMER2 creo que tambien, o sino hacer varios desbordes, pero mejor con un solo desborde, creo que es mejor.
[La mejor precision que se pueda, puesto que espara un pov y el tiempo de enceder y apagar los leds debe ser aceptable para que la imagen no se distorsiones a bajas y altas velocidades del motor.
No tienes problema de precision, ya que la velocidad es baja. mas bien tendras problemas si a las velocidades mas bajas tarda mucho y desborda el TIMER antes de que pase el sensor.
He leido que lo mejor es con timer1 y un oscilador de 20 mhz, no me importaria usar otro pic solo para que me calcule el tiempo y al obtener el tiempo enviarlo al contolador principal donde v a estar cargado el codigo para mostrar las imagenes......
A 20Mhz contara mas rapido y desbordara antes, el oscilador "MAS LENTO" que puedas. Te debe llegar un solo PIC, pero eso depende de la complejidad del resto del programa.
-
****A 2500RPM no tienes problema te va a pasar cada 24ms, pero a 700RPM son 11.67Hz es una frecuencia baja , te va a pasar cada 85.69ms, TIMER0 solo cuenta hasta 65535ms, TIMER1 con un preescaler alto te puede valer, TIMER2 creo que tambien, o sino hacer varios desbordes, pero mejor con un solo desborde, creo que es mejor.
Seria cuestion de probar haber como seria la imagen cambiando los rpm del motor
****No tienes problema de precision, ya que la velocidad es baja. mas bien tendras problemas si a las velocidades mas bajas tarda mucho y desborda el TIMER antes de que pase el sensor.
si lo importante es la presicion de tiempo para poderlo dividir entre los 255 leds, si a bajas velocidades se ve mal, se coloca una instrucion de comparcion de tiempo, ejmplo:
tiempo= 100
si el timer es menor que 100 q borre el timer e inicie de nuevo hasta que timer sea igual a 100 o mayor para ejecute la funcion de mostrar de las imagenes
****A 20Mhz contara mas rapido y desbordara antes, el oscilador "MAS LENTO" que puedas. Te debe llegar un solo PIC, pero eso depende de la complejidad del resto del programa.
ok mejor trabajar con un cristal de 4 Mhz
Como puedo hacer el codigo, donde hay informacion concreta para hacerlo, anteriormente trabajaba con asm hace aos en el 2002 cuando estudiaba ahorita estoy retomando nuevamente pero nunca tuve la oportunidad de trabajar con timer ....
Gracias nuevamente por tomarte tu tiempo
-
Aqui tienes casi todo lo que hay que saber:
http://www.todopic.com.ar/foros/index.php?topic=24720.0
-
ok gracias por el dato