Este es el programa en ensamblador (me disculparan lo desorganizado del código, pero soy nuevo en esto de publicarlo, y espero mejorarlo para el próximo):
;-------------------------------------------------------------------------
;PROGRAMA QUINTO JOSE NOE
;01 de julio de 2012 continuando el 22 de julio
;programa que cuenta de 0 a 15, incrementa cuando se presiona RA0, y decrementa cuando se presiona RA1 (entrada alta)
;se visualiza el conteo en el puerto B.
;----------------------------------------------------------------------------
LIST P= 16F84A ; comando que indica el pic usado
INCLUDE
;-----------------------------------------------------------------------------
; Configuracion para el GRABADOR
_HS_OSC equ 0x3FFE
_WDT_OFF equ 0x3FFB
_PWRTE_ON equ 0x3FF7
_CP_OFF equ 0x3FFF
__config _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;_CP_ON / _OFF Proteccion del Codigo
;_PWRTE_ON / _OFF Reset mediante Power-Up Timer
;_WDT_ON / _OFF WatchDog
;_LP_OSC Oscilador de bajo Consumo (35Khz a 200Khz)
;_XT_OSC Oscilador de Cristal (100khz a 4Mhz)
;_HS_OSC Oscilador de Alta velocidad (4Mhz a 20Mhz)
;_RC_OSC Oscilador Resistencia-Capacitor ()
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Declaracion de Constantes, Variables y Base
RADIX HEX ;Base Hexadecimal
#DEFINE BANK_0 BCF STATUS,RP0 ;Ir al banco 0
#DEFINE BANK_1 BSF STATUS,RP0 ;Ir al Banco 1
;------------------------------------------------------------------------------
;---------------------- DEFINO MIS VARIABLES O REGISTROS
CBLOCK 0X0C ;MAPA DE MEMORIA DEL PIC16F84, con esto puedo definir ;varias variables
;sin necesidad de determinar la ubicación de la memoría
;esta ubicación está dada por 0x0c
Contador
ENDC ;termino de asignar variables
;------------------------------------------------------------------------------
; Vectores de Interrupcion
ORG 0 ; el programa comienza en la dirección 0
;(vector de reset)
goto programa ; se salta a la etiqueta "programa"
ORG 5 ; se asigna la dirección 5 a la siguiente instrucción que contiene la
; etiqueta inicio ¿para qué? para evitar invalidar la pila
;en caso de alguna interrupción, ya que esta salta a la posición 4
;---------------------------------------------------------------------------------------------
;------------------------- PROGRAMA ------------------------------------------------
programa
BANK_1 ;Ir al banco 1
CLRF TRISB ;TRISB = 0 Salidas o puerto B como salidas, se aprovecha la ;instrucción include para
;no tener que escribir tanto
movlw 0xff ;pone en W 0xff, que equivale en binario a 11111111
;este código es para poner el puerto A como entrada
MOVWF TRISA ;TRISA = 0xFF Entradas
BANK_0 ;Ir al banco 0
;----------------------------------------------------------------------------------------------
BORRARCONTADOR ; borrar contador
CLRF Contador ;borramos el contador, lo ponemos en cero
;----------------------------------------------------------------------------------------------
INICIO
MOVF Contador,W ;W = Contador, ponemos en W el valor del contador
MOVWF PORTB ;PORTB = W, escribimos en el puerto B, el valor del contador
; ------------ compara primero el PULSADOR1 que aumenta la cuenta
BTFSS PORTA,0 ;PORTA,RA0 = 1, si es un UNO salta una instrucción, sino es ;porque se presiono
goto PULSADOR2
CALL INCREMENTO ;si se presiono llama a la subrutina INCREMENTO allí ;también se hace el antirebote
goto INICIO
PULSADOR2 ; ------------ PULSADOR2 disminuye la cuenta
BTFSS PORTA,1 ;si es 1 salta una instrucción, sino sigue leyendo
GOTO INICIO ;si es un cero vuelve a INICIO para seguir leyendo
CALL DECREMENTO ;si es un uno va a la subrutina DECREMENTO, allí está el antirrebote
goto INICIO
;----------------------------------------------------------------------------------------------
INCREMENTO
BTFSC PORTA,0 ;PORTA,RA0 = 0, es porque se dejo de presionar, si
;sigue el "1" es porque no se ha dejado de presionar
;entonces debe quedarse hay hasta que se deje de presionar
goto INCREMENTO
INCF Contador ;incrementa el contador, es decir, contador++
MOVLW 0x10 ;cargo a W = 16, para comparar el valor del contador con este
SUBWF Contador,W ;W = Contador - 16, realizo esta resta
BTFSS STATUS,Z ;Contador = 16, ¿qué hace aquí? Z se pone en 1 si el resultado ha ;sido 0
;o se pone a 0, si el resultado no ha sido cero, en este caso
;si el resultado es cero, es porque el contador es 16, o sea que hay que
;reiniciarlo.
GOTO FIN_INCREMENTO ;hace esto si el contador no es 16, sino va a
CLRF Contador ;borramos el contador, lo ponemos en cero
FIN_INCREMENTO
RETURN
;------------------------------------------------------------------------------------------------------
DECREMENTO
BTFSC PORTA,1 ;PORTA,RA1 = 0, es porque se dejo de presionar, si
;sigue el "1" es porque no se ha dejado de presionar
;entonces debe quedarse hay hasta que se deje de presionar
goto DECREMENTO
DECF Contador,F ;Contador--
MOVLW 0xFF ;W = 0xFF,es 255 o en binario 11111111
SUBWF Contador,W ;Contador - 0xFF, realizo esta resta como en el incremento
BTFSS STATUS,Z ;Contador = 0xFF
GOTO FIN_DECREMENTO ;NO ir a INICIO
MOVLW 0x0F ;W = 0x0F, si es igual que 255 es porque paso la cuenta, por eso debe cargarse con 15
MOVWF Contador ;Contador = W
FIN_DECREMENTO
RETURN
;------------------------------------------------
END ;directiva que indica el fin del programa