TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: dekike en 18 de Mayo de 2006, 23:46:04
-
Hola amigos, soy nuevo en este foro. Me ha llamado la atencion la actividad que se mantiene aqui.
Bueno voy al grano: Estoy tratando de hacer trabajar al pic16f877a como contador de eventos a través de la interrupcion por el pin RB0. Lo he configurado para activarse por flanco negativo. Se debe mostrar un numero de cuatro digitos en displays . Creo que el codigo esta bien, pero no funciona bien. Les agradedezco que me revicen el codigo y me echen una manito.
Gracias...
;PROGRAMA DISPLAYS_F877A
;Interrrupcion del microcontrolador pic16f877a a traves de pin rb0.
;
;----------------------------------------------------------------------
LIST P=16F877A
#INCLUDE "P16F877A.INC"
__CONFIG _XT_OSC
CBLOCK 0X20
COUNTER_1 ;Contador para unidades
COUNTER_10 ;Contador para decenas
COUNTER_100 ;Contador para centenas
COUNTER_1000 ;Contador para miles
STORE_w ;Reg para guardar temporalmente el contenido de W
STORE_st ;Reg para guardar temporalmente STATUS despues del swapf
PDel0
PDel1
RETAR1
RETAR2
RETAR3
ENDC
#DEFINE BANK_1 BSF STATUS,RP0 ;Bit 5
#DEFINE BANK_0 BCF STATUS,RP0
RESET_VECTOR
ORG 00h
GOTO START
ORG 04h
GOTO ISR ;Interrupcion Service Routine
START
BANK_1
CLRF TRISA ;Control de transistores
CLRF TRISD ;Salida para displays
MOVLW 11110001h
MOVWF TRISB
BCF OPTION_REG,INTEDG ;Interrupcion con flanco descendente en rb0
BANK_0
BCF INTCON,INTF ;Bandera INTF a cero.
BSF INTCON,GIE ;Interrupciones globales
BSF INTCON,INTE ;Habilita interrupcion por rb0
;Inicializacion de contadores y registros
CLRF COUNTER_1
CLRF COUNTER_10
CLRF COUNTER_100
CLRF COUNTER_1000
;;Inicializacion de puertos
CLRF PORTA
CLRF PORTB
CLRF PORTD
;------------------------------------------------------------------------------
;=========== PRINCIPAL =======
MAIN
; BCF INTCON,INTF ;Bandera INTF a cero.
BSF INTCON,GIE ;Interrupciones globales
; BSF INTCON,INTE ;Habilita interrupcion por rb0
BSF PORTA,0 ;Active transistor 1
MOVF COUNTER_1,W
CALL TABLE
MOVWF PORTD
CALL DELAY1
BCF PORTB,0 ;Desactive transistor 1
GOTO MAIN ;===========
;-----------------------------------------------------------------------------
;===========RUTINA INTERRUPCION
ISR
;Comienzo de la rutina IRS----
SAVE_REGS
MOVWF STORE_w ;Guarda contenido de W
SWAPF STATUS,W ;Swap el contenido de STATUS en W
MOVWF STORE_st ;Guarda el contenido de STATUS (swapped)
;Tratamiento----------------
BTFSS INTCON,INTF ;Verfifica estado de la bandera
GOTO EXIT_IRS ;Sino, salir
MOVLW .9 ;Para saber si counter_1 es igual a menor que 9
SUBWF COUNTER_1,0 ;( resta f-W )el resultado se almacena en W
BTFSC STATUS,Z ;verfificar la bandera Z (zero): Z=1 solo cuando el resultado es cero.
GOTO INC_10
INC_1
INCF COUNTER_1
GOTO WATCH ;salir
INC_10
CLRF COUNTER_1
MOVLW .9 ;Para saber si counter_1 es igual a menor que 9
SUBWF COUNTER_10,0 ;( resta f-W )el resultado se almacena en W
BTFSC STATUS,Z ;verfificar la bandera Z (zero): Z=1 solo cuando el resultado es cero.
GOTO INC_100
INCF COUNTER_10
GOTO WATCH
INC_100
CLRF COUNTER_10
MOVLW .9 ;Para saber si counter_1 es igual a menor que 9
SUBWF COUNTER_100,0 ;( resta f-W )el resultado se almacena en W
BTFSC STATUS,Z ;verfificar la bandera Z (zero): Z=1 solo cuando el resultado es cero.
GOTO INC_1000
INCF COUNTER_100
GOTO WATCH
INC_1000
CLRF COUNTER_100
MOVLW .9 ;Para saber si counter_1 es igual a menor que 9
SUBWF COUNTER_1000,0 ;( resta f-W )el resultado se almacena en W
BTFSC STATUS,Z ;verfificar la bandera Z (zero): Z=1 solo cuando el resultado es cero.
GOTO ALARM
INCF COUNTER_1000
GOTO WATCH
ALARM
BSF PORTA,4 ;Avisar que llego a 10.000 unidades
GOTO WATCH
WATCH BTFSS PORTB,0 ;Verificar el estado del pulsador.
GOTO WATCH
BCF INTCON,INTF
BSF INTCON,INTE
;Fin de la rutina IRS---------
EXIT_IRS
SWAPF STORE_st,W ;Deja STATUS como estaba
MOVWF STATUS ;y lo restaura
SWAPF STORE_w,1 ;Restaura el contenido de W
SWAPF STORE_w,0 ;STORE_w,0
RETFIE ;========= SALIR DE INTERRUPCION
;------------------------------------------------------------------------------
TABLE
ADDWF PCL
RETLW 3Fh ;Código para el cero
RETLW 06h ;Código para el uno
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh ;;Código para el nueve
DELAY1
MOVLW .3
MOVWF RETAR1
NEXT DECFSZ RETAR1,1
GOTO NEXT
RETURN
PAUSE
MOVLW D'2' ;PAUSA
MOVWF RETAR1
P1 MOVLW D'10'
MOVWF RETAR2
P2 MOVLW D'5'
MOVWF RETAR3
P3 DECFSZ RETAR3,F
GOTO P3
DECFSZ RETAR2,F
GOTO P2
DECFSZ RETAR1,F
GOTO P1
RETURN
;------------------------------------------------------------------------------
END
-
Hola dekike, tratare de exponer algunos de los detalles que encontre a simple vista:
1)TABLE
ADDWF PCL,F ;te falta declarar donde guarda el resultado.
2) BSF PORTA,0 ;Active transistor 1
MOVF COUNTER_1,W
CALL TABLE
MOVWF PORTD
CALL DELAY1
BCF PORTB,0 ;Desactive transistor 1
Primero normalmente se pone el dato en el PORTD y despues se altiva el transistor, de la manera que se encuentra el multiplexado no sale bien representado.
3) BTFSS INTCON,INTF ;Verfifica estado de la bandera
GOTO EXIT_IRS ;Sino, salir
En este caso si entro a la interrupcion es solo posible por la interrupcion de RB0, por lo tanto estas lineas estan de sobra
4)WATCH
BTFSS PORTB,0 ;Verificar el estado del pulsador.
GOTO WATCH
BCF INTCON,INTF
BSF INTCON,INTE
Para evitar que una misma pulsada te cuente dos veces con esperar que el boton deje de esta presionado no alcanza, el motivo es los rebotes que un pulsador tiene, a ti te parece que lo apretas solo una ves, pero el pulsador envia 3, 4, etc. pulsos que son generador por los rebotes del mismo, para que no te cuente un rebote lo que debes hacer es agregarle una rutina de demora de por lo menos 50ms para deje pasar los rebotes y luego revisas si an dejado de apretar el pulsador, si la demora, al ser la rutina de interrupcion mucho más rapida que el rebote en una pulsada puede contarte más de una.
Activas nuevamente la interrupcion INTE, como esta ya estaba activa no hace falta que repitas el proceso.
Bueno, esa son las que encontré de solo mirarlo, si con las reformas no funciona y lo deseas lo pruebo más a fondo.
Un saludo.
Atte. CARLOS.
-
Gracias Carlos, por tu aporte. Tan pronto tenga un tiempito lo reformare.
Saludos.
Dekike