'ADAPTADO PARA EL PIC16F877 ***********************************************************
Define CONF_WORD = 0x3f32
Define CLOCK_FREQUENCY = 20
'********************************** PIC Entrenadora BASIC (PicEBasic)******************************
'NOMBRE: 16F88_Pic_EBasic_LCD_RTC_ADC_12******ADAPTACION AL PIC16F877******************************
'MICRO: PIC16F88
'FECHA/AUTOR: 04/07, 05/07 - By COS
'VERSION 1.2
'Se habilita el modulo usar como salida de datos serie
'se cambian todos los "Serout PORTB.5, 4800, " por Hserout
'se observa un ahorro de memoria considerable y una aceleracion del programa increible.
'VERSION 1.1
'modificacion de la rutina "pause_ms"
'modificacion de rutina de teclas, porque se veian afectadas al crecer la longitud del programa main
'Se añade salida de la temperatura, hora y fecha por el puerto serie (Soft)
'Pendiente de grafica de temperatura por el hyperterminal
'VERSION 1.0
'DESCRIPCION: Muestra en el display la fecha, hora (24h)mediante el DS1307 y temperatura (LM35)
'S1 y S2 pulsadas al mismo tiempo, entramos en programacion del reloj
'Una vez en programacion con S1 seleccionamos el dato a cambiar, este queda en modo parpadeo
'Una vez en programacion con S2 incrementamos el dato seleccionado dentro de sus cotas
'S1, pulsado al principio salida del RTC a on, 1Hz, y S2 salida a off, led off
'Se muestra la temperatura en el LCD mediante un LM35, temperatura positiva y negativa
'***************************************************************************************************
'-------------------------------------Puertos del LCD-----------------------------------------------
Define LCD_BITS = 8
Define LCD_DREG = PORTB
Define LCD_DBIT = 0
Define LCD_RSREG = PORTC
Define LCD_RSBIT = 0
Define LCD_EREG = PORTC
Define LCD_EBIT = 4
Define LCD_RWREG = PORTC
Define LCD_RWBIT = 1
Define LCD_COMMANDUS = 2000 'Tiempo de espera despues de ejecutar un comand 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, solo se ejecuta una vez en mSeg.
'-----------------------------------asignacion de nombres-----------------------------------------------------
Symbol sda = PORTC.2 'asignamos nombre al pin que hara de SDA del puerto I2C
Symbol scl = PORTC.3 'asignamos nombre al pin que hara de SCL del puerto I2C
Symbol led_amarillo = PORTA.7 'led amarillo
Symbol led_verde = PORTB.0 'led verde
Symbol luz_lcd = PORTB.3 'retroiluminacion del lcd
Symbol s1 = RE0 'se asigna nombre a la tecla
Symbol s2 = RE1 'se asigna nombre a la tecla
'***********************************DEFINICION DE VARIABLES**************************************
'-----------------------------------variables de los timer---------------------------------------
DIM aux_pause
AS Word
'variable auxiiar el PAUSE DIM pause
AS Word
'contiene el valor para simular el comando Waitms DIM timer_1ms
AS Word
'base de tiempos se incrementa cada 1mSeg, timer del PAUSE DIM timer_base
AS Byte
'tiempo referencia para los timer por soft del programa DIM timer_base_tiempo
AS Byte
'contiene el valor del tiempo del timer_base DIM timer1_ms
AS Word
'base de tiempos en ms DIM timer2_ms
AS Word
'base de tiempos en ms DIM timer3_ms
AS Word
'base de tiempos ms DIM timer1_100ms
AS Byte
'base de tiempos msx100 DIM timer2_100ms
AS Byte
'base de tiempos msx100 DIM timer3_100ms
AS Byte
'base de tiempos msx100 DIM timer_1ms_tiempo
AS Word
'contiene el valor del tiempo de timer_1ms DIM timer1_ms_tiempo
AS Word
'contiene el valor del tiempo del timer1_ms DIM timer2_ms_tiempo
AS Word
'contiene el valor del tiempo del timer2_ms DIM timer3_ms_tiempo
AS Word
'contiene el valor del tiempo del timer3_ms DIM timer1_100ms_tiempo
AS Byte
'contiene el valor del tiempo del timer1_100ms DIM timer2_100ms_tiempo
AS Byte
'contiene el valor del tiempo del timer2_100ms DIM timer3_100ms_tiempo
AS Byte
'contiene el valor del tiempo del timer3_100ms '--------------------------------------Variables Programa RTC----------------------------------------
DIM aux_4h
AS Byte
'contendra el nibble alto del dato leido por el I2C DIM aux_4l
AS Byte
'contendra el nibble bajo del dato leido por el I2C DIM i
AS Byte
'variable indice DIM reg
(7) AS Byte
'contendra los valores finales de fecha y hora en el sistema decimal DIM flash_1
AS Bit
'controla el parpadeo de los digitos del lcd, activo a 1 DIM dato
AS Byte
'indica la direccion del RTC a cambiar de valor DIM flag_1
AS Bit
'activa la rutina de ajuste del reloj, activo a 1 DIM s1_on
AS Bit
'tecla pulsada si s1_on=1 DIM s2_on
AS Bit
'tecla pulsada si s2_on=1 DIM aux_ajuste
AS Byte
'variable auxiliar para la rutina de ajuste '-----------------------------------------------------------------------------------------------
'-------------------------------Variables del ADC y Rutina division (temperatura)------------------------------
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 (temperatura)----------------------------
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------------------------------------------
'------------------------------------asignacion de valores a las variables (RTC)--------------------------
s1_on = 0
s2_on = 0
dato = 7 'fuera de ajuste o modo normal de trabajo del reloj, de 0 a 6 modo ajuste
flash_1 = 0
flag_1 = 0
timer_base = 0
timer1_ms = 0
timer2_ms = 0
timer3_ms = 0
timer1_100ms = 0
timer2_100ms = 0
timer3_100ms = 0
timer_base_tiempo = 100 'temporiza 100 mSeg
timer_1ms_tiempo = 1 'temporiza 1mseg
timer1_ms_tiempo = 100 'temporiza 100 mSeg., asignado a la tecla S1
timer2_ms_tiempo = 500 'temporiza 500 mSeg.
timer3_ms_tiempo = 100 'temporiza 100 mSeg., asignado a la tecla S2
timer1_100ms_tiempo = 10 'temporiza 1 Seg.
timer2_100ms_tiempo = 10 '255 'temporiza 25.5 Seg.
timer3_100ms_tiempo = 1 'temporiza 0.1seg.
'-------------------------------------asiganacion de valores a las variables (temperatura)------
entero = 0
decimal = 0
division = 0
adc_4 = 0
factor_escala = 10 'factor de escala para un decimal
temperatura = 0
temp = 0
media_indice = 0
aux_media = 0
'**************************************DEFINICION DE PUERTOS*************************************
'----------------------ASIGNACION DE I/O y valores de inicio de las salidas---------------------
AllDigital
'ADCON1 = 0x07 'Los pin PORTA como I/O
TRISA = 0xff 'Puerto A como salidas
TRISB = 0xff 'puerto B como salidas
TRISC = 0xff
TRISD = 0xff
TRISE = 0xff
'TRISA.4 = 1 'como entrada (RA4, adc)
TRISE.0 = 1 'como entrada (RA6, tecla S1)
TRISE.1 = 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
'------------------------------------Velocidad de la UART-----------------------------------------
Hseropen 4800 'velocidad de trabajo del modulo UART del PIC, RB5 tiene que ser declarado como salida
'------------------------------------Inicializacion de Interrupciones-----------------------------
T1CON.TMR1CS = 0 'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
T1CON.T1CKPS0 = 0 'factor del preescales del timer1, 0
T1CON.T1CKPS1 = 0 'factor del preescales del timer1, 0
TMR1H = 0xfc 'carga el registro del contador para que desborde cada 1mSeg, byte alto
TMR1L = 0x18 'carga el registro del contador para que desborde cada 1mSeg, byte bajo
T1CON.TMR1ON = 1 'habilitacion del TMR1, comienza a incrementarce
INTCON.PEIE = 1 'bit de habilitacion de interrupciones de perifericos
Enable 'INTCON.GIE habilita todas las interrupciones globales
'**************************************Inicio Programa*********************************************
Lcdinit 'inicializa el lcd sin cursor
Hserout 0x0c, "MUESTRA LA TEMPERATURA MEDIA CADA 25.5 Seg.", CrLf 'alpuerto serie
Hserout "-------------------------------------------", CrLf, CrLf 'alpuerto serie
PIE1.TMR1IE = 1 'activa las interrupciones del timer1
pause = 1000
GOSUB pause_ms 'espera el tiempo indicado en pause
Lcdout "16F88LCD_RTC/I2C" 'escribe en el lcd
Lcdcmdout LcdLine2Home 'seleciona la linea dos como proxima para escritura
Lcdout "ADC_LM35_RS232" 'escribe en el lcd
pause = 3000
GOSUB pause_ms 'espera el tiempo indicado en pause
Lcdcmdout LcdClear 'borra el display y cursor a casa
'--------------------------------inicializa variable media_temperatura---------------------------
'Gosub inicializa_temp
'--------------------------------inicializa los registros del RTC---------------------------------
GOSUB inicaliza_rtc
'--------------------------------------Main Programa-----------------------------------------------
main:
IF s1
= 1 AND s1_on
= 1 AND s2
= 1 AND s2_on
= 1 AND flag_1
= 0 THEN '________modo ajuste flag_1 = 1 'activa la rutina de ajustes
dato = 0 'selecciono registro del RTC
pause = 200
GOSUB pause_ms 'hace una pausa del valor que tenga pause en ms
s1_on = 0 'desbloquea la tecla S1
s2_on = 0 'desbloquea la tecla s2
Endif '___________________
IF flag_1 = 1 THEN GOSUB ajuste_reloj '__________saltamos a la rutina de ajuste
IF timer3_100ms >= timer3_100ms_tiempo THEN 'actualiza datos en el lcd cada 100ms
GOSUB lee_hora 'lee la fecha y hora del reloj
GOSUB print_lcd 'actualiza los datos del reloj en el display
timer3_100ms = 0
Endif '__________________
IF timer2_100ms >= timer2_100ms_tiempo THEN
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_rs232_temperatura
GOSUB print_rs232_date
timer2_100ms = 0
Endif
GOTO main
'--------------------------------------FIN DEL MAIN---------------------------------------------
'**************************************Subrrutinas**********************************************
inicaliza_rtc: '-------------------------inicializa el reloj----------------------------------------------------
PIE1.TMR1IE = 0 'deshabilita las interrupciones del timer1
I2CRead sda, scl, 0xd1, 0, reg(0) 'leo los segundos
reg
(0) = reg
(0) AND %
01111111 'habilito bit de control que activa el reloj I2CWrite sda, scl, 0xd0, 0, reg(0) 'escribo el registro de los segundos
I2CRead sda, scl, 0xd1, 1, reg(0) 'leo el registro de los minutos
reg
(0) = reg
(0) AND %
10111111 'habilito bit de control que activa el formato de 24h I2CWrite sda, scl, 0xd0, 0, reg(0) 'escribo el registro de los minutos
'-------------------------------inicializa la salida del RTC-------------------------------
I2CWrite sda, scl, 0xd0, 7, 0x10 'salida a 1hz, a on
IF s2 = 0 THEN I2CWrite sda, scl, 0xd0, 7, 0x80 'salida a off, led off
PIE1.TMR1IE = 1 'habilita las interrupciones del timer1
pause = 1000
GOSUB pause_ms 'espera el tiempo indicado en pause
RETURN
ajuste_reloj: 'rutina de ajuste del reloj
'________________________Control posicion del dato a variar en el reloj
IF s1
= 1 AND s1_on
= 1 AND s2_on
= 0 THEN 'detecta tecla S1 dato = dato + 1 'seleciona el dato a ser modificado
IF dato > 6 THEN flag_1 = 0 'indica fin de rutina de ajuste
s1_on = 0 'la tecla queda desbloqueada
Endif '_____________________________
'____________Lectura de la hora para su modificacion y posterior grabacion, rutina BCD
IF s2
= 1 AND s2_on
= 1 AND s1_on
= 0 THEN 'deteca tecla S2 s2_on = 0 'la tecla queda desbloqueada
IF dato < 7 THEN 'limita la direcciones de trabajo del reloj
GOSUB lee_hora 'lee los datos de los regis. RTC y los pasa a decimal, elimina los bit de control
aux_ajuste = reg(dato) 'hace una imagen del valor del registro a modificar
aux_ajuste = aux_ajuste + 1 'incrementa el dato a modificar que fue seleccionado
IF dato
= 2 AND aux_ajuste
> 23 THEN aux_ajuste
= 0 'acota horas IF dato
= 0 OR dato
= 1 THEN 'acota segundos y minutos IF aux_ajuste > 59 THEN aux_ajuste = 0
Endif
IF dato
= 3 AND aux_ajuste
> 7 THEN aux_ajuste
= 1 'acota el dia de la semana IF dato
= 4 AND aux_ajuste
> 31 THEN aux_ajuste
= 1 'acota el dia del mes IF dato
= 5 AND aux_ajuste
> 12 THEN aux_ajuste
= 1 'acota el mes IF dato
= 6 AND aux_ajuste
> 30 THEN aux_ajuste
= 1 'acota el año, año maximo 2030 IF aux_ajuste
> 49 AND aux_ajuste
< 60 THEN 'Decimal a BCD aux_ajuste = aux_ajuste - 50
aux_ajuste.4 = 1
aux_ajuste.6 = 1
Endif
IF aux_ajuste
> 39 AND aux_ajuste
< 50 THEN 'Decimal a BCD aux_ajuste = aux_ajuste - 40
aux_ajuste.6 = 1
Endif
IF aux_ajuste
> 29 AND aux_ajuste
< 40 THEN 'Decimal a BCD aux_ajuste = aux_ajuste - 30
aux_ajuste.4 = 1
aux_ajuste.5 = 1
Endif
IF aux_ajuste
> 19 AND aux_ajuste
< 30 THEN 'Decimal a BCD aux_ajuste = aux_ajuste - 20
aux_ajuste.5 = 1
Endif
IF aux_ajuste
> 9 AND aux_ajuste
< 20 THEN 'Decimal a BCD aux_ajuste = aux_ajuste - 10
aux_ajuste.4 = 1
Endif
IF aux_ajuste < 10 THEN aux_ajuste = aux_ajuste 'Decimal a BCD
IF dato = 0 THEN aux_ajuste.7 = 0 'restaura el bit de configracion, activa el oscilador del reloj
IF dato = 2 THEN aux_ajuste.7 = 0 'restaura el bit, no lo utiliza el RTC
IF dato = 2 THEN aux_ajuste.6 = 0 'restaura el bit de configuracion, reloj 24h
PIE1.TMR1IE = 0 'deshabilita las interrupciones del timer1
I2CWrite sda, scl, 0xd0, dato, aux_ajuste 'actualiza el dato ya modificado
PIE1.TMR1IE = 1 'activa las interrupciones del timer1
Endif
Endif '____________
'__________Controla el parpadeo de los digitos cuando el modo selec es activo
IF timer2_ms >= timer2_ms_tiempo THEN 'tiempo del parpadeo
IF flash_1 = 1 THEN 'selecciona si el dato a modificar es visible o no
flash_1 = 0 'dato es visible
ELSE
flash_1 = 1 'dato no es visible
Endif
timer2_ms = 0 'recarga la base de tiempos
Endif '______________
RETURN
lee_hora: 'lee la hora del RTC en formato BCD y la pasa a decimal
i = 0 'variable indice, asigna los datos de forma ordenada, leidos del RTC
WHILE i <= 6 'se repite el codigo comprendido entre while y wend, mientras i sea menor o igual a 6
PIE1.TMR1IE = 0 'deshabilita las interrupciones del timer1
I2CRead sda, scl, 0xd0, i, reg(i) 'lectura de la direccion de memoria indicada del RTC, formato BCD
PIE1.TMR1IE = 1 'activa las interrupciones del timer1
aux_4l
= reg
(i
) AND %
00001111 'eliminamos los bit de configuracion del RTC y dejamos solo el nibble bajo IF i
= 0 THEN aux_4h
= reg
(i
) AND %
01110000 'segundos, borrado de bit configuracion y almacena nibble alto IF i
= 1 THEN aux_4h
= reg
(i
) AND %
01110000 'minutos, almacena nibble alto IF i
= 2 THEN aux_4h
= reg
(i
) AND %
00110000 'horas, borrado de bit configuracion y almacena nibble alto IF i
= 3 THEN aux_4h
= reg
(i
) AND %
00000000 'dia_semana, almacena nibble alto IF i
= 4 THEN aux_4h
= reg
(i
) AND %
00110000 'dia_mes, almacena nibble alto IF i
= 5 THEN aux_4h
= reg
(i
) AND %
00010000 'mes, almacena el nibble alto IF i
= 6 THEN aux_4h
= reg
(i
) AND %
11110000 'año, almacena el nibble alto aux_4h = ShiftRight(aux_4h, 4) 'convierte el nibble alto en bajo
reg(i) = (aux_4h * 10) + aux_4l 'fusiona los nibbles alto y bajo en una sola variable en formato decimal
i = i + 1 'incrementa la variable indice con cada repeticion del bucle While/Wend
WEND 'fin del bucle y salta a While
RETURN
print_lcd: 'rutina de escritura en el lcd
Lcdcmdout LcdLine1Home 'cursor del lcd a la izquierda en la linea 1
IF dato
= 2 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos de la hora Lcdout " " 'borra el dato determinado para dar la sensacion de parpadeo
ELSE
IF reg(2) < 10 THEN Lcdout "0" 'si horas es inferior a 10 escribe el cero delante
Lcdout #reg(2) 'escribe la hora
Endif
Lcdout ":" 'escribe el separador
IF dato
= 1 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos de los minutos Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(1) < 10 THEN Lcdout "0" 'si minutos es inferior a 10 escribe el cero delante
Lcdout #reg(1) 'escribe los minutos
Endif
Lcdout ":" 'escribe el separador
IF dato
= 0 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos de los segundos Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(0) < 10 THEN Lcdout "0" 'si segundos es inferior a 10 escribe el cero delante
Lcdout #reg(0) 'escribe los segundos
Endif
GOSUB print_lcd_temp 'salto con retorno a la rutina de impresion de la temperatura
Lcdcmdout LcdLine2Home 'cursor del lcd a la izquierda en la linea 2
IF dato
= 3 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos del dia semana Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(3) = 1 THEN Lcdout "Dom." 'asigna el literal al dia de la semana
IF reg(3) = 2 THEN Lcdout "Lun."
IF reg(3) = 3 THEN Lcdout "Mar."
IF reg(3) = 4 THEN Lcdout "Mie."
IF reg(3) = 5 THEN Lcdout "Jue."
IF reg(3) = 6 THEN Lcdout "Vie."
IF reg(3) = 7 THEN Lcdout "Sab."
Endif
Lcdout " " 'escribe separador
IF dato
= 4 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos del dia del mes Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(4) < 10 THEN Lcdout "0" 'si dia del mes es inferior a 10 escribe cero
Lcdout #reg(4) 'escribe el dia del mes
Endif
Lcdout "/" 'escribe el separador
IF dato
= 5 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos de los meses Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(5) < 10 THEN Lcdout "0" 'si mes es inferior a 10 escribe cero
Lcdout #reg(5) 'escribe el mes
Endif
Lcdout "/20" 'separador y los dos primeros digitos del año de 4 digitos
IF dato
= 6 AND flash_1
= 1 THEN 'control final del parpadeo de los digitos de los años Lcdout " " 'borra el dato determinado para dar la sencacion de parpadeo
ELSE
IF reg(6) < 10 THEN Lcdout "0" 'si año es inferior a 10 escribe primero el cero
Lcdout #reg(6) 'escribe el año
Endif
RETURN
'--------------------------------------Subrrutina lectura ADC, division y LCD
lee_adc: '_______________________lee la entrada analogica
'ADCON1 = 0x00 'Los pin PORTA como analogicos
'Adcin 4, adc_4 'Lee el valor de la entrada analogica y lo guarda en adc_4
'ADCON1 = 0x07 'Los pin PORTA como I/O
RETURN
print_lcd_temp: '____________________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
Lcdout " " 'espacio en blanco
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
'___________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
inicializa_temp: '__________inicializa la media aritmetica de la temperatura en el arranque
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
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
RETURN
print_rs232_temperatura: 'Envia la temperatura con decimales al puerto serie
PIE1.TMR1IE = 0 'OFF, interrupciones del timer1
Hserout "TEMPERATURA: " 'pagina en blanco y literal al purto serie
IF signo = 0 THEN Hserout "+" 'muestra el signo de la temperatura
IF signo = 1 THEN Hserout "-" 'muestra el signo de la temperatura
Hserout #entero, ".", #decimal, " " 'temperatura al rs232
PIE1.TMR1IE = 1 'ON, interrupciones del timer1
RETURN
print_rs232_date: 'rutina de escritura de la hora y fecha por el RS232
PIE1.TMR1IE = 0 'OFF, interrupciones del timer1
IF reg(2) < 10 THEN Hserout " 0" 'si horas es inferior a 10 escribe el cero delante
Hserout #reg(2), ":" 'escribe la hora
IF reg(1) < 10 THEN Hserout "0" 'si minutos es inferior a 10 escribe el cero delante
Hserout #reg(1), ":" 'escribe los minutos
IF reg(0) < 10 THEN Hserout "0" 'si segundos es inferior a 10 escribe el cero delante
Hserout #reg(0), " " 'escribe los segundos
IF reg(3) = 1 THEN Hserout "Dom." 'asigna el literal al dia de la semana
IF reg(3) = 2 THEN Hserout "Lun."
IF reg(3) = 3 THEN Hserout "Mar."
IF reg(3) = 4 THEN Hserout "Mie."
IF reg(3) = 5 THEN Hserout "Jue."
IF reg(3) = 6 THEN Hserout "Vie."
IF reg(3) = 7 THEN Hserout "Sab."
IF reg(4) < 10 THEN Hserout " 0" 'si dia del mes es inferior a 10 escribe cero
Hserout #reg(4), "/" 'escribe el dia del mes
IF reg(5) < 10 THEN Hserout "0" 'si mes es inferior a 10 escribe cero
Hserout #reg(5), "/20" 'escribe el mes
IF reg(6) < 10 THEN Hserout "0" 'si año es inferior a 10 escribe primero el cero
Hserout #reg(6), "#", CrLf 'escribe el año
PIE1.TMR1IE = 1 'ON, interrupciones del timer1
RETURN
pause_ms: 'rutina de espera, rutina tipo Waitms, pause establese el tiempo total en mSeg
'pause = 1 'ESTA LINEA SOLO SE ACTIVA CUANDO SE UTILIZA EL SIMULADOR
PIE1.TMR1IE = 0 'OFF, interrupciones del timer1
timer_1ms_tiempo = pause 'valor a temporizar por timer_1ms
timer_1ms = 0 'al borrar el contador se activa y comienza la cuenta de 1mSeg
PIE1.TMR1IE = 1 'ON, interrupciones del timer1
WHILE timer_1ms < timer_1ms_tiempo 'tiempo en mSeg maximos a contar
WEND
RETURN
'***********************************Interrupciones*****************************************************
ON Interrupt
'Comienzan las rutinas de las interrupciones, desactiva las interrupciones TMR1H = 0xec 'recarga el contador del timer1 para que desborde pasado 1mSeg, byte alto
TMR1L = 0x79 'recarga el contador del timer1 para que desborde pasado 1mSeg, byte bajo
Save
SYSTEM 'Guarda los valores del sistema para poder reemprender el curso normal del programa IF PIR1.TMR1IF = 1 THEN 'comprueba que la interrupcion del timer1 es activa
'_________________bases de tiempos
timer_base = timer_base + 1 'contador general
IF timer_1ms < timer_1ms_tiempo THEN timer_1ms = timer_1ms + 1 'contador para control de la rutina Pause
IF timer1_ms < timer1_ms_tiempo THEN timer1_ms = timer1_ms + 1 'contador
IF timer2_ms < timer2_ms_tiempo THEN timer2_ms = timer2_ms + 1 'contador
IF timer3_ms < timer3_ms_tiempo THEN timer3_ms = timer3_ms + 1 'contador
IF timer_base >= timer_base_tiempo THEN 'limita el timepo de ejecucion, cada timer_base_tiempo
IF timer1_100ms < timer1_100ms_tiempo THEN timer1_100ms = timer1_100ms + 1 'contador
IF timer2_100ms < timer2_100ms_tiempo THEN timer2_100ms = timer2_100ms + 1 'condtador
IF timer3_100ms < timer3_100ms_tiempo THEN timer3_100ms = timer3_100ms + 1 'contador
timer_base = 0 'reset a la base de tiempos
Endif '________________fin bases de tiempos
PIR1.TMR1IF = 0 'borra el flag de salto del tmr1
Endif
'_________________Detecta tecla pulsada
IF s1
= 0 AND s1_on
= 0 AND timer1_ms
>= timer1_ms_tiempo
THEN 'tecla S1 s1_on = 1 'la tecla fue pulsada
s2_on = 0 'la tecla s2 a pff
IF s1
= 0 AND s2
= 0 THEN s2_on
= 1 'S2 timer1_ms = 0 'tiempo entre pulsacion y pulsacion
Endif
IF s2
= 0 AND s2_on
= 0 AND timer3_ms
>= timer3_ms_tiempo
THEN 'tecla s2 s2_on = 1 'la tecla fue pulsada
s1_on = 0 'la tecla s1 a off
IF s1
= 0 AND s2
= 0 THEN s1_on
= 1 'S1 timer3_ms = 0 'tiempo entre pulsacion y pulsacion
Endif
IF s1 = 0 THEN led_verde = 0 'mestra el estado de S1
IF s2 = 0 THEN led_amarillo = 0 'muestra el estado de S2
IF s1 = 1 THEN led_verde = 1 'mestra el estado de S1
IF s2 = 1 THEN led_amarillo = 1 'muestra el estado de S2
'________Fin detecta tecla pulsada
RESUME 'activa las interrupciones y retorna el curso normal del programa, antes del salto