TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Enigma en 23 de Junio de 2007, 15:06:01
-
Hola que tal muy buenas tardes, tengo un problemita, vean estoy haciendo una temporización con el timer 0 pero para que me dure 1 segundo, entonces bueno hice esta rutina y creo que esta mala, puesto que cuando hago la simulación no me funciona correctamente... Por los resultados que he obtenido, lo que esta malo es la parte adicional para que me dure el segundo completo, porque cuando coloco al timer0 a desbordarse en su maximo, es decir, colocando el divisor de frecuencia en 256, si me funciona, pero lo malo es que así me dura solo 0,06528 Segundos, y con ese tiempo ni chance me va a dar ver el parpadeo de un led, además que durante ese tiempo es que voy a encender un motorsito de 5V, y bueno es muy poquitico tiempo.... No se alguien que me ayude aquí... esto es lo que estoy haciendo:
;-------RUTINA PARA QUE LA TEMPORIZACION ME DURE 1 SEGUNDO----------------
TIM3
BSF PORTE,0 ; ENCIENDO EL MOTOR
MOVLW 0X64 ; CARGO W CON 100
MOVWF CONT1 ; MUEVO ESO A LA VARIABLE CONTADOR
CICLO3
MOVLW .0 ; CARGO W CON 0
SUBWF CONT1,W ; RESTO CONT1 CON W
BTFSC STATUS,Z ; LAS UNIDADES LLEGARON AL FINAL? SALTA SI ES 0
GOTO PISO ; SI, ABRO LAS PUERTAS
MOVLW 0X00 ; NO, CARGO W CON 00000000
MOVWF TMR0 ; CARGO EL TIMER CON CERO
NADA3 BTFSS TMR0,7 ; PREGUNTO SIEMPRE POR EL BIT 7 DEL TMR0
GOTO NADA3 ; ME QUEDO HACIENDO NADA
GOTO CICLO3 ; REPITO EL PROCESO OTRA VEZ
;------------------------------INTERRUPCION DEL TIMER0-----------------------------------
INTERUMP
DECFSZ CONT1 ; DECREMENTO CONT1. SALTA SI ES CERO
RETFIE ; NO, ME DEVUELVO OTRA VEZ A SEGUIR CONTANDO
BCF PORTE,0 ; SI, APAGO EL MOTOR
RETFIE ;
Por cierto estoy utilizando un cristal de 4MHz, estoy trabajando con el PIC 16F877A, y estoy usando assembler (mplab)
Agradezco su gentil colaboración............!!!! gracias!!!!! :-/
Atte: Enigma... La llanerita de Guayana :P
-
¿Porqué verificas el bit7 del timer0 ? ¿porque no verificas el T0IF ?
-
Como en vez de colocar btfss TMR0,7 colocque BTFSS INTCON,2???.... ummm ya lo hice y nada..... ese timer nunca me sale del goto nada, es decir nunca me va a lainterrupción.... dios mio ya no se que hacer.... tengo todos lo cabellos arrancados....
Atte: Enigma.... la llanerita de Guayana :P
-
Como en vez de colocar btfss TMR0,7 colocque BTFSS INTCON,2???.... ummm ya lo hice y nada..... ese timer nunca me sale del goto nada, es decir nunca me va a lainterrupción.... dios mio ya no se que hacer.... tengo todos lo cabellos arrancados....
Atte: Enigma.... la llanerita de Guayana :P
Debiera funcionar y debieras tener en cuenta que lo debes 'borrar' al flago para volverlo a detectar una y otra vez.
-
A lo que se refiere Maunix es a al banderin por desborde del timer0 INTCON,T0IF . Sugiero que leas el datasheet la parte concerniente al registro INTCON ahi encontraras para que sirve y que utilidad lleva con el timer0. Si tienes dudas con el idioma aca puedes postear tus dificultades.
-
Y a hice todo eso, me percate de ese error, es decir, que no limpiaba la bandera del Timer0 en el vector de interrupción, pense que ese podria ser el error, pero nada chamo.... Cuando borre la bandera me pude dar cuenta que la cuestión esta en que el timer nunca se desborda, es decir, nunca el pic llega a la interrupción.... nunca sale del ciclo goto nada!!!....
Le he hecho de todo, lo he puesto a dormir haber si es que cae en ese ciclo infinito y nada... hasta copie uno que ya estaba hecho y compilado y que funciona supuestamente, y nada vale, no se si es problema con el simulador, pero no creo porque ya he hecho varios proyectos allí y todo me funciona al pelo!!! ese Timer me tiene con canas verdes, porque cabellos ya no me quedan!!!!!!! :x......... AUXILIO!!!!!!!!!!!!11 NECESITO AYUDA............. :-/........... Por favor alguien que se apiade de mi!!!!! POR FAVOR!!!!!!!!!!!!!!!!!! :(
Este fue el ultimo que hice, que suspuestamente me deberia durar 50 Segundos.... pero NADA!!!! :x
LIST P=16F877A
INCLUDE "P16F877A.INC"
CONT1 EQU 0X22 ;
CONT2 EQU 0X23 ;
ORG 0X00 ;
GOTO PRINCIPAL ;
GOTO 0X04 ;
GOTO INTERUMP ;
;------------------------------INTERRUPCION-----------------------------------
INTERUMP
BCF INTCON,2 ; LIMPIO LA BANDERA
RETFIE ; NO, ME DEVUELVO OTRA VEZ A SEGUIR CONTANDO
;-----------------------PROGRAMA PRINCIPAL---------------------
PRINCIPAL
BSF STATUS,RP0 ; SELECCIONA EL BANCO 1
MOVLW 0X47 ; MUEVO 01000111 A W
MOVWF OPTION_REG ; CONFIGURO LOS BITS DEL REGISTRO DEL TMR0
MOVLW 0XA0 ; MUEVO 10100000
MOVWF INTCON ; HABILITO GIE Y T0IE
MOVLW 0XCF ; PARA CONFIGURAR EL PUERTO B COMO SALIDA
MOVWF TRISB ; CONFIGURA EL PUERTO B COMO SALIDA
CLRF STATUS ; REGRESA AL BANCO 0
BSF PORTB,5 ; ENCIENDO EL MOTOR
MOVLW 0X2D ;
MOVWF CONT1 ;
TIEMPO
MOVLW 0X64 ; 100 EN DECIMAL
MOVWF CONT2 ;
TIEMPO1
MOVLW 0XD8 ; 216 EN DECIMAL
MOVWF TMR0 ;
NADA
BTFSC TMR0,7 ;
GOTO NADA ;
DECFSZ CONT2 ;
GOTO TIEMPO ;
DECFSZ CONT1 ;
GOTO TIEMPO1 ;
BCF PORTB,5 ;
STOP
NOP ;
END ;
Aqui pregunto por bit siete porque se que nunca va a cambiar a cero, siempre va a estar en uno.... y de igual manera si pregunto por el TOIF, lo mismo no se me sale de ese goto nada..... Estoy utilizando el mismo cristal de 4MHZ!!!!!
AAAAAaaaAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHhhhhhhhhhhh :x :x :x... ya no se que hacer......
Atte: Enigma... La llanerita de Guayana :P
-
Hola Enigma:
Te adjunto un codigo para generar una interrupcion de 1 segundo por el TMR0. A mi me funciona y me va bien espero que te sirva y puedas ver y/o comparar con tu programa.
Un saludo Fermin
EL PROGRAMA
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
ENDC
TMR0_Carga50us EQU -d'43' ; Obtenido experimentalmente con ayuda del
#DEFINE Salida PORTB,3 ; simulador del MPLAB.
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG 4 ; Vector de interrupción.
goto Timer0_Interrupcion
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
bcf Salida ; Esta línea se configura como salida.
movlw b'00001000'
movwf OPTION_REG ; Sin prescaler para TMR0 (se asigna al Watchdog).
bcf STATUS,RP0 ; Acceso al Banco 0.
movlw TMR0_Carga50us ; Carga el TMR0.
movwf TMR0
movlw b'10100000'
movwf INTCON ; Autoriza interrupción T0I y la general (GIE).
Principal ; No puede pasar a modo de bajo consumo
goto $ ; porque detendría el Timer 0.
; Subrutina "Timer0_Interrupcion" -------------------------------------------------------
;
; Como el PIC trabaja a una frecuencia de 4 MHz el TMR0 evoluciona cada microsegundo. Para
; conseguir un retardo de 50 microsegundos con un prescaler de 1 el TMR0 tiene que contar
; 43 impulsos. Efectivamente: 1µs x 1 x 43 + tiempo de los saltos y otros = 50 µs.
;
; Las instrucciones "nop" se ponen para ajustar el tiempo a 50 µs exacto y lograr una onda
; cuadrada perfecta. El simulador del MPLAB comprueba unos tiempos para la onda cuadrada de
; 10 kHz exactos de 50 µs para el nivel alto y otros 50 µs para el bajo.
Timer0_Interrupcion
nop
movlw TMR0_Carga50us
movwf TMR0 ; Recarga el TMR0.
btfsc Salida ; Testea el anterior estado de la salida.
goto EstabaAlto
EstabaBajo
nop
bsf Salida ; Estaba bajo y lo pasa a alto.
goto FinInterrupcion
EstabaAlto
bcf Salida ; Estaba alto y lo pasa a bajo.
FinInterrupcion
bcf INTCON,T0IF ; Repone flag del TMR0.
retfie ; Retorno de interrupción
END
-
Hola de nuevo:
me equivoque al ponerte la temporizacion no es de 1 segundos, el programa adjuntogenera retardos de 50 microsegundos, pero cambiando los valores puedes llegar al segundo. Pero para ver como te funciona la interrupcion por el TMR0 te pueede servir.
De todas formas te adjunto otro que genera tiempos de 0,5 y 0,8 segundos.
; Un LED conectado a la línea 1 del puerto de salida se enciende durante 500 ms y apaga
; durante otros 500 ms. Los tiempos de temporización se realiza mediante la utilización
; de la interrrupción por desbordamiento del Timer 0 del PIC.
;
; ZONA DE DATOS **********************************************************************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
Registro50ms ; Registro auxiliar para conseguir una temporización
ENDC ; mayor.
Carga500ms EQU d'10'
TMR0_Carga50ms EQU -d'195'
#DEFINE LED PORTB,1
; ZONA DE CÓDIGOS ********************************************************************
ORG 0 ; El programa comienza en la dirección 0.
goto Inicio
ORG 4 ; Vector de interrupción
goto Timer0_Interrupcion
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
bcf LED ; Línea del LED configurada como salida.
movlw b'00000111'
movwf OPTION_REG ; Prescaler de 256 para el TMR0
bcf STATUS,RP0 ; Acceso al Banco 0.
movlw TMR0_Carga50ms ; Carga el TMR0.
movwf TMR0
movlw Carga500ms
movwf Registro50ms
movlw b'10100000'
movwf INTCON ; Activa interrupción del TMR0 (TOIE) y la general.
Principal ; No se puede utilizar el modo bajo consumo
goto $ ; porque el timer se detiene.
; Subrutina "Timer0_Interrupcion" -------------------------------------------------------
;
; Como el PIC trabaja a una frecuencia de 4MHz, el TMR0 evoluciona cada microsegundo.
; El bucle central se hace en un tiempo de 50 ms. Para ello se utiliza un prescaler
; de 256 y el TMR0 tiene que contar 195 impulsos. Efectivamente:
; 195 x 256 = 49929 µs = 50 ms aproximadamente.
; Para conseguir una temporización de 500 ms, habrá que repetir 10 veces el lazo de 50 ms.
Timer0_Interrupcion
movlw TMR0_Carga50ms
movwf TMR0 ; Recarga el TMR0.
decfsz Registro50ms,F ; Decrementa el contador.
goto FinInterrupcion
movlw Carga500ms
movwf Registro50ms ; Repone el contador nuevamente
btfsc LED ; Testea el último estado del LED.
goto EstabaEncendido
EstabaApagado
bsf LED ; Estaba apagado y lo enciende.
goto FinInterrupcion
EstabaEncendido
bcf LED ; Estaba encendido y lo apaga.
FinInterrupcion
bcf INTCON,T0IF ; Repone flag del TMR0.
retfie
; Con el simulador del MPLAB se comprueba que los tiempos son: En alto 499261 µs y en
; bajo 499258 µs.
END
-
Hay chamo!!!!!!! hay!!! Chamo!!!! Fer_TACA muchacho Dios te bendiga, chamo has puesto fin a mi sufrimiento!!!!!! Dios como agradecerte!!!! Berro, pero tu programa tiene casi lo mismo que el mio a diferencia que tu hiciste el decremento del contador y todo eso dentro de la interrupción, me pregunto si eso tuvo algo que ver.... Además que lo pusiste a dar vuelticas en una misma linea.... Será que en el mio cuando lo ponia a dar vueltas en Goto nada, caia en un ciclo infinito??? umm!!!! No lo se!!! SI ALGUIEN PUDIERA RESPONDER ESTA INTERROGANTE, seria bueno para no volver a cometer el mismo error a futuro :?... en fin, lo modifique, y lo puse para tres segundos y funciona al pelo!!! Más fiiiiiino!!!! :-/.... Gracias de verdad...
y Gracias a todos los que me colaboraron también porque he aprendido más acerca de este temporizador corrigiendo los errores que todos me detectaron... y que bueno porque el sabado tengo exámen de esto y de interrupciones!!!! jejejejejeje :-)
Atte: Enigma... La llanerita de Guayana :P
-
Y a hice todo eso, me percate de ese error, es decir, que no limpiaba la bandera del Timer0 en el vector de interrupción, pense que ese podria ser el error, pero nada chamo.... Cuando borre la bandera me pude dar cuenta que la cuestión esta en que el timer nunca se desborda, es decir, nunca el pic llega a la interrupción.... nunca sale del ciclo goto nada!!!....
Le he hecho de todo, lo he puesto a dormir haber si es que cae en ese ciclo infinito y nada... hasta copie uno que ya estaba hecho y compilado y que funciona supuestamente, y nada vale, no se si es problema con el simulador, pero no creo porque ya he hecho varios proyectos allí y todo me funciona al pelo!!! ese Timer me tiene con canas verdes, porque cabellos ya no me quedan!!!!!!! :x......... AUXILIO!!!!!!!!!!!!11 NECESITO AYUDA............. :-/........... Por favor alguien que se apiade de mi!!!!! POR FAVOR!!!!!!!!!!!!!!!!!! :(
Este fue el ultimo que hice, que suspuestamente me deberia durar 50 Segundos.... pero NADA!!!! :x
LIST P=16F877A
INCLUDE "P16F877A.INC"
CONT1 EQU 0X22 ;
CONT2 EQU 0X23 ;
ORG 0X00 ;
GOTO PRINCIPAL ;
GOTO 0X04 ;
GOTO INTERUMP ;
;------------------------------INTERRUPCION-----------------------------------
INTERUMP
BCF INTCON,2 ; LIMPIO LA BANDERA
RETFIE ; NO, ME DEVUELVO OTRA VEZ A SEGUIR CONTANDO
;-----------------------PROGRAMA PRINCIPAL---------------------
PRINCIPAL
BSF STATUS,RP0 ; SELECCIONA EL BANCO 1
MOVLW 0X47 ; MUEVO 01000111 A W
MOVWF OPTION_REG ; CONFIGURO LOS BITS DEL REGISTRO DEL TMR0
MOVLW 0XA0 ; MUEVO 10100000
MOVWF INTCON ; HABILITO GIE Y T0IE
MOVLW 0XCF ; PARA CONFIGURAR EL PUERTO B COMO SALIDA
MOVWF TRISB ; CONFIGURA EL PUERTO B COMO SALIDA
CLRF STATUS ; REGRESA AL BANCO 0
BSF PORTB,5 ; ENCIENDO EL MOTOR
MOVLW 0X2D ;
MOVWF CONT1 ;
TIEMPO
MOVLW 0X64 ; 100 EN DECIMAL
MOVWF CONT2 ;
TIEMPO1
MOVLW 0XD8 ; 216 EN DECIMAL
MOVWF TMR0 ;
NADA
BTFSC TMR0,7 ;
GOTO NADA ;
DECFSZ CONT2 ;
GOTO TIEMPO ;
DECFSZ CONT1 ;
GOTO TIEMPO1 ;
BCF PORTB,5 ;
STOP
NOP ;
END ;
Aqui pregunto por bit siete porque se que nunca va a cambiar a cero, siempre va a estar en uno.... y de igual manera si pregunto por el TOIF, lo mismo no se me sale de ese goto nada..... Estoy utilizando el mismo cristal de 4MHZ!!!!!
AAAAAaaaAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHhhhhhhhhhhh :x :x :x... ya no se que hacer......
Atte: Enigma... La llanerita de Guayana :P
Pequeños errores, grandes desastres...
-
wou que detalle jijij ni me habia dado cuenta :mrgreen:
-
Me parece que Enigma sigue con el "enigma"... :D :D
Bueno, te lo comento:
el error surge porque pusiste:
en lugar de:
Ese pequeño detalle, costó caro porque si vemos cómo se ensambla tu código quedaría ubicado así:
| Ubicación | Vector ID: | Instrucción |
| 0x000 | Inicio/Reset | GOTO PRINCIPAL |
| 0x001 | | GOTO 0X04 |
| 0x002 | | GOTO INTERUMP |
| 0x003 | | BCF INTCON,2 |
| 0x004 | Interrupciones | RETFIE |
| 0x005 | | BSF STATUS,RP0 |
| ... | | ... |
Entonces, tu programa corre bien, hasta que surge la Interrupción. Cuando se ejecuta la interr, se ejecuta partiendo de la posicion 0x004, por lo que cuando ocurre, se ejecuta solamente la instruccion RETFIE(ver tabla). RETFIE es una instruccion que además de hacer un "RETURN", setea el bit INTCON,GIE es decir, habilita las interrupciones globales. Al hacerlo, sucede la catastrofe! el flag INTCON,T0IF continúa seteado!!!(debido a ese detalle que produjo que se acomodaran mal las lineas...). Como el INTCON,T0IF sigue seteado(ya que se ha esquivado la linea que lo ponía a cero), inmediatamente el PIC vuelve a ingresar a la rutina de interrupcion(0x004) volviendose a ejecutar el RETFIE nuevamente, etc, hasta el resto de la eternidad :P
¿Se comprendió?
Ahora, si agregaras al menos una linea "NOP"(o más) inmediatamente despues de la linea: GOTO 0X04 tu código funcionaría de maravillas! aún sin tener que cambiar el "GOTO" por el "ORG". Te dejo que lo analices y confirmes por tu cuenta.
Salut!
-
De nada Enigma.
Me alegro que te haya servido para tu programa y espero que con eso y con las aportaciones de Bruno seas capaz de entender por que no te funcionaba.
Saludos Fermin
-
Jajajaja!!! miercole!!!! nahuara no me habia dado cuenta de eso!!!! jajajaja Por Dios, así estaria de cansada que no me di cuenta de esa miercole!!! jajajaja Chamos disculpen mi horror, pero de pana que no me percate de ese goto!!!! ay que pena!!!! :g) jajajajaja
Atte: Enigma... La llanerita de Guayana :P
-
Hola muchachos, disculpen el fastidio.... pero tengo dos pregunticas!!!
La primera es:
Hay alguna forma de visualizar el desbordamiento del timer en Mplab???
Y la segunda....
Quiero hacer que despues que el timer termine de temporizar, me pase a otra subrutina, en este caso llamada piso, es valido activar una bandera en la interrupción y que despues pregunte por ella en la subrutina del timer para ver si esta activada???. La bandera es pis
Observen esto....
;-------RUTINA PARA QUE LA TEMPORIZACION ME DURE 3 SEGUNDOS----------------
TIM3
BSF STATUS,RP0 ; ME CAMBIO AL BANCO 1
MOVLW b'00000111' ;
MOVWF OPTION_REG ; PRESCALER DE 256 PARA EL TMR0
BCF STATUS,RP0 ; ACCESO AL BANCO 0
MOVLW 0X00 ; CARGA EL TMR0.
MOVWF TMR0 ; CON 255
MOVLW 0X60 ; PARA QUE ME DURE 3 SEG
MOVWF REGISTRO50MS ; LO MUEVO A LA VARIABLE DEL TIMER
BSF PORTC,0 ; ENCIENDO EL MOTOR
MOVLW b'10100000' ; MUEVO A0 A W
MOVWF INTCON ; ACTIVA LA INTERRUPCION DEL TMR0 (TOIE) Y LA GENERAL.
NADA3 ; NO SE PUEDE UTILIZAR EL MODO BAJO CONSUMO PORQUE EL
GOTO $ ; TIMER SE DETIENE
BTFSS PIS,0 ; PREGUNTA SI EL TIMER TERMINO DE CONTAR
GOTO NADA3 ; NO
GOTO PISO ; SI
;------------------------------INTERRUPCION-----------------------------------
INTERUMP
MOVLW 0X00 ; MUEVO 255
MOVWF TMR0 ; ESO LO MUEVO AL TIMER0
DECFSZ REGISTRO50MS,F ; DECREMENTA EL CONTADOR
GOTO FININTERRUPCION ; ME DEVUELVO
BCF PORTC,0 ; ESTABA ENCENDIDO Y LO APAGA
FININTERRUPCION
BCF INTCON,T0IF ; REPONE EL FLAG DEL TMR0.
BSF PIS,0 ; ACTIVA LA BANDERA PARA SABER QUE TERMINO
RETFIE
Lo que quisiera saber es que si de esta manera despues que el timer0 termine de contar me va a pasar a la subrutina piso... Disculpen de pana, pero es que posee pocos conocimientos acerca del timer0, y bueno la información que he conseguido me explica lo mismo siempre!!!!! :?.... Por fa si pueden ayudarme!!1 gracias!!!! :-/
Atte: Enigma... La llanerita de Guayana :P
-
Hay alguna forma de visualizar el desbordamiento del timer en Mplab???
Solo por el flag que se enciende o por el registro que se hace 0.
Quiero hacer que despues que el timer termine de temporizar, me pase a otra subrutina, en este caso llamada piso, es valido activar una bandera en la interrupción y que despues pregunte por ella en la subrutina del timer para ver si esta activada???. La bandera es pis
Es perfectamente válido y de hecho se suele hacer así. Son flags de tu aplicación con la cual tu puedes saber qué haces y que no has hecho.
Saludos
-
offtopic:
nahuara no me habia dado cuenta de eso!!!!
...
es naguará (http://www.ucla.edu.ve/lara/curiosid.htm) para que vean que esta expresión no solo se usa en Barquisimeto, sino en varias partes del país :)
-
jejeje bueno la palabra Naguara, me la copie de un guaro que andaba de visita aquí en puerto ordaz es primo de u amigo y bueno las veces que estabamos con el decia a cada rato esa expresión... y como yo soy una esponja para todo se me pego y hasra el sol de hoy y desde hace como 5 años aún la conservo!!!! jejejejeje
Gracias por la corrección..!!!! :D
Atte: Enigma... La llanerita de Guayana :P