El programa:
'***************** Placa Entrenadora (PIC EBadic) ***************************************
'NOMBRE: 16F88_Pic_EBasic_EJEMPLO_33
'Descripcion: TEST DE LA PLACA EBasic_I2C (Led y DS1624), Temperatura positiva y negativa)
'Micro: PIC16F88 / 8mhz reloj interno
'Fecha/Autor: 23/01/09, 15/01/09, 2/08/07, 29/7/07 By COS, PSI v7.41
'Version: 1.3
'Se añaden temperaturas negativas
'Se crea la función lcdsig_ds1624, que permite seleccionar 0,1 o 2 decimales
'Version: 1.2
'Se eliminan elementos redundantes en la funcion
'Version: 1.1
'Se añade TEST para el DS1624 (temperatura)
'*****************************************************************************************
Define CONF_WORD = 0x2f50 'Configuración de bits (fuses)
Define CONF_WORD_2 = 0x3ffc 'Configuración de bits (fuses)
Define CLOCK_FREQUENCY = 8 'Frecuencia del reloj en Mhz
'Define SIMULATION_WAITMS_VALUE = 1 'Hace que se ignoren los tiempos de los WaitMs
'-------------------------------------Puertos del LCD-------------------------------------
Define LCD_BITS = 4 'Indicamos que el bus de datos del lcd sera de 4bit
Define LCD_DREG = PORTA 'Bus de datos sera el puerto A
Define LCD_DBIT = 0 'Bus de datos seran los 4 bit menos significativos del puerto A
Define LCD_RSREG = PORTB 'Bit de control RS sera del puerto B
Define LCD_RSBIT = 7 'RB7 como RS
Define LCD_EREG = PORTB 'Bit de control E sera del puerto B
Define LCD_EBIT = 6 'RB6 como E
Define LCD_COMMANDUS = 2000 'Tiempo de espera despues de ejecutar un comando del lcd en uSeg.
Define LCD_DATAUS = 50 'Tiempo de espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 50 'Tiempo de espera despues de inicializar el Display.
'Definicion de puertos--------------------------------
AllDigital 'los pin I/O digitales
'ANSEL = %00010000 'los pin I/O digitales y RA4 analogico
CMCON = 0x07 'comparador a off
OSCCON = 0x7e 'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0x00 'Puerto A como salidas
TRISB = 0x00 'puerto B como salidas
'TRISA.4 = 1 'como entrada (RA4, adc)
TRISA.6 = 1 'como entrada (RA6, tecla S1)
TRISA.5 = 1 'como entrada (RA5, tecla S2)
'Declaracion de constantes-----------------------------
Const p_off = 0 'apaga el led
Const p_on = 1 'enciende el led
Const p_nc = 2 'no cambia estado el led
'Reasignacion de nombres------------------------------
Symbol sda = RB1 'asignamos nombre al pin que hara de SDA del puerto I2C
Symbol scl = RB4 'asignamos nombre al pin que hara de SCL del puerto I2C
Symbol led_amarillo = RA7 'led amarillo
Symbol led_verde = RB0 'led verde
Symbol luz_lcd = RB3 'iluminación del lcd
Symbol s1 = RA6 'tecla S1
Symbol s2 = RA5 'tecla S2
'Variables generales---------------------------------------
Dim temperatura As Word 'temperatura entero .HB, decimales .LB
'Inicio------------------------------------------------
Lcdinit 'inicializa el LCD sin cursor
WaitMs 100 'pausa de 100 mSeg.
Lcdout "Test P. EB_I2C" 'Imprime el texto en el LCD
WaitMs 3000 'pausa de 3Seg.
Call led(p_off, p_off, p_on, p_off) 'led a off
'Rutina Programa---------------------------------------
main:
Call led(p_nc, p_nc, p_nc, p_on) 'Control luces
temperatura = d_ds1624(0) 'genera una lectura en el chip ds
Call led(p_nc, p_nc, p_nc, p_off) 'Control luces
WaitMs 1000 'pausa de 1Seg, tiempo maximo de conversion del chip ds
Call led(p_nc, p_nc, p_nc, p_on) 'Control luces
temperatura = d_ds1624(1) 'almacena la lectura en dos bytes
Call led(p_nc, p_nc, p_nc, p_off) 'Control luces
Lcdcmdout LcdLine2Home 'cursor al principio de la linea 2
Lcdout "Temp. " 'Imprime en el LCD
Call lcdsig_ds1624(temperatura, 1, 1) 'Llama a imprimir temperatura con formato
WaitMs 1000 'hace una pausa de 1Seg.
Goto main
End
'Rutinas-----------------------------------------------
'Detecta signo e imprime con 0, 1 o 2 decimales
'Parte entera con formato de 3 digitos
'arg1 = Valor de entrada de temperatura
'arg2 = 0 no hay decimales, arg2 = 1 un decimal, arg2 = 2 con dos decimales
'arg3 = 0 no imprime "C" despues de los decimales, arg3 = 1 si la imprime
Proc lcdsig_ds1624(arg1 As Word, arg2 As Byte, arg3 As Bit) 'Declara el tipo y argumentos de la funcion
If arg1.15 = 0 Then 'Selecciona +/-
If arg1 > 0 Then Lcdout "+" 'Imprime en el lcd
If arg1 = 0 Then Lcdout " " 'Imprime en el lcd
Else
arg1.15 = 0 'Deja la parte entera
If arg1 > 0 Then Lcdout "-" 'Imprime en el lcd
If arg1 = 0 Then Lcdout " " 'Imprime en el lcd
Endif
If arg1.HB < 100 Then Lcdout "0"
If arg1.HB < 10 Then Lcdout "0"
Lcdout #arg1.HB 'Escribe parte entera
If arg2 = 1 Or arg2 = 2 Then Lcdout "." 'Escribe lcd
If arg2 = 1 Then arg1.LB = arg1.LB / 10 'Suprime el segundo decimal
If arg2 = 2 And arg1.LB < 10 Then Lcdout "0" 'Mantiene el formato dos decimales
If arg2 = 1 Or arg2 = 2 Then Lcdout #arg1.LB 'Escribe los decimales
If arg3 = 1 Then Lcdout "C" 'Imprime en el lcd
End Proc
'Funcion de lectura/escritura del DS1624
'ds_rw=0 el chip prepara un lectura
'ds_rw=1 el chip entrega una lectura
'ds_rw=2 se hace una lectura del registro de control.
'd_ds1624, byte mas significativo parte entera, menos significativo 2 decimales
'Hay que recordar declarar SDA y SCL
Function d_ds1624(ds_rw As Byte) As Word ', d_aux As Long) As Word
Dim d_aux As Long
RA4 = 1 'Led placa I2c a On
If ds_rw = 0 Then 'Solicita una lectura de temperatura
I2CWrite sda, scl, %10010010, 0xac, 0x00 'Inicializa el registro de control
WaitMs 10 'Pausa para que termine la escritura
I2CWrite1 sda, scl, %10010010, 0xee 'Comienza una conversión
Endif
If ds_rw = 1 Then 'Hace la lectura de la temperatura
I2CWrite1 sda, scl, %10010010, 0xaa 'Prepara el chip para lectura de temperatura
I2CRead1 sda, scl, %10010011, d_ds1624.HB, d_ds1624.LB 'Lee la temperatura
If d_ds1624.15 = 1 Then 'Detecta signo de la temperatura
d_ds1624 = Not d_ds1624 'Pasa a complemento a 1
d_ds1624 = d_ds1624 + 1 'Pasa a complemento a 2
d_ds1624.15 = 1 'Activa bit de signo negativo que se pierde en la operación
Endif
d_ds1624.LB = ShiftRight(d_ds1624.LB, 3) 'Elimina bit que no se usan
d_aux = (d_ds1624.LB * 625) / 1000 'Calcula la parte decimal, 2 digitos
'd_aux = (d_ds1624.LB * 9) / 15 'Calcula la parte decimal, 2 digitos, operación simplificada
d_ds1624.LB = d_aux.LB 'Pasa los decimales a la variable de transferencia
Endif
If ds_rw = 2 Then 'Hace una lectura del registro de control
d_ds1624 = 0 'Inicializa variable
I2CRead sda, scl, %10010011, 0xac, d_ds1624.LB 'lee registro de control
Endif
RA4 = 0 'led placa i2c a Off
End Function
'Controla el estado de los led, Call(x1, x2, x3, x4)
'x=0 led apagado, x=1 led encendido, x=2 no hay cambio
Proc led(led_amarillo As Byte, led_verde As Byte, luz_lcd As Byte, led_ebi2c As Byte)
If led_amarillo = 1 Then RA7 = 0 'led amarillo a on
If led_amarillo = 0 Then RA7 = 1 'led amarillo a off
If led_verde = 1 Then RB0 = 0 'led verde a on
If led_verde = 0 Then RB0 = 1 'led verde a off
If luz_lcd = 1 Then RB3 = 1 'LCD iluminado
If luz_lcd = 0 Then RB3 = 0 'LCD apagado
If led_ebi2c = 1 Then RA4 = 1 'led EB_I2C a on
If led_ebi2c = 0 Then RA4 = 0 'led EB_I2C a off
End Proc