Termometro con pic16F877A

Esto es para los interesados en electronica y microcontroladores, es un termometro digital hecho con un pic16F877A, un display de 16x2 y un LM35 (sensor de temperatura). El sensor manda la señal analogica al microcontrolador y despliega en el display la temperatura que el sensor esta capturando. Tiene una varioacion como de 1 grado con la temperatura real asi que es bastante exacto. Les dejo el circuito electrico, la simulacion la hice con el ISIS proteus:

====== Lista de materiales ======

U1 = Microcontrolador PIC16F877A
U2 = Sensor de temperatura LM35
LCD1 = Display de 16x2 (16 caracteres por 2 filas)
X1 = Cristal de cuarzo de 4Mhz
PB1 = pulsador o push button normalmente abierto
R1 = Resistencia de 100 ohm a 1/4 w
R2 = Resistencia de 10 kohm a 1/4 w
RV1 = Potenciometro de 10 kohm
C1, C2 = Capacitores ceramicos de 15pf (no polarizados)
C3 = Capacitor ceramico de 100nf (no polarizados)
D1 = Diodo 1N4148

NOTA: Si tu LCD tiene un led para la luz de fondo debes agregarle una resistencia de 220 o 330 ohm en el pin del anodo o polo positivo de este led. Pera saber cuales son esos pines consulta el datasheet de tu LCD.

Termometro con pic16F877A

electronica

Tambien les dejo el codigo, esta hecho en lenguaje ensamblador, el codigo no lo hice, solo lo modifique del original por que estaba hecho para el pic16f887, les dejo la info del autorIng. Miguel Angel Piedra Angeles, http://www.cosasdeingenieria.com

;*********************************************************************************** ; *
; programa: termometro.asm * ; *
; este programa muestra el funcionamiento del conversor analógico - digital que *
; contiene el pic16f877a. toma la señal analógica del sensor de temperatura y la *
; convierte a digital. una vez hecha la conversión la despliega en la pantalla lcd *
; dándonos como resultado la temperatura que hay en el ambiente. * ; *
; velocidad del reloj: 4mhz tipo de reloj: xt *
; perro guardián: deshabilitado protección del código: off * ; * ;***********************************************************************************
list p=16f877a radix hex include "p16f877a.inc" ;declaración de la librería ;*******************declaración de los bits de configuración*******************
__config _cp_off&_cpd_off&_lvp_off&_wdt_off&_xt_osc
;************************** declaración de registros **************************
cblock 0x20 num1,num2,num3 ;******************************************************************************
pointer ;registros utilizados en
unidades,decenas ;binbcd y en la adquisición de
centenas,millares ;datos
datoh
unidadest,decenast
centenast,millarest
sample
shift
;******************************************************************************
promedio
contador
endc

cblock 0x70 ;se coloca a datol en una de las localidades de datol
;memoria que están espejadas en banco0 y banco1
endc
;****************************************************************************** ;****************declaración de los pines de control de la lcd*****************
#define rs portc,2
#define en portc,1 ;****************************************************************************** ;**************puerto donde estarán los pines de datos de la lcd***************
portlcd equ portd ;****************************************************************************** ;******************************************************************************
;comandos de la pantalla
limpiar equ b'00000001' ;limpia toda la pantalla
renglon1 equ b'10000000' ;coloca en el renglón 1
renglon2 equ b'11000000' ;coloca en el renglón 2
dison equ b'00001100' ;enciende el display
home equ b'00000010' ;va a la dirección 0
shiftdl equ b'00011100' ;rota el lcd a la izquierda
shiftdr equ b'00011000' ;rota el lcd a la derecha
shiftcl equ b'00010100' ;rota el cursor a la izquierda
shiftcr equ b'00010000' ;rota el cursor a la derecha ;******************************************************************************
org 0x00 ;vector de reset
goto inicio ;salto al inicio del código
org 0x04 ;vector de interrupción
;*******************tablas de datos para la subrutina binbcd*******************
tablau ;tabla de unidades
movf pointer,w
addwf pcl,f
retlw d'2'
retlw d'6'
retlw d'8'
retlw d'4'
retlw d'2'
retlw d'6'
retlw d'8'
retlw d'4'
retlw d'2'
retlw d'1'

tablad ;tabla de decenas
movf pointer,w
addwf pcl,f
retlw d'1'
retlw d'5'
retlw d'2'
retlw d'6'
retlw d'3'
retlw d'1'
retlw d'0'
retlw d'0'
retlw d'0'
retlw d'0'

