;
;					EJEMPLO 3.21
;
;				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 PCF8591. Convertidor DAC y ADC
;
;El programa lee el resultado de la conversión ADC de la tensión análogica presente en el
;canal 0 del convertidor PCF8591. El resultado binario será convertido a BCD y visualizado
;sobre los 4 displays controlados por el dispositivo SAA1064. El rango visualizado estará
;comprendido entre 0000 y 0255.
;
;Se recomienda conectar un potenciómetro en la borna AN0 de la uPIC'Trainer PLUS para 
;introducir una tensión analógica variable entre 0V y la tensión de referencia que se esté
;empleando.

		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
A_inp		equ	0x1c		;Resultado de la conversión AD de entrada
Buffer_H	equ	0x1d
Buffer_L	equ	0x1e		;Resultado de la conversión a BCD

		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

;****************************************************************************************
;A_Input: Esta rutina lee el valor binario procedente del canal 0 del ADC contenido en el
;dispositivo I2C PCF8591.

A_Input		call	Txt_Start_Bit	;Transmite secuencia de inicio
		movlw	b'10010001'
		movwf	DataByte
		call	Txt_Byte	;Dirección del PCF8591 (modo lectura)
		bsf	_Ultimo_Byte	;Recibe un único byte cada vez
		call	RcvByte		;Recibe resultado de conversión AD
		call	Txt_Stop_Bit    ;Transmite secuencia de STOP
		movf	DataByte,W
		movwf	A_inp		;Salva valor resultante de la conversión
		return

;**************************************************************************************
;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

;**************************************************************************************
;BIN_BCD: Convierte el valor binario presente en el acumulador (W) en BCD. El resul-
;tado se deposita en las variables Buffer_H y Buffer_L.

BIN_BCD         clrf 	Buffer_L        ;Limpiar regs.de trabajo.
                clrf 	Buffer_H            
                                     
BIN_BCD_1       addlw 	0xf6          	;Resta 10 por suma de complemento a 2.
                btfss 	STATUS,C       	;Hay Carry?
                goto 	BIN_BCD_3       ;NO.
                movwf 	A_inp         	;SI.Guardar en reg.Temporal.
                incf 	Buffer_L,F      ;Incrementar byte bajo guardarlo y enviar...
                movf 	Buffer_L,W      ;..copia al ==> W...
                xorlw 	b'00001010'    	;..0Ah xor W(BCDL). 
                btfss 	STATUS,Z       	;Es "0" el resultado de la operación?
                goto 	BIN_BCD_2       ;NO.
                clrf 	Buffer_L        ;SI.Limpiar el byte bajo e...
                incf 	Buffer_H,F	;incrementar el alto.
BIN_BCD_2       movf 	A_inp,W		;Recuperar el dato.
                goto 	BIN_BCD_1       ;Continuar la operación.

BIN_BCD_3       addlw 	H'0A'          	;TEMPO + 0Ah
                swapf 	Buffer_L,F     	;<3:0> <==> <7:4> y ==> BCDL
                iorwf 	Buffer_L,F     	;W or BCDL ==> BCDL
                return

;*************************************************************************************
;Un_Pack: Esta rutina recoge los dos bytes almacenados en Buffer_L y Buffer_H los 
;desempaqueta en 4 dígitos BCD que son convertidos a código 7 segmentos para, posteriormente
;Visualizarlos sobre los displays

Un_Pack		swapf	Buffer_H,W
		call	BCD_7seg
		movwf	Digito_1	;Convierte nibble de más peso de Buffer_H
		movf	Buffer_H,W
		call	BCD_7seg
		movwf	Digito_2	;Convierte nibble de menos peso de Buffer_H
		swapf	Buffer_L,W
		call	BCD_7seg
		movwf	Digito_3	;Convierte nibble de más peso de Buffer_L
		movf	Buffer_L,W
		call	BCD_7seg
		movwf	Digito_4	;Convierte nibble de menos peso de Buffer_L
		return

Inicio:		clrf	PORTA
		clrf	PORTB
		bsf	STATUS,RP0	;Selecciona página 1 de datos
		movlw	b'00011111'
		movwf	TRISA		;RA0-RA4 entradas
		clrf	TRISB		;Puerta 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
				
Loop:		clrwdt			;Refresca el WDT
		call	A_Input		;Obtiene el valor de la conversión ADC
		movf	A_inp,W
		call	BIN_BCD		;Lo convierte a BCD
		call	Un_Pack		;Desempaqueta y convierte a 7 segmentos
		call	VISUALIZA	;Visualiza sobre los 4 displays del SAA1064

		goto	Loop

		end			;Fin del programa fuente

