;
;					EJEMPLO 3.15
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para MicroPIC Trainer y Trainer PLUS. Interface I2C gestionado por software.
;
;Haciendo uso de las rutinas incluidas en el fichero I2CLOW.INC, se trata de controlar
;el funcionamiento de los distintos dispositivos I2C, existentes en la tarjeta 
;Trainer PLUS. Estos dispositivos están conectados entre sí al bus I2C común. Se recomienda
;leer las especificaciones técnicas de los mismos, para tener un mayor conocimiento de las
;posibilidades de los mismos. Igualmente es importante desconectar los leds de la uPIC Trainer
;mediante el jumper J7 pues de lo contrario actuarían como carga adicional en las líneas RB6
;y RB7 que, en estos ejemplos, forman el bus I2C.
;
;El dispositivo I2C SAA1064. Controlador de displays 7 segmentos
;
;Se trata de un contador UP/DOWN de 4 dígitos cuya visualización se realiza en los 4 displays
;de la uPIC Trainer PLUS, gobernados por el dispositivo I2C SAA1064.
;
;Los pulsos a contar se introducen por RA0. Si RA1 = 0 la cuenta es ascendente, en caso
;contrario descendente.

		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos

CLKIN		equ	.4000000	;Frecuencia de trabajo
                 
I2c_var		equ	0x0c		;Inicio de las variables para rutinas I2C_LOW
Key_var		equ	0x12		;Inicio de las variables de manejo del teclado
Digito_1	equ	0x18
Digito_2	equ	0x19
Digito_3	equ	0x1a		
Digito_4	equ	0x1b		;Buffer de salida al SAA1064 de los 4 dígitos		
Conta_1		equ	0x1c
Conta_2		equ	0x1d
Conta_3		equ	0x1e
Conta_4		equ	0x1f		;Variables del contador

		org	0x00		;Vector de reset
		goto	Inicio
		org	0x05		;Salvar el vector de interrupción	

		include	"I2CLOW.INC"	;Incluye las rutinas de manejo del bus I2C
		include "teclado.INC"	;Incluye rutinas de manejo del teclado

;**************************************************************************************
;VISUALIZA: Esta rutina recoge el valor de las cuatro variables "Dígito" y las transmi-
;te por el bus I2C para su visualización sobre los displays de uPIC Trainer Plus.

VISUALIZA:	call	Inicia_Bus	;Inicia líneas del bus I2C
		call	Txt_Start_Bit	;Envía condición de inicio
		movlw	b'01110110'
		movwf	DataByte
		call	Txt_Byte	;Transmite dirección del dispositivo (escritura)
		clrf	DataByte
		call	Txt_Byte	;Transmite byte de instrucción
		movlw	b'01000111'
		movwf	DataByte	
		call	Txt_Byte	;Transmite byte de control
		movf	Digito_1,W
		movwf	DataByte
		call	Txt_Byte	;Transmite Dígito 1
		movf	Digito_2,W
		movwf	DataByte
		call	Txt_Byte	;Transmite Dígito 2
		movf	Digito_3,W
		movwf	DataByte
		call	Txt_Byte	;Transmite Dígito 3
		movf	Digito_4,W
		movwf	DataByte
		call	Txt_Byte	;Transmite Dígito 4
		call	Txt_Stop_Bit	;Transmite secuencia de STOP
		return

;*********************************************************************************
;Delay_20_ms: Esta rutina de temporización tiene por objeto eliminar el "efecto
;rebote" de los periféricos electromecánicos. Realiza un delay de 20 mS. Si el PIC
;trabaja a una frecuencia de 4MHz, el TMR0 evoluciona cada uS. Si queremos tempori-
;zar 20000 uS (20 mS) con un preescaler de 128, el TMR0 deberá contar 156 eventos
;(156 * 128). El valor 156 equivale a 9c hex. y como el TMR0 es ascedente habrá que
;cargar su complemento a 1 (63 hex.).

Delay_20_ms:	bcf	INTCON,T0IF	;Desconecta el flag de rebasamiento
		movlw	0x63		;Complemento hex. de 156
		movwf	TMR0		;carga el TMR0
Delay_20_ms_1	clrwdt			;Refrescar el WDT
		btfss	INTCON,T0IF	;Rebasamiento del TMR0 ??
		goto	Delay_20_ms_1	;Todavía no
		bcf	INTCON,T0IF	;Ahora si, reponer el flag
		return

;***********************************************************************************
;Esta rutina produce incrementos en decimal sobre las 4 posiciones del contador