tablac ;tabla de centenas
movf pointer,w
addwf pcl,f
retlw d'5'
retlw d'2'
retlw d'1'
retlw d'0'
retlw d'0'
retlw d'0'
retlw d'0'
retlw d'0'
retlw d'0'
retlw d'0' ;******************************************************************************
inicio: bsf status,rp0 ;cambio a banco1
clrf trisd ;configuro todo portd como salida
bcf trisc,1 ;configuro portc,1 como salida(en)
bcf trisc,2 ;configuro portc,2 como salida(rs)
bcf status,rp0 ;cambio a banco0
clrf portd ;apago posible latchs en portd
clrf portc ;apago posible latchs en portc
call init_adqui ;llamo a la subrutina de configuración de
;el modulo adc
call initlcd ;llamo a la subrutina de inicialización
;de la pantalla lcd 16x2
start call d16x2 ;llamo a la subrutina que escribe el mensaje inicial ;****************************************
;codigo que hace que se ejecute el comando de rotación a la derecha 46 veces
movlw .46
movwf shift

vuelta call retardo
movlw shiftdr ;comando de rotación
call cmd
decfsz shift,f
goto vuelta
;****************************************
movlw limpiar ;comando de limpieza de pantalla
call cmd
opera movlw renglon1 ;comando para empezar a escribir a partir
call cmd ;de la primera dirección del renglon1
clrf promedio ;se limpia al registro promedio
call adqui ;se llama a la subrutina de adquisición de
;datos del adc
call binbcd ;llamo a la subrutina que convierte de binario
;a ascii
;****************************************
movf millares,w ;mando los datos adquiridos a la lcd
call dato
movf centenas,w
call dato
movf decenas,w
call dato
movf unidades,w
call dato
;****************************************
movlw b'11011111' ;dato para el símbolo de grado
call dato
movlw 'c' ;la c de celsius
call dato
goto opera ;regreso al inicio del programa principal
;**************************subrutina de los mensajes **************************
d16x2 movlw "p"
call dato
movlw "r"
call dato
movlw "o"
call dato
movlw "y"
call dato
movlw "e"
call dato
movlw "c"
call dato
movlw "t"
call dato
movlw "o"
call dato
movlw " "
call dato
movlw "p"
call dato
movlw "d"
call dato
movlw "m"
call dato
movlw renglon2
call cmd
movlw "t"
call dato
movlw "e"
call dato
movlw "r"
call dato
movlw "m"
call dato
movlw "o"
call dato
movlw "m"
call dato
movlw "e"
call dato
movlw "t"
call dato
movlw "r"
call dato
movlw "o"
call dato
movlw " "
call dato
movlw "a"
call dato
movlw "/"
call dato
movlw "d"
call dato
return
;**********************subrutina de adquisición del adc**********************
adqui: call sampletime ;retardo de adquisición
bsf adcon0,go ;inicia la conversión
btfsc adcon0,go ;ya se termino la conversión?
goto $-1 ;no? pregunta de nuevo
banksel adresh ;si, continua
movf adresh,w ;lee la parte más significativa
movwf datoh ;guárdalo en datoh
banksel adresl ;cambio a banco1
movf adresl,w ;lee la parte menos significativa
movwf datol ;guárdalo en datol
banksel portb ;cambio a banco0
bcf status,c ;borra el bit de acarreo
rrf datoh,f ;elimino el bit menos significativo
rrf datol,f ;para ocupar solo 9 bits
return
sampletime:
movlw .225
movwf sample
espera_s:
nop
nop
decfsz sample,f
goto espera_s
return
;***********************subrutina de inicialización lcd************************
initlcd:
movlw b'00110000' ;1
call cmd
movlw b'00110000' ;2
call cmd
movlw b'00110000' ;3
call cmd
movlw b'00111100' ;4
call cmd
movlw b'00001000' ;5
call cmd
movlw b'00000001' ;6
call cmd
movlw b'00000110' ;7
call cmd
movlw dison ;8
call cmd
movlw home
call cmd
return
;*****************subrutina que envía los caracteres a la lcd******************
dato movwf portlcd
bsf rs
nop
nop
nop
bsf en
call retardo5ms
bcf en
return
;******************subrutina que envía los comandos a la lcd*******************
cmd movwf portlcd
bcf rs
nop
nop
nop
bsf en
call retardo5ms
bcf en
return
;******************************************************************************
retardo5ms
movlw d'1'
movwf num3
otra25 movlw d'100'
movwf num2
otra15 movlw d'166'
movwf num1
otra5 decfsz num1,f
goto otra5
decfsz num2,f
goto otra15
decfsz num3,f
goto otra25
return
;******************************************************************************
retardo movlw d'3'
movwf num3
otra25a movlw d'200
' movwf num2
otra15a movlw d'166'
movwf num1
otra5a decfsz num1,f
goto otra5a
decfsz num2,f
goto otra15a
decfsz num3,f
goto otra25a
return
;******************subrutina de conversión de binario a ascii******************
binbcd clrf millares
clrf unidades
clrf decenas
clrf centenas
clrf pointer
otra btfss datoh,7
goto rota
call tablau
addwf unidades,f
call tablad
addwf decenas,f
call tablac
addwf centenas,f
;****************************************
movf unidades,w
sublw d'10'
btfss status,c
goto mayor
goto menor
mayor incf decenas,f
movlw d'10'
subwf unidades,f
goto dece
menor movlw d'10'
subwf unidades,w
btfss status,z
goto dece
goto mayor
;****************************************
dece movf decenas,w
sublw d'10'
btfss status,c
goto mayord
goto menord
mayord incf centenas,f
movlw d'10'
subwf decenas,f
goto cente
menord movlw d'10'
subwf decenas,w
btfss status,z
goto cente
goto mayord
;****************************************
cente movf centenas,w
sublw d'10'
btfss status,c
goto mayorc
goto menorc
mayorc incf millares,f
movlw d'10'
subwf centenas,f
goto milla
menorc movlw d'10'
subwf centenas,w
btfss status,z
goto milla
goto mayorc
;****************************************
milla movf millares,w
sublw d'10'
btfss status,c
goto mayorm
goto menorm
mayorm movlw d'10'
subwf millares,f
goto rota
menorm movlw d'10'
subwf millares,w
btfss status,z
goto rota
goto mayorm
;****************************************
rota rlf datol,f
rlf datoh,f
incf pointer,f
movf pointer,w
sublw d'10'
btfss status,z
goto otra
movlw 0x30
addwf unidades,f
movlw 0x30
addwf decenas,f
movlw 0x30
addwf centenas,f
movlw 0x30
addwf millares,f
return
;**********************subrutina de configuración del cad**********************
init_adqui:
bsf status,rp0
bsf trisa,0
clrf adcon1
bcf status,rp0
movlw b'11000001'
movwf adcon0
return
end ;final del programa

