La nueva version del programa que muestra el signo de la temperatura:
'************************* PIC Entrenadora BASIC (PicEBasic)******************************
'NOMBRE: 16F88_LCD_ADC_Funcion_14
'VERSION: 1.3
'MICRO: PIC16f88A
'FECHA/AUTOR: 04/07, 02/07, 13/07, 12/06 - By COS, PSI v7.41
'Version 1.4
'Para la version 1.3 de hard, 04/07, etpa_lm35xz, LM35: -55 a +150C.
'Se hacen modificaciones para que muestre valores negativos de temperatura con la nueva version del hard.
'Se corrige la rutina de calculo de temperatura para el nuevo circuito acondicionador
'Se corrige la rutina de muestra de datos para mostrar la temperatura con signo.
'Version: 1.3
'Se añade un sensor de temperatura en la entrada RA4, se conecta un LM35DZ por medio de la placa ETPA_LM35xZ, Ver. 1.2
'Se toma una lectura cada 1000mSeg. y se calcula la media aritmetica con 20 muestras
'Se ajusta la placa ETPA_LM35xZ, para maxima temperatura 60º = 3V (RA2)
'Como 5V=1023=100º, 3V=613.8=60º
'Como el rango de temperatura del LM35DZ es de 0º a 100º, el RA1 se ajusta a cero voltios
'Version: 1.2
'Simplificado de la rutina de division
'Modificacion de la rutina print_lcd, para hacerla compatible con el nuevo formato salida de datos de la division
'Version: 1.1
'Se acelera la rutina del display
'Se implementa una rutina tipo funcion para la division
'Version: 1.0
'Descripcion: muestra en el display el valor de la entrada analogica con dos decimales y en voltios
'***********************************************************************************
Define CONFIG = 0x2f50 'Configuración bits (Fuses)
Define CONFIG2 = 0x3ffc 'Configuración bits (Fuses)
Define CLOCK_FREQUENCY = 8 'Clock en Mhz
'Define SIMULATION_WAITMS_VALUE = 1 'Activar para simulación, acelera los comandos 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*************************************
'Asignacion de I/O y valores de inicio de las salidas---------------------
ANSEL = %00000000 'Los pin I/O digitales
Define ADC_SAMPLEUS = 10 'El minimo, configuracion del ADC
Define ADC_CLOCK = 5 '16Tad a 8Mhz = 2uSeg, minimo permitido por el micro 1.5uSeg, configuracion ADC
'_______________Registros afectados por Define ADC_CLOCK y ADCIN________________
ANSEL = %00010000 'Los pin I/O digitales y RA4 analogico
ADCON0 = %01100000 'Fosc/16 a 8Mhz (ADCON1.ADCS2=1) =2uSeg (minimo 1.uSeg), channel RA4
ADCON1 = %01000000 'Voltage reference (AVdd/AVss) y seleccion de escala division clock/2 ADCON1.ADCS2=1
'_______________________________________________________________________________
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)
PORTB.3 = 1 'Luz lcd a on (RB3)
PORTA.7 = 1 'Led amarillo a off
PORTB.0 = 1 'Led verde a off
'------------------------------------------------------------------
Lcdinit 'Inicializa el lcd sin cursor
'Variables globales
'Variables del ADC y Rutina division------------------------------
Dim entero As Word 'Parte entera
Dim decimal As Word 'Los dos decimales
Dim division As Long 'Almacenara el numero con los dos decimales
Dim adc_4 As Word 'Contendra el valor de la entrada del ADC
Dim aux_adc_4 As Word 'Auxiliar
'Variables temperatura-------------------------------------------
Dim factor_escala As Word 'Contiene el factor de correcion para pasar el valor del ADC a voltios, max. 5V
Dim temperatura As Word 'Almacena la temperatura final
Dim temp As Long 'Contendra la temperatura completa sin coma
Dim signo As Bit 'Indica el signo de la temperatura
'Variables calculo media aritmetica-------------------------------
Dim media_temp(20) As Word 'Numero de muestras para calcular la media aritmetica
Dim media_indice As Byte 'Se utiliza como indice
Dim aux_media As Byte 'Variable auxiliar
'Asignaciones ---------------------------------------------------
entero = 0
decimal = 0
division = 0
adc_4 = 0
factor_escala = 10 'Factor de escala para un decimal
temperatura = 0
media_indice = 0
aux_media = 0
'----------------------------------------------------------------
WaitMs 1000 'Espera 1Seg
Lcdout "16f88_LCD_ADC_" 'Escribe en el lcd
Lcdcmdout LcdLine2Home 'Seleciona la linea dos como proxima para escritura
Lcdout "Funcion_1.4"
WaitMs 3000
Lcdcmdout LcdClear
Lcdout "Pruebas LM35xZ" 'Escribe en el lcd
WaitMs 3000 'Espera 3Seg
Lcdcmdout LcdClear 'Borra el display, y cursor al principio de la primera linea
Lcdout "Lectura Pin RA4" 'Muestra los datos en el lcd
'--------------------------------Inicializa variable media_temperatura---------------------------
Gosub lee_adc 'Salto con retorno, rutina de lectura de la entrada ADC
Gosub temp_calculo 'Salto con retorno, hace el calculo de la temperatura y guarda el valor en temperatura
For media_indice = 0 To 19 'Indice para rocorrer todas las direcciones de memoria que forman la variable tipo array media_temp
media_temp(media_indice) = temperatura 'Se de el valor a media_temp
Next media_indice 'Terminacion del bucle For
media_indice = 0 'Se inicializa a cero, para un uso posterior
'--------------------------------------Main Programa-----------------------------------------------
main:
Gosub lee_adc 'Salto con retorno, rutina de lectura de la entrada ADC
Gosub temp_calculo 'Salto con retorno, hace el calculo de la temperatura y guarda el valor en temperatura
Gosub media_arit 'Salto con retorno, calcula la media aritmetica
division = dvsion_dcmles(temperatura, factor_escala) 'Llama a la funcion dvsion_dcmles, que retorna un long
Gosub print_lcd 'Salto con retorno, rutina muestra los datos por el LCD
WaitMs 1000 'Hace una pausa de 100mSeg
Goto main
End
'**************************************Subrutinas**********************************************
'Subrutina lectura ADC, division y LCD
lee_adc: '_______________________Lee la entrada analogica
Adcin 4, adc_4 'Lee el valor de la entrada analogica y lo guarda en adc_4
Return
print_lcd: '____________________Muestra los datos por el display
entero = division.HW 'Sede el word alto a entero, parte entera
decimal = division.LW 'Sede el byte alto del word bajo a decimal_1
Lcdcmdout LcdLine2Home 'Selecciona la primera linea y cursor al principio
Lcdout "ADC ", #adc_4, " T " 'Muestra los datos en el lcd
If signo = 0 Then Lcdout "+", #entero, "." 'Muestra los datos en el lcd
If signo = 1 Then Lcdout "-", #entero, "." 'Muestra los datos en el lcd
Lcdout #decimal, "C " 'Muestra los datos en el lcd
Return
'________Argumentos de entrada dos variables tipo word, dividendo y divisor, argumento de salida una variable tipo long
Function dvsion_dcmles(dvdo As Word, dvsor As Word) As Long '________Rutina funcion division con decimales
Dim f_entera As Word 'Variable local, contendra la parte entera
Dim f_resto As Word 'Varable local, contendra el resto
Dim f_decimal As Word 'Contendra la parte decimal
f_entera = dvdo / dvsor 'Obtengo la division
f_resto = dvdo Mod dvsor 'Obtengo el resto
f_decimal = (f_resto * 10) / dvsor 'Calculo 1 decimal, para obtener 2 decimales multiplicar por 100
dvsion_dcmles.HW = f_entera 'Almacena la parte entera en el word alto
dvsion_dcmles.LW = f_decimal 'Almacena la parte decimal word bajo
'Recuerda que la parte decimal tiene que ser mostrada en el display con plantilla de dos digitos siempre
End Function
'___________Calculo de la media aritmetica de la temperatura, 20 muestras
media_arit:
media_temp(media_indice) = temperatura 'Asigna el valor
temperatura = 0 'Se inicaliza a cero
For aux_media = 0 To 19 'Blucle for, se ejecuta 20 veces
temperatura = temperatura + media_temp(aux_media) 'Se suman los valores
Next aux_media 'Cierra for
temperatura = temperatura / 20 'Termina el calculo de la media
media_indice = media_indice + 1 'Controla la entrada de datos que corresponde a media_temp(x)
If media_indice > 19 Then media_indice = 0 'Acota el ultimo valor del indice de media_temp
Return
'___________Calculo de la temperatura
temp_calculo: 'Calculo de la temperatura y del signo de la misma
If adc_4 > 112 Then 'Determina si la temperatura es superior a 0ºC
aux_adc_4 = adc_4 'Asigna el valor del ra4 a la variable auxiliar
aux_adc_4 = aux_adc_4 - 112 'Elimina de la temperatura la parte de la escala negativa
temp = (5000 * aux_adc_4) / 1023 'Calcuala el valor de la temperatura sin coma decimal
signo = 0 'Temperatura positiva
Endif
If adc_4 = 112 Then 'Determina si la temperatura es 0ºC
temp = 0 'Temperatura 0ºC
signo = 0 'Asigna signo positivo
Endif
If adc_4 < 112 Then 'Determina si la temperatura es inferior a 0ºC
aux_adc_4 = adc_4 'Asigna el valor del RA4 a la variable auxiliar
aux_adc_4 = 112 - aux_adc_4 'Elimina de la temperatura la parte de la escala negativa
temp = (5000 * aux_adc_4) / 1023 'Calcuala el valor de la temperatura sin coma decimal
signo = 1 'Asigna el simbolo menos a la temperatura
Endif
temperatura = temp 'Se pasa de Long a Word
Return