Incremento	incf	Conta_4,F
		movlw	.10
		subwf	Conta_4,W
		btfss	STATUS,Z	;Dígito 4 mayor de 9 ??
		goto	Inc_Fin		;No
		clrf	Conta_4		;Si, puesta a 0
		incf	Conta_3,F
		movlw	.10
		subwf	Conta_3,W
		btfss	STATUS,Z	;Dígito 3 mayor de 9 ??
		goto	Inc_Fin		;No
		clrf	Conta_3		;Si, puesta a 0
		incf	Conta_2,F
		movlw	.10
		subwf	Conta_2,W
		btfss	STATUS,Z	;Dígito 2 mayor de 9 ??
		goto	Inc_Fin		;No
		clrf	Conta_2		;Si, puesta a 0
		incf	Conta_1,F
		movlw	.10
		subwf	Conta_1,W
		btfsc	STATUS,Z	;Dígito 1 mayor de 9 ??
		clrf	Conta_1		;Si, puesta a 0
Inc_Fin		return

;***********************************************************************************
;Esta rutina produce decrementos en decimal sobre las 4 posiciones del contador

Decremento	decf	Conta_4,F
		movlw	0xff
		subwf	Conta_4,W
		btfss	STATUS,Z	;Dígito 4 menor de 0 ??
		goto	Dec_Fin		;No
		movlw	.9
		movwf	Conta_4		;Si, puesta a 9
		decf	Conta_3,F
		movlw	0xff
		subwf	Conta_3,W
		btfss	STATUS,Z	;Dígito 3 menor de 0 ??
		goto	Inc_Fin		;No
		movlw	.9
		movwf	Conta_3		;Si, puesta a 9
		decf	Conta_2,F
		movlw	0xff
		subwf	Conta_2,W
		btfss	STATUS,Z	;Dígito 2 menor de 0 ??
		goto	Inc_Fin		;No
		movlw	.9
		movwf	Conta_2		;Si, puesta a 9
		decf	Conta_1,F
		movlw	0xff
		subwf	Conta_1,W
		btfss	STATUS,Z	;Dígito 1 menor de 0 ??
		goto	Dec_Fin		;No
		movlw	.9
		movwf	Conta_1		;Si, puesta a 9
Dec_Fin		return

Inicio:		clrf	PORTA
		clrf	PORTB
		bsf	STATUS,RP0	;Selecciona página 1 de datos
		movlw	b'00000011'
		movwf	TRISA		;RA0 y RA1 entradas
		clrf	TRISB		;Puerta A y B salidas
		movlw	b'10000110'	;Preescaler de 128 para el TMR0. Pull_Up Off
		movwf	OPTION_REG				
		bcf	STATUS,RP0	;Selecciona página 0 de datos	

		call	Inicia_Bus	;Inicia el bus I2C
		
		clrf	Conta_1
		clrf	Conta_2
		clrf	Conta_3
		clrf	Conta_4		;Borra contadores

		movlw	b'00111111'
		movwf	Digito_1
		movwf	Digito_2
		movwf	Digito_3
		movwf	Digito_4
		call	VISUALIZA	;Visualiza 0000 en los displays

Loop		clrwdt
		btfss	PORTA,0		;Flanco ascendente en RA0 ??
		goto	Loop		;No
		call	Delay_20_ms	;Si, elimina rebotes

Loop_1		clrwdt
		btfsc	PORTA,0		;Flanco descendente en RA0 ??
		goto	Loop_1		;No
		
		btfsc	PORTA,1		;Si, ha habido pulso. RA1=0 ??
		goto	Dec_Conta	;No, decrementar el contador

Inc_Conta	call	Incremento	;Si, incrementar conador
		goto	Visualizar

Dec_Conta	call	Decremento	;Decrementar

Visualizar	movf	Conta_4,W
		call	BCD_7seg	;Convierte a 7 segmentos el dígito 4
		movwf	Digito_4	;Almacena en el buffer de visualización
		movf	Conta_3,W
		call	BCD_7seg	;Convierte a 7 segmentos el dígito 3
		movwf	Digito_3	;Almacena en el buffer de visualización
		movf	Conta_2,W
		call	BCD_7seg	;Convierte a 7 segmentos el dígito 2
		movwf	Digito_2	;Almacena en el buffer de visualización
		movf	Conta_1,W
		call	BCD_7seg	;Convierte a 7 segmentos el dígito 1
		movwf	Digito_1	;Almacena en el buffer de visualización
		call	VISUALIZA	;Visualiza el buffer sobre los 4 displays

		goto	Loop
		
		end			;Fin del programa fuente