Es pero les sea util, saludos y espero sus comentarios

23 comentarios - Termometro con pic16F877A

@Legolas0388
muchas gracias loco justo lo que buscaba...espero que ande!
@evagor2710
chingo krnal pero estaria mejor con todo y el protus para descargar
@anirak3000
Q bien todo...vi que lo tienes con el 887, crees que me lo puedas pasar? Espero q si...Gracias!!!
@jorget12
buen aporte es lo que buscaba, gracias
@loky1989teo
NO COMPILA, HAY VARIABLES QUE NISIQUIERA HAS DECLARADO, GRACIAS POR HACERME PERDER 1 HORA
@lukazmo +1
che amigo me podrias pasar por favor el archivo hex y la simulacion en proteus
@lukazmo
che amigo me podrias pasar el archivos hex y la simulaacion en proteus por favor
@blackburne44
lo modifico??? en "list" sigue diciendo "16f887a", el ensamblador esta utilizando otro archivo para ensamblar, hay funciones q no van a estar declaradas para el 16f84 y viceversa.
@leumaszeri
oye me podrias mandar el programa con la simulacion eske ya trate de hacerlo y no me sale
@CAASIWARE
GRACIAS!, este trabajo es muy útil, gracias de nuevo!
@xmax30
cuando compilo el archivo no me sale el archivo hexadecimal, ¿que puedo hacer?
@aldo_sanchez12
perdon, pero tendras la direccion web del .asm para el 16f887, q es el que necesito, porfa, gracias
@josem1708
Buenos días. Por casualidad tienes el código para el pic16f877 (no el A). Mi correo es josem1708@hotmail.com. Gracias de antemano.
@spunkyLeeloo
No lo siento amigo, revisa el datasheet de tu pic, no creo que cambien mucho las instrucciones, y gracias por comentar
@1099547782
seria bueno q subiera un blog de notas con el codigo