;SONOMETRO version 16 final
;Lista de funciones acumuladas por versiones anteriores: muestra valor instantáneo-
;- muestra promedio de los valores mostrados en otro sector del LCD
;Se realiza la coversión a dbA por medio de tabla-
;Reordenamiento de pantalla - se incluye cálculo de temperatura mediante la utilización del LM 35 con amplificador de ganancia 2
;Se trabaja el conversor AD con 3 entradas analógicas - 
; posibilidad de elegir la escala mediante tecla (L o H) cambiando asi el canal del conversor ente RA0 (AN0) y RA3 (AN3). 
;Incluye subrutinas de sonido
;alarma sonora programable-correccion de 3 grados anulada
;se calibra escala H
;Se reordenan en subrutinas partes del programa- Se incluye calibracion sonometro

;Se incluye menu de funciones- sonometro+termómetro- timer
;Variante por versión: correcciones finales


;PROGRAMA VALIDO PARA PIC16F818

;--------------------------------------
;RECORDAR CAMBIAR DIRECCIONES DE REGISTROS DE PROPOSITO GENERAL A PARTIR DE 20h EN ESTE PIC

;--------------------------------------


;toma lectura mediante conversor A/D y almacena en registro leido
;muestra en LCD - MUESTRA VALOR DE REGISTRO LEIDO EN DECIMAL 3 DIGITOS -  en interfase de 4 bits
;se usara 4 bits MSB del puertob para envio de datos a 4bits - RB4 RB5 RB6 RB7 respectivamente conectados a D4 D5 D6 D7 y RB0 RB1 a RS y E respectivamente- RW va a masa.

 

	list 	p=16f818
	#include p16f818.inc

portb	equ	06h ;el puerto b esta en la posicion 06h de la ram
porta	equ	05h;el puerto b esta en la posicion 05h de la ram
trisa	equ	85h	;regis de config de puerto b esta en la direcc 85h de la ram
trisb	equ	86h	;regis de config de puerto b esta en la direcc 86h de la ram
status	equ	03h ;registro de estado esta en la direcc 03h de la ram
adresh	equ	1Eh; registro donde se almacena el resultado alto del conversor
adcon0	equ	1Fh; registro del conversor
adcon1	equ	9Fh; registro del conversor
fsr		equ 04h; registro de direccionamiento indirecto
indf	equ	00h; registro para direccionamiento indirecto
;--comienzan registros de propositos generales-----


temp5	equ	20h
aux		equ	21h; este sera un  registro auxiliar para la subrutina instruc/escrib 
unidad	equ	22h; registro unidades
decena	equ	23h; registro decenas
centena	equ	24h; registro centenas
leido	equ	25h; registro leido

tempo1	equ	26h ;registro tempo1 esta  en la direcc 26h de la ram
tempo2	equ	28h ;registro tempo2 esta  en la direcc 28h de la ram
tempo3	equ	2Ah ;registro tempo3 esta  en la direcc 2Ah de la ram -Estos 3 ultimos son para sub espera

espc	equ	2Bh; registro para retardo dentro de subrutina leercv-factible de eliminar en futuro

espc2	equ	2Ch; registro para retardo dentro de subrutina leercv-factible de eliminar en futuro

np	equ	2Dh; registro de subrutina promedx - es el divisor-

leido2		equ	2Eh; registro para guardar valor original de leido

aux2	equ	2Fh; registro de subrutina promedionp - guarda el valor acumulado de las sucesivas lecturas

bandera	equ	30h; registro equivalente a status pero para uso particular - ej se usa en subrutina promednp
promedio	equ	31h; registro de la subrutina promedionp
dcent	equ	32h; registro de almacenar dirección de memoria del LCD donde se va a escribir las centenas
ddece	equ	33h; registro de almacenar dirección de memoria del LCD donde se va a escribir las decenas
dunid	equ	34h; registro de almacenar dirección de memoria del LCD donde se va a escribir las unidades

opc	equ	35h; registro de subrutina menu

;--- registros se subrutina reloj-----------

ps1	equ	36h 
ps2	equ	37h  
ps3	equ	38h
ps4	equ	7Dh

;---Fin  registros se subrutina reloj-----------

;--- registros se subrutina timer-----------

segund	equ	7Eh
minut	equ	7Fh
;--- fin registros se subrutina timer-----------


;------Registros reservados para la tabla de conversión-----------

d1	equ 39h
d2	equ 3Ah
d3	equ 3Bh
d4	equ 3Ch
d5	equ 3Dh
d6	equ 3Eh
d7	equ 3Dh
d8	equ 3Fh
d9	equ 40h
d10	equ 41h
d11	equ 42h
d12	equ 43h
d13	equ 44h
d14	equ 45h
d15	equ 46h
d16	equ 47h
d17	equ 48h
d18	equ 49h
d19	equ 4Ah
d20	equ 4Bh
d21	equ 4Ch
d22	equ 4Dh
d23	equ 4Eh
d24	equ 4Fh
d25	equ 50h
d26	equ 51h
d27	equ 52h
d28	equ 53h
d29	equ 54h
d30	equ 50h
d31	equ 51h
d32	equ 52h
d33	equ 53h
d34	equ 51h
d35	equ 52h
d36	equ 53h
d37	equ 54h
d38	equ 55h
d39	equ 56h
d40	equ 57h
d41	equ 58h
d42	equ 59h
d43	equ 5Ah
d44	equ 5Bh
d45	equ 5Ch
d46	equ 5Dh
d47	equ 5Eh
d48	equ 5Fh
d49	equ 60h
d50	equ 61h
d51	equ 62h
d52	equ 63h
d53	equ 64h
d54	equ 65h
d55	equ 66h
d56	equ 67h
d57	equ 68h
d58	equ 69h
d59	equ 6Ah
d60	equ 6Bh
d61	equ 6Ch
d62	equ 6Dh
d63	equ 6Eh
d64	equ 6Fh
d65	equ 70h
d66	equ 71h
d67	equ 72h

;------Fin de registros reservados para la tabla de conversión-----------


;----------registros de subrutina tono1---------
tf1	equ 73h
tf2	equ 74h
ts1	equ 75h
ts2	equ 76h
ts3	equ 77h
ctperi	equ 78h
frecu	equ 79h
durac	equ 7Ah
;--------Fin registros de subrutina tono1--------
alarm	equ	7Bh; registro de subrutina alarma - guarda el valor de sonar alarma
memtemp	equ	7Ch; registro que memoriza temperatura al salir de subrutina temperatura


;--Fin de  registros de propositos generales-----




	org	00h; vector de reset
	goto	inicio; va a iniciar el programa principal
	org	05h


;--------SUBRUTINAS-------------

;Subrutina que manda una instruccion o dato al LCD

instruc
	bcf		portb,0; RB0=0 o sea RS=0 es una instruccion para LCD
	goto	dato2
escrib
	bsf	portb,0;  RB0=1 o sea RS=1 es una dato para LCD
dato2	
	movwf	aux; guarda contenido de w en aux
	movlw	0fh; carga 00001111 en w
	andwf	portb,1; AND entre w=00001111 y portb y guarda resultado en portb
	movf	aux,0; carga aux en w
	
	andlw	b'11110000'; AND entre literal 11110000 y w en el cual esta copiado aux  (guarda el resultdado en w)

	iorwf	portb,1; OR entre w  y portb - guarda resultado en portb
	
	bsf		portb,1; RB1=1 o sea E=1 habilito LCD

	call	retardo
	
	bcf		portb,1; RB1=E=0 deshabilita LCD
	
	call	retardo
	
;---terminó envio  4 bit MSB-------
;---comienza el envio de 4 bit LSB---

	movlw	0fh; carga 00001111 en w
	andwf	portb,1; AND entre w=00001111 y portb - guarda resultado en portb
	swapf	aux,0; intercambia NIBLES de aux y lo guarda en w
	andlw	b'11110000'; AND entre literal 11110000 y w en el cual esta copiado aux con los NIBLES intercambiados (guarda el resultdado en w)
	iorwf	portb,1; OR entre w  y portb - guarda resultado en portb
	bsf		portb,1; RB1=1 o sea E=1 habilito LCD
	call	retardo
	call	retardo
	bcf		portb,1; RB1=E=0 deshabilita LCD
	call	retardo
;---termino el envio de lo 4bit LSB---	
	return

;----------------------------------------

;Subrutina retardo

retardo
	
	movlw	0ffh; carga literal 0ffh en w
	movwf	temp5; mueve contenido de w a temp5
decr
	decfsz	temp5,1; decrementa temp5 y guarda resultado en temp5- salta la intruccion siguiente si temp5 es igual a cero
	goto	decr
	movlw	0ffh; carga literal 0ffh en w
	movwf	temp5; mueve contenido de w a temp5
decr2
	decfsz	temp5,1; decrementa temp5 y guarda resultado en temp5- salta la intruccion siguiente si temp5 es igual a cero
	goto	decr2
	return

;-----------------------------------------------------------------------------
;Subrutina espera - Retardo general-
	

espera	nop

retardo1
	incf	tempo1,1
retardo2
	incf	tempo2,1
retardo3
	incf	tempo3,1
	btfss 	tempo3,6
	goto	retardo3
	clrf	tempo3
	btfss	tempo2,5
	goto	retardo2
	clrf	tempo2
	btfss	tempo1,4
	goto	retardo1
	clrf	tempo1
	return
;-----Fin subrutina espera-------------------------------------------

;----SUBRUTINA mostrar que realiza escritura de CENTENAS DECENAS Y UNIDADES para valor instantaneo SPL - promedio SPL - temperatura--o cualquier
;cosa almacenada en los registros CENTENAS DECENAS Y UNIDADES-------
;la dirección de memoria LCD para centenas se toma del registro dcent - 
;la dirección de memoria LCD para decenas se toma del registro ddece - 
;la dirección de memoria LCD para unidades se toma del registro dunid - 
;los registros dcent ddece y dunid se deben cargar antes de llamar a esta subrutina


	
mostrar	

;--comienza el envío de CENTENAS---
	movlw	d'48'; cargo 48 decimal en w
	addwf	centena,1; sumo  48 decimal a centena para que  el numero en centena este  en ASCII

	
	movf	dcent,0;  carga dirección de memoria del LCD donde se  va a mostrar CENTENAS
	call 	instruc
	movf	centena,0;
	
	btfsc	centena,0; si el bit 0 de centenas es 0 salta siguiente instruccion- no muestra centenas cero

	call	escrib; muestra CENTENAS
	call	retardo
;---termino envio de  CENTENAS---

;--comienza el envío deDECENAS---


	movlw	d'48'; cargo 48 decimal en w
	addwf	decena,1; sumo  48 decimal a decena para que  el numero en decena este  en ASCII
	movf	ddece,0;   carga dirección de memoria del LCD donde se  va a mostrar DECENAS
	call	instruc
	movf	decena,0;
	call	escrib; muestra DECENAS
	call	retardo
;---termino envio de  DECENAS---

;--comienza el envío de UNIDADES---

mostrarunidad
	movlw	d'48'; cargo 48 decimal en w
	addwf	unidad,1; sumo  48 decimal a unidad para que  el numero en unidad este  en ASCII
	movf	dunid,0;   carga dirección de memoria del LCD donde se  va a mostrar UNIDADES

	call 	instruc
	movf	unidad,0; 
	call	escrib; muestra unidades
;---termino envio de  UNIDADES---

	call	espera; tiempo de espera para leer comodamente el display

	return

;--FIN SUBRUTINA -mostrar- que realiza escritura de CENTENAS DECENAS Y UNIDADES - válida para SPL instantáneo SPL promedio - temperatura

;------Subrutina DECIMAL--------------------

;Convierte el número almacenado en un registro leido (si estamos usando un conversor A/D leido se cargará con el contenido de adress) en 3 dígitos  (BCD) que seran en lo registros centena - decena - unidad.

;****ADVERTENCIA***- subrutina decimal destruye contenido del registro leido al ser usada****ADVERTENCIA***

decimal
	clrf	unidad
	clrf	decena
	clrf	centena

;----va a determinar las centenas----

	movlw	d'100'; carga decimal 100 en w
cent
	subwf	leido,1; resta 100 a leido y lo guarda en leido
	btfss	status,0; verifica el carry (el bit 0 de status)- la instruccion dice salta intrucción
;siguiente si es 1
	goto	sum; si el carry es 0 deja de restar
	incf	centena,1;  si carry es 1 incrementa centena
	goto	cent; volverá a restar 100 a leido
sum
	addwf	leido,1; suma 100 a leido- esto es porque antes de llegar aqui le habia restado 100 a leido buscando las centenas y leido valia menos de 100 antes de hacerlo
;---terminó de obtener las centenas---	

;----va a determinar las decenas----	
	movlw	d'10'; carga decimal 10 en w
dece
	subwf	leido,1; resto 10 a leido y lo guardo en leido
	btfss	status,0;  verifica el carry (el bit 1 de status)la instruccion dice salta intrucción
;siguiente si es 1
	goto	sum1; si el carry es 0 deja de restar 
	incf	decena,1; si el carry es 1 incrementa decena
	goto	dece; volverá a restar 10 a leido
sum1
	addwf	leido,1;  suma 10 a leido- esto es porque antes de llegar aqui le habia restado 10 a leido buscando las centenas y leido valia menos de 10 antes de hacerlo
	
;---terminó de obtener las decenas---

;----va a determinar las unidades----	
	movf	leido,0; carga w con lo que ha quedado en leido- representa las unidades
	movwf	unidad; carga w en registro unidad
;---terminó de obtener las unidades---
	return

;------FIN Subrutina DECIMAL--------------------

;----Subrutina (leercv) leer el conversor---------------------

leercv

	bcf	status,5 ;se posiciona en banco 0
	bcf	adcon0,0; arbitrariamente apago el convesor 
	bsf	status,5 ;se posiciona en banco1
	bcf	adcon1,6; se hace 0 el bit 6 de adcon1 - ADCS2 para que NO divida por 2 el clock del conversor


	bcf	status,5 ;se posiciona en banco0
	movlw	b'01000001'
	movwf	adcon0; se selecciona fconv=fosc/8 - se elije canal0 RA0/AN0 como entrada analógica principal en este programa
;pero tambien seran analógicas RA1/AN1 y RA3/AN3- en instruccion siguiente las declaro-
;- conversión no en progreso-go/done* en 0- enciende el conversor haciendo bit  adon = 1 del registro adcon0
	movlw	b'00000100'; este es el cambio versión 10
	bsf	status,5 ;se posiciona en banco1
	movwf	adcon1; justificación a izquierda - se trata conversor como de 8 bits - se usará solo registro ADRESH como resultado de conversión 
;-  las entradas RA2 RA4 de  porta se trataran como entradas digitales mientras que  RA0/AN0 RA1/AN1 y RA3/AN3 serán entradas analógicas del conversor
	bcf	status,5 ;se posiciona en banco0


leercv2
	
	bsf		adcon0,2; comienza la conversión - hace 1 bit 2 de ADCON0 o sea go/done*
	



consu
	
	btfsc	adcon0,2; pregunta si bit2 de ADCON0 es   0 (cero) o sea si termino la conversión - salta si es cero
	
	goto	consu; si no termino sigue esperando
	movf	adresh,0; carga registro ADRESH (resultado de la conversión) en w


;porque el contenido de w fue alterado al amplificar
	movwf	leido; carga en registro  leido el valor de la conversión



;detección de  bajo escala - hace  digitos spl instantaneo igual a ( -- )
;esto se basa en que si leido es menor o igual a 2 no se muestre numeros sino (--)
;leido igual a 3 sera considerado 50dB spl

	movlw	d'2'; carga decimal 2 en w
	subwf	leido,0; resta decimal 2 a leido
	btfss	status,0; verifca bit de carry- si es 1 (leido mayor a 2) salta siguiente instrucción
	bsf	bandera,3; hace 1 el bit 3 de bandera para indicar por debajo de escala - spl instantaneo (---)
	movlw	d'2'; carga decimal 2 en w
	addwf	leido,1; restauro leido al que le habia restado 2

;Fin detección de  bajo escala - mensaje LOW




	

	return

;----Fin Subrutina (leercv) leer el conversor---------------------

;Subrutina promednp --hace el promedio de sucesivas lecturas - lo devuelve por leido pero lo acumulado queda en aux2
;ADVERTENCIA: no es igual a la subrutina con el mismo nombre de versiones anteriores

;aux2 registro auxiliar usado como acumulador de suma del promedio
;promedio registro donde se almacena el resultado del promedio -  al terminar la subrutina para luego cargarlo en leido antes de return



promednp
	

	movf	leido2,0; carga leido en w
	
	addwf	aux2,1; suma acumulando en aux2

	btfsc	status,0; verifica carry de la operación anterior, el cual será 1 si hubo overflow en el
;registro aux2  - la instrucción verifica el bit 0 de status - la instrucción dice salta la próxima
;instrucción si es  0 (cero)

	goto 	overaux2

	incf	np,1; incrementa el divisor del promedio


	btfsc	status,0;  verifica carry de la operación anterior, el cual será 1 si hubo overflow en el registro np - la instrucción verifica el bit 0 de status -  dice salta la próxima instrucción si es  0 (cero)

	goto	overnp

	goto promediar; salta a promediara si no hubo overflow ni de aux2 ni de np

overaux2
	subwf	aux2,1; resta la ultima suma que provocó overflow en aux2

	bsf	bandera,0; hace 1 el bit 0 del registro bandera - indicando así que hubo overflow

		goto promediar

overnp
	decf	np,1; decrementa np - hubo overflow en np
	subwf	aux2,1; resta la ultima suma ya que no la puedo contar - hubo overflow en np

	goto promediar


;comienza el calculo del promedio

promediar
	clrf	aux
	clrf	promedio
	movf	aux2,0; carga aux2 en w
	movwf	aux; carga w en aux - se pasó el contenido de aux2 a aux
	
	movf	np,0; carga  np en w
restnp
	subwf	aux,1; resto np a aux y lo guardo en aux (aux es un registro auxiliar para operar localmente 
	btfss	status,0;  verifica el carry (el bit 1 de status)la instruccion dice salta intrucción
;siguiente si es 1
	goto	finpro; si el carry es 0 deja de restar 
	incf	promedio,1; si el carry es 1 incrementa promedio 
	goto	restnp; volverá a restar np a aux
finpro
	
	
	movf	promedio,0; carga promedio en w
	movwf	leido; carga w en leido - se pasó el contenido de promedio a leido

	btfss	bandera,0; prueba si hay 1 en el bit 0 de bandera - o sea si ocurrió algún overflow - si hay 1 salta la siguiente instrucción

	return
	
	movf	leido2,0; carga leido2  en w

	movwf	aux2; carga w wn aux2 -  o sea está guardando leido2 (última lectura) en aux2

	clrf	np; limpia np
	incf	np,1; cuenta 1 en np porque ya tiene un valor acumulado (el último) aux2

	return

;----Fin Subrutina promednp --------------------------


;----Subrutina de conversión a db------------------------

;Toma leido y lo transforma mediante una tabla (situada entre posicion -registros ;generales- 39h y 66h ) y el uso de direccionamiento indirecto --(fsr)-
;La lógica es: toma contenido de leido- descarta los 2 bits LSB - hace desplazamiento de leido hacia la derecha (2 bits) -
;- suma 39h a contenido de leido  para caer dentro de la zona de la tabla-
;carga este resultado a fsr - siendo esta la posición de memoria que contiene el 
;valor transformado- se carga en leido antes de salir de la subrutina ---

covdb
	movf	leido,0; carga en w el contenido leido 
	andlw	b'11111100'; and entre w (que contiene leido) y 11111100 para enmascar y descartar los 2 bits LSB

	movwf	leido; se carga leido con resultado operación anterior

	rrf	leido,1; hace otro desplazamiento en 1 bit hacia la derecha del registro leido
	rrf	leido,1; hace desplazamiento en 1 bit hacia la derecha del registro leido
	movlw	39h; carga literal 39h  en w
	addwf	leido,0; suma 39h (contenido en w) y leido - para desplazar a posición de memoria correspondiente al valor en db de leido- lo guarda en w
	movwf	fsr; carga en fsr (registro de direccionamiento indirecto) el valor al que debe apuntar y que estaba contenido en w

	movf	indf,0; carga en w el contenido de la posición de memoria al que apuntaba fsr

	movwf	leido; carga en leido el resultado de la conversión
	return

;--Fin subrutina de conversión a db------------------------------------


;---------Subrutina temperatura-----------

temperatura

	bcf		adcon0,4; hace 0 el bit 4 de adcon0 -junto con la proxima instrucción selecciona AN1
	bsf		adcon0,3; hace 1 el bit 3 de adcon0 seleccionando asi el canal AN1 del conversor - donde se leerá la temperatura
	call	retardo; 
	call	leercv2; se realiza la lectura del conversor - sale guardado en registro leido
;corrección del valor de temperatura
	;decf	leido,1
	;decf	leido,1
	;decf	leido,1; acaba de restar 3 grados a lectura de temperatura
;fin de corrección de temperatura


	movf	leido,0; carga contenido de leido a w
	movwf	memtemp; carga contenido de leido en memtemp que previamente se cargo en w
;memorizando en este registro el valor de la temperatura




	bcf		adcon0,3; hace cero el bit3 de adcon0 dejando así seleccionado la entrada AN0 del conversor- considero no hacer retardo porque no lo usaré inmediatamente
	return

;---------Fín subrutina temperatura-----------

;---------Subrutina  tecla1--------------------

tecla1
	btfss	porta,2; prueba si bit (RA2) es 1 - si lo es salta siguiente instrucción 
;- RA2 como entrada digital detecta si se presiono la tecla de escala - es 1  si se presionó
; y 0 si no se presionó la tecla 1
	
	goto	notecla1
	movlw	b'00000010'; carga (00000010) en w
	xorwf	bandera,1; hace XOR entre registro bandera y contenido de w - esto se hace para complementar el bit 1 de bandera
	call	dingdong; señal audible para avisar que se presionó la tecla de cambio de escala

notecla1
	return
;---------Fin subrutina  tecla1--------------------

;----------Subrutina tecla2 programacion temperatura----
tecla2

	btfss	porta,4; prueba si bit (RA4) es 1 - si lo es salta siguiente instrucción 
;- RA4 como entrada digital detecta si se presiono la tecla 2 de programar alarma 
;- es 1  si se presionó y 0 si no se presionó la tecla 2
	return
;sección de la alarma
	call	escribealarma; escribe mensaje Alarma
	call	beep
	call	beep
	call	dingdong
	btfss	bandera,2; prueba si bit2 de bandera es 1 - si lo es salta siguiente instrucción -  bit2=1  alarma activada
	clrf	alarm; asi la temperatura de alarma inicialmente es cero si nunca se programó todavía

selecionando	
	movf	alarm,0; carga contenido de alarma a w
	movwf	leido; carga contenido de alarma en leido que previamente se cargo en w


	call	decimal; va a convertir el contenido de leido a decimal y lo carga en registros centena-decena-unidad
;(aqui leido ya no contiene el valor original)

	movlw	090h; carga en w  dirección de centenas-LO MANDO FUERA DEL DISPLAY para evitar mostrar centenas
	movwf	dcent; carga registro dcent con dirección
	movlw	08Dh; carga en w  dirección de decenas
	movwf	ddece; carga registro ddece con dirección
	movlw	08Eh; carga en w  dirección de unidades
	movwf	dunid; carga registro dunid con dirección
	call	mostrar; muestra contenido de centena-decena-unidad en el display- temperatura
;muestra cero temperatura la primera vez y luego el valor incrementado
	
	btfsc	porta,4; prueba si bit (RA4) es 0 - si lo es salta siguiente instrucción 
;- RA2 como entrada digital detecta si se presiono la tecla 2 que ahora sirve para salir de 
;programar alarma - es 1  si se presionó (sale) y 0 si no se presionó la tecla 2 (no sale)
	goto	saletecla2; se va a la salida

	btfss	porta,2; prueba si bit (RA2) es 1 - si lo es salta siguiente instrucción 
;- RA2 como entrada digital detecta si se presiono la tecla1 la cual incrementa la temperatura 
; de alarma ahora - fuera de esta subrutina es la tecla de escala - es 1  si se presionó y
; 0 si no se presionó la tecla 1
	goto	selecionando
	incf	alarm,1; incrementa temperatura de alarma
	call	beep; pitido de avance- cada pitido incrementa temperatura de alarma

	goto	selecionando

saletecla2
	bsf	bandera,2; hace 1 el bit 2 de bandera para indicar alarma activada
	
	movlw	8Ah; 
	call instruc
	movlw	"*"; 
	call	escrib

	
	call	midiendo
	
	call	sonisalida

nuncatecla2

	return

;----------Fin subrutina tecla2 programacion temperatura----

;-------Subrutina ver si es la temperatura de alarma------
;Incluye activar sonidos de alarma------------------------
tempalarm

	movf	memtemp,0; carga memtemp en w- contiene el valor de temperatura
	xorwf	alarm,0 ;lo guardo en w porque no me interesa guardarlo en otro lado
	btfss	status,2 ;junto con la intruccion anterior ve si alarm (alarm contiene temperatura de alarma)
; es igual a memtemp- si bit 2 de status es 1 es porque son iguales- 
;la instrucción actual dice salta si es 0- si es 1 suena la alarma y no se detiene hasta presionar
; tecla2 - en ese caso se apaga y se desactiva-
	goto	saletempalarm
	
siguesonando	
	bsf		portb,2; coloca en estado alto el pin 2 (RB2) del puerto b
	call	escribealarma; escribe mensaje Alarma
	call	beep
	call	dingdong
	call	dingdong1
	btfss	porta,4; prueba si bit (RA4) es 1 - si lo es salta siguiente instrucción 
;- RA2 como entrada digital detecta si se presiono la tecla 2 que ahora sirve para salir de 
;tempalarm - es 1  si se presionó (sale) y 0 si no se presionó la tecla 2 (no sale)

	goto	siguesonando
	clrf	alarm
	bcf		portb,2; asegura bit 2 de portb en 0
	bcf	bandera,2; hace 0 el bit 2 de bandera para indicar alarma desactivada

	movlw	8Ah; 
	call instruc
	movlw	" "; 
	call	escrib

saletempalarm
	call	midiendo; escribe mensaje Midiendo

	
	return


;-------Fin subrutina ver si es la temperatura de alarma------



;---------Subrutina  cambio de escala------------

escala
	btfss	bandera,1; prueba si bit1 de bandera es 1 - si lo es salta siguiente instrucción -  bit1=1  escala H - bit1=0  escala L
	goto	escabaja
escaalta
	bsf	adcon0,3
	bsf	adcon0,4; se seleccionó canal 3 del conversor -RA3/AN3

	movlw	0C9h
	call	instruc
	movlw	"H"
	call	escrib; se escribe H en la posición C9h del LCD

	goto	salescala
escabaja
	
	bcf	adcon0,3
	bcf	adcon0,4; se seleccionó canal 0 del conversor -RA0/AN0

	movlw	0C9h
	call	instruc
	movlw	"L"
	call	escrib; se escribe L en la posición C9h del LCD

salescala
	return

;---------Fin subrutina  cambio de escala------------

;-------------Subrutina tono1--------------------------

;subrutina tono1  -antes de llamarla se debe cargar el regist frecu (1 a 80)  y el registro durac (de 0 a 255)-
;el valor de frecu  1 (agudos) a 80 (graves) determina la frecuencia.
; el valor de durac (hasta 255) determina la duración. NO es igual para todas las frecuencias

tono1
	clrf	ts1  
	clrf	ts2
	clrf	ts3
rt1
	incf	ts1,1
rt2
	incf	ts2,1
rt3
	call	periodo
	incf	ts3,1
	movf	durac,0
	xorwf	ts3,0 ;lo guardo en w porque no me interesa guardarlo en otro lado
	btfss	status,2 ;junto con la intruccion anterior ve si ts3 es igual a durac-
	goto	rt3
	clrf	ts3
	movf	durac,0
	xorwf	ts2,0 ;lo guardo en w porque no me interesa guardarlo en otro lado
	btfss	status,2 ;junto con la intruccion anterior ve si ts2 es igual a durac-
	goto	rt2
	clrf	ts2
	movf	durac,0
	xorwf	ts1,0 ;lo guardo en w porque no me interesa guardarlo en otro lado
	btfss	status,2 ;junto con la intruccion anterior ve si ts1 es igual a durac-
	goto	rt1
	return

;------Subrutina  periodo ( para subrutina tono1---

periodo
	clrf	ctperi
bajo
	bcf	portb,3  ;semiciclo bajo (cero) de la onda cuadrada.Esta intrucc selec salida sonora.
	call	semiciclo ;determina la duracion de este semiciclo
	incf	ctperi,1
	movf	frecu,0
	xorwf	ctperi,0 ;lo guardo en w porque no me interesa guardarlo en ctperi
	btfss	status,2
	goto	bajo
	clrf	ctperi
alto	
	bsf	portb,3   ;semiciclo alto (uno) de la onda cuadrada.Esta intrucc selec salida sonora.
	call	semiciclo
	incf	ctperi,1
	movf	frecu,0
	xorwf	ctperi,0 ;lo guardo en w porque no me interesa guardarlo en ctperi
	btfss	status,2
	goto	alto
	return

;----Subrutina semiciclo (para subrutina tono1)-----

semiciclo
	clrf	tf1
	clrf	tf2
retf1
	incf	tf1,1
retf2
	incf	tf2,1
	btfss	tf2,1 ;determina la duracion del semiciclo T/2 (controla la frec)
	goto	retf2 	
	clrf	tf2
	btfss	tf1,1 ;determina la duracion del semiciclo T/2 (controla la frec)
	goto	retf1
	return

;-------------Fin subrutina tono1------------------


;----------------------------------------------------------------------------
;subrutina ding dong

dingdong
	movlw	d'10' 
	movwf	frecu 
	movlw	d'6' 
	movwf	durac 
	call	tono1 
	movlw	d'6' 
	movwf	frecu 
	movlw	d'6' 
	movwf	durac 
	call	tono1 	
	return
;---------------------------------------------------------------------
;subrutina beep

beep
	
	movlw	d'10' 
	movwf	frecu 
	movlw	d'5' 
	movwf	durac 
	call	tono1 	
	return

;---------------------------------------------------------------------

;---------------------------------------------------------------------
;subrutina beep2

beep2
	
	movlw	d'14' 
	movwf	frecu 
	movlw	d'10' 
	movwf	durac 
	call	tono1 	
	return

;---------------------------------------------------------------------


;---------------------------------------------------------------------
;subrutina beep3

beep3
	
	movlw	d'6' 
	movwf	frecu 
	movlw	d'6' 
	movwf	durac 
	call	tono1 	
	return

;---------------------------------------------------------------------



;---------------------------------------------------------------------
;subrutina ding dong1

dingdong1
	movlw	d'6' 
	movwf	frecu 
	movlw	d'6' 
	movwf	durac 
	call	tono1 
	movlw	d'10' 
	movwf	frecu 
	movlw	d'6' 
	movwf	durac 
	call	tono1 	
	return
;---------------------------------------------------------------------


;------Subrutina escribe Midiendo-----------------------------------

midiendo	
	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc

	movlw	"M"; este es el primer carcater del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	"i"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	"d"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	"i"; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"e"; 
	call	escrib

	movlw	85h; 
	call instruc
	movlw	"n"; 
	call	escrib

	movlw	86h; 
	call instruc
	movlw	"d"; 
	call	escrib

	movlw	87h; 
	call instruc
	movlw	"o"; 
	call	escrib

	movlw	88h; 
	call instruc
	movlw	"."; 
	call	escrib

	movlw	89h; 
	call instruc
	movlw	" "; 
	call	escrib

	return

;------Fin subrutina escribe Midiendo-----------------------------------
;------Subrutina escribe Alarma-----------------------------------
escribealarma	
	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc

	movlw	"*"; este es el primer carcater del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	"A"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	"L"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	"A"; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"R"; 
	call	escrib

	movlw	85h; 
	call instruc
	movlw	"M"; 
	call	escrib

	movlw	86h; 
	call instruc
	movlw	"A"; 
	call	escrib

	movlw	87h; 
	call instruc
	movlw	"*"; 
	call	escrib

	movlw	88h; 
	call instruc
	movlw	" "; 
	call	escrib

	movlw	89h; 
	call instruc
	movlw	" "; 
	call	escrib

	return

;------Fin subrutina escribe Alarma-----------------------------------

;---Subrutina copyright-----------------------------------------------

copyright
	movlw	01h
	call	instruc; borrar pantalla
	

	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc

	movlw	"("; este es el primer caracter del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	"c"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	")"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	" "; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"D"; 
	call	escrib

	movlw	85h; 
	call instruc
	movlw	"J"; 
	call	escrib

	movlw	86h; 
	call instruc
	movlw	"B"; 
	call	escrib

	movlw	87h; 
	call instruc
	movlw	"-"; 
	call	escrib

	movlw	88h; 
	call instruc
	movlw	"2"; 
	call	escrib

	movlw	89h; 
	call instruc
	movlw	"0"; 
	call	escrib


	movlw	8Ah; 
	call instruc
	movlw	"0"; 
	call	escrib

	movlw	8Bh; 
	call instruc
	movlw	"7"; 
	call	escrib


	call	dingdong
	call	dingdong1
	call	beep2
	call	dingdong
	call	dingdong1


	call	espera
	call	espera
	call	espera
	call	espera
	
	return


;---Fin subrutina copyright-----------------------------------------------


;---Subrutina vario - escritura de  -  t=  - c -  SPL- dB - Pr------------

varios

	movlw	8Bh; 
	call instruc
	movlw	"t"; 
	call	escrib

	movlw	8Ch; 
	call instruc
	movlw	"="; 
	call	escrib
	
	movlw	8Fh; 
	call instruc
	movlw	"c"; 
	call	escrib

	movlw	0C0h; 
	call instruc
	movlw	"S"; 
	call	escrib

	movlw	0C1h; 
	call instruc
	movlw	"p"; 
	call	escrib

	movlw	0C2h; 
	call instruc
	movlw	"l"; 
	call	escrib

	movlw	0C6h; 
	call instruc
	movlw	"d"; 
	call	escrib

	movlw	0C7h; 
	call instruc
	movlw	"B"; 
	call	escrib

	
	movlw	0CBh; 
	call instruc
	movlw	"P"; 
	call	escrib

	movlw	0CCh; 
	call instruc
	movlw	"r"; 
	call	escrib
	return
;---Fin subrutina escritura de mensaje  -  t=  - c -  SPL- dB - Pr-----------


;------Subrutina escribe Calibrando---------------------------

calibrando	
	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc

	movlw	"C"; este es el primer caracter del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	"a"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	"l"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	"i"; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"b"; 
	call	escrib

	movlw	85h; 
	call instruc
	movlw	"r"; 
	call	escrib

	movlw	86h; 
	call instruc
	movlw	"a"; 
	call	escrib

	movlw	87h; 
	call instruc
	movlw	"n"; 
	call	escrib

	movlw	88h; 
	call instruc
	movlw	"d"; 
	call	escrib

	movlw	89h; 
	call instruc
	movlw	"o"; 
	call	escrib

	return

;------Fin subrutina escribe Calibrando-------------------------------


;-----Subrutina calibra--------------
;el conversor A/D tiene seleccionado en este momento la entrada AN0 o sea está en escala H


calibra

	movlw	01h; carga w con literal 01h
;la intrucc asociada dice: BORRAR PANTALLA
	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

	call	calibrando; escribe mensaje calibrando

	call	varios

scalibra
	
	
	call	espera
	call	espera
	call	espera
	call	espera
	call	espera
	call	espera
	

	call	beep3; emite sonido que recibirá por aire el MIC
	call	leercv2; realiza la lectura de la salida del LM386 en la escala alta
	call	splinstantaneo
	
	call	beep3; emite sonido que recibirá por aire el MIC
	call	leercv2; realiza la lectura de la salida del LM386 en la escala alta


	
	movlw	d'180'; carga en w el literal decimal 180(sonometro gabinete)


	subwf	leido,0; resta w (que ahora contiene 180) a leido
	
	btfss	status,0; si carry=1 es porque leido es mayor que xx(SPL=67) - si carry=0 entonces leido es menor o igual a xx
;la instrucción dice si carry=1 entonces salta instrucción siguiente (leido es mayor que xx)
;lo cual indicaría que el sistema esta listo para medir
;si carry=0 entonces no salta siguiente instrucción (leido es menor o igual que 30 (SPL=67))sigue calibrando



	goto	scalibra; sigue calibrando
	
	call	sonisalida
	call	sonisalida
	call	midiendo
	return

;-----Fin subrutina calibra-----------


;--------Subrutina sonisalida------------------------------------

sonisalida

	call	dingdong1
	call	beep
	call	beep
	call	beep
	return

;--------Fin subrutina sonisalida------------------------------------

;--------Subrutina splinstantaneo------------------------------------

splinstantaneo
	call	covdb; llama a subrutina que hace pasaje a db

	call	decimal; va a convertir el contenido de leido a decimal y lo carga en registros centena-decena-unidad
;(aqui leido ya no contiene el valor original)

	movlw	0C3h; carga en w  dirección de centenas
	movwf	dcent; carga registro dcent con dirección
	movlw	0C4h; carga en w  dirección de decenas
	movwf	ddece; carga registro ddece con dirección
	movlw	0C5h; carga en w  dirección de unidades
	movwf	dunid; carga registro dunid con dirección



	btfsc	bandera,3; prueba si bit3 de bandera es 0-si lo es salta siguiente instrucción
;el bit 3 de bandera valiendo 1 implica escala por debajo de 50 (--)dB
	call	escbajo	
	btfss	bandera,3; prueba si bit3 de bandera es 1-si lo es salta siguiente instrucción
	call	mostrar; muestra contenido de centena-decena-unidad en el display- muestra SPL instantáneo
	bcf		bandera,3; hace 0 el bit 3 de bandera
	return

;--------Fin subrutina splinstantaneo------------------------------------


;-------Subrutina LOW-------- no se muestra valores bajos (menos de 50) instantaneos
escbajo

	movlw	0C3h; 
	call instruc
	movlw	" "; 
	call	escrib

	movlw	0C4h; 
	call instruc
	movlw	"-"; 
	call	escrib

	movlw	0C5h; 
	call instruc
	movlw	"-"; 
	call	escrib
	return

;-------Fin subrutina LOW-----------------------



;------Subrutina menu-------
; sale de esta subrutina quedando almacenado la opción elegida en registro opc
;Registros necesarios a declarar para uso de esta subrutina: opc

menu
	bcf	portb,2; asegura que el pin de salida RB2 sea 0
	clrf	opc; limpia registro opc
	movlw	01h; codigo para borrar pantalla
	call	listamenu; se escribe el menu en pantalla

siguemenu
	movf	opc,0; carga valor de opc en w
	movwf	unidad; carga contenido w en registro unidad
	movlw	8Fh; carga literal 8Fh en w
	movwf	dunid; carga en registro dunid la direccion del LCD (8Fh) en donde aparecerá el número de opción
	call	mostrarunidad; llama a subrutina que esta dentro de subrutina mostrar
	btfsc	porta,4; detecta si se presionó tecla2 (RA4) o sea sale del menu si es 1 ya la intruccion dice salte proxima instrucción si es cero
	goto	salemenu
	btfss	porta,2; prueba si bit RA2 (si se presionó tecla1)es 1- incrementará registro opc si es así
	goto	siguemenu
	incf	opc,1; incrementa registro opc guarda en opc
	call	beep
	movf	opc,0; carga opc en w
	xorlw	d'2'; hace xor entre decimal  y contenido de w
	btfss	status,2; junto con la instrucción anterior verifica si registro opc=2 - (verifica bit z de status) - si no lo es z de status es cero, por lo tanto salta la siguiente instrucción
	goto siguemenu
	clrf	opc
	goto siguemenu
salemenu
	return


;------------Fin subrutina menu------------


;--------Subrutina timer----------------------------
;Registros necesarios para esta subrutina segund-minut

timer

	movlw	01h
	call	instruc; borrar pantalla
	call	esctimer; escribe en pantalla TIMER -min-seg
	clrf	segund
	clrf	minut
	call	mostminseg


sigueseg
	btfss	porta,2; prueba si se presionó la tecla 1 (RA2) utilizada para incrementar segundos en este punto
	goto	sigueseg2
	incf	segund,1; incrementa segundos
	call	masde60
	call	mostminseg
	call	beep

sigueseg2

	btfsc	porta,4; prueba si se presionó tecla 2 (RA4)- pasa a minutos- 1 si se presionó - 0 si no se presionó
	goto	sigueminut
	goto	sigueseg

sigueminut

	call	dingdong
	call	dingdong1
	call	dingdong
sigueminut3
	btfss	porta,2; prueba si se presionó la tecla 1 (RA2) utilizada para incrementar minutos en este punto
	goto	sigueminut2
	incf	minut,1; incrementa minutos
	call	mostminseg
	call	beep
sigueminut2
	btfsc	porta,4; prueba si se presionó la tecla 2 (RA4)-salir de programacion-en este punto
	goto	contando
	goto	sigueminut3



contando
	call	sonisalida


contando2	
;---------------------------------------------------------------	
	movlw	87h; 
	call instruc
	movlw	"*"; 
	call	escrib

	call	tcalib

	movlw	87h; 
	call instruc
	movlw	" "; 
	call	escrib
	call	tcalib

;--------------------------------------------------------------------------
	
	
	call	mostminseg
	decf	segund,1
	call	menosde0


	btfss	porta,2; prueba si se presionó la tecla 1 (RA2)-conteo mudo  o no mudo-en este punto
	goto	nomudo
	movlw	b'00010000'; carga (00010000) en w
	xorwf	bandera,1; hace XOR entre registro bandera y contenido de w - esto se hace para complementar el bit 4 de bandera

nomudo
	btfss	bandera,4; si el bit 4 de bandera esta en 1 salta siguiente instrucción- conteo mudo-
	
	
	call	beep

	btfsc	bandera,4; si el bit 4 de bandera esta en 1 salta siguiente instrucción-retardo para compensar mudo
	call	espera; espera para compensar el tiempo de la subrutina beep cuando esta mudo


	movf	segund,0; carga segund en w
	iorwf	minut,0; hace OR entre w y minut-guarda en w para no guardar en otro lugar-
	btfss	status,2; salta si bit z=	1
;intrucción si es 0 o sea minut=0 y segund=0- terminó la cuenta

	goto	contando2
sonando
	bsf		portb,2; coloca en estado alto el pin 2 (RB2) del puerto b
	call	mostminseg
	call	escribealarma
	call	dingdong1
	call	beep2
	call	dingdong1
	btfss	porta,4; sale de sonando solo si se presiona RA4 - tecla 2-
	goto	sonando
	return
;despues de esta subrutina se debe llamar al menu con goto menu
;--------Fin de subrutina timer-----------------------

;-----Subrutina masde60------------

masde60
	movf	segund,0; carga segund en w
	xorlw	d'60'; XOR entre decimal 60 y w
	btfss	status,2; salta si bit z=	1
	return
	clrf	segund
	return
;-----Fin subrutina masde60------------

;-----Subrutina menosde0------------

menosde0

	movf	segund,0; carga segund en w
	xorlw	d'255'; XOR entre decimal 255 y w
	btfss	status,2; salta siguiente instrucción si bit z=1
	return
	movlw	d'59'; carga decimal 59 en w
	movwf	segund; carga w en segund
	decf	minut,1; decrementa minut
	return

;-----Fin subrutina menosde0------------

;-----Subrutina mostminseg-----------
;Trabaja con 2 registros que contienen minut (minutos) y segund (segundos) cargados en otra subrutina

mostminseg
	movf	segund,0; carga contenido de registro segund en w
	movwf	leido; carga contenido de w a registro leido
	call	decimal; convierte en decimal contenido de leido y lo carga en registros centena-decena-unidad
	
	movlw	090h
	movwf	dcent

	movlw	0CBh; direccion del LCD  a visualizar segundos-decenas
	movwf	ddece
	movlw	0CCh;  direccion del LCD  a visualizar segundos-unidades
	movwf	dunid
	call	mostrar; muestra segundos en LCD
	movf	minut,0; va a mostrar los minutos-carga contenido del registro minut en w
	movwf	leido; carga contenido de w a registro leido
	call	decimal
	movlw	0C6h
	movwf	dcent
	movlw	0C7h
	movwf	ddece
	movlw	0C8h
	movwf	dunid
	call	mostrar
	return
;-----Fin subrutina mostminseg---------------

;--------Subrutina de calibración de timer-------

tcalib

	movlw	09Ch; carga literal 0ffh en w
	movwf	tempo1; mueve contenido de w a tempo1
tcalib2	
	call	retardo
	decfsz	tempo1,1; decrementa tempo1 y guarda resultado en tempo1- salta la intruccion siguiente si temp5 es igual a cero
	goto	tcalib2
	return

;--------Fin subrutina de calibración de timer-------


;---Subrutina listamenu---------------------

listamenu

	movlw	01h
	call	instruc; borrar pantalla

	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc

	movlw	"0"; este es el primer caracter del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	")"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	"S"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	"+"; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"T"; 
	call	escrib

	movlw	86h; 
	call instruc
	movlw	"1"; 
	call	escrib

	movlw	87h; 
	call instruc
	movlw	")"; 
	call	escrib

	movlw	88h; 
	call instruc
	movlw	"T"; 
	call	escrib

	movlw	89h; 
	call instruc
	movlw	"m"; 
	call	escrib

	movlw	8Eh; 
	call instruc
	movlw	">"; 
	call	escrib

	return

;---------Fin subrutina listamenu------------

;---Subrutina esctimer---------------------

esctimer

	movlw	01h
	call	instruc; borrar pantalla

	movlw	80h; se indica posicion de memoria del LCD en que quiere escibir el dato

	call instruc
	call	espera


	movlw	"T"; este es el primer caracter del mensaje - al estar entre comillas se le indica al compilador que el dato requerido s el valo ASCII del caracter

	call	escrib


;repito con el resto de los caracteres
	
	movlw	81h; 
	call instruc
	movlw	"I"; 
	call	escrib

	movlw	82h; 
	call instruc
	movlw	"M"; 
	call	escrib

	movlw	83h; 
	call instruc
	movlw	"E"; 
	call	escrib

	movlw	84h; 
	call instruc
	movlw	"R"; 
	call	escrib


	movlw	87h; 
	call instruc
	movlw	"p"; 
	call	escrib



	movlw	0C9h; 
	call instruc
	movlw	"m"; 
	call	escrib

	movlw	0CDh; 
	call instruc
	movlw	"s"; 
	call	escrib

	return

;---------Fin subrutina esctimer------------

;--------FIN SUBRUTINAS--------

;------INICIO programa principal-----

inicio
	

	bsf	status,5 ;se posiciona en banco1
	
	movlw	00h
	movwf	trisb; en este caso seteo todo el portb como salida 
; recordar que 0 es salida y 1 es entrada al definir puertos
	
	movlw	b'0011111'
	
	movwf	trisa; se establece que los pines RA2 y RA4 de  porta se trataran como entradas digitales 
;- mientras que  RA0/AN0 RA1/AN1 y RA3/AN3 serán entradas que luego seran definidas 
;como entradas analógicas del conversor

	bcf	status,5	; se posiciona en banco 0
	
;-------inicializacion del LCD--------
	movlw	02h; carga w con literal 02h RB1=1 o sea E=1 habilito LCD

	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

;------------otra instruccion-----------
	movlw	28h; carga w con literal 28h
;la intrucc asociada dice: interfase de datos de 4 bits y se va a usar 2 lineas - corresponde a la intruccion ACTIVAR FUNCION

	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

;------------otra instruccion-----------
	movlw	06h; carga w con literal 06h
;la intrucc asociada dice: dato fijo en pantalla- corresponde a la intruccion SELECCIONAR MODO

	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

;------------otra instruccion-----------

	movlw	0Ch; carga w con literal 0Ch
;la intrucc asociada dice: encienda la pantalla y desactive el cursor- corresponde a la intruccion ENCENDER O APAGAR PANTALLA

	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

;------------otra instruccion-----------
	movlw	01h; carga w con literal 01h
;la intrucc asociada dice: BORRAR PANTALLA

	call instruc;   enviaremos este valor al portb y por lo tanto al LCD

;----fin inicializacion del LCD-----

	call	copyright
	;call	midiendo; escribe mensaje midiendo
	call	espera
	;call	varios
;---Se arma (cargandose en los registros reservados) la tabla de conversión--
;se cargan valores -de 50db a 105db--------------------------

tabla
	movlw	d'50'
	movwf	d1
	movlw	d'51'
	movwf	d2
	movlw	d'52'
	movwf	d3
	movlw	d'53'
	movwf	d4
	movlw	d'55'
	movwf	d5
	movlw	d'56'
	movwf	d6
	movlw	d'57'
	movwf	d7
	movlw	d'57'
	movwf	d8
	movlw	d'58'
	movwf	d9
	movlw	d'59'
	movwf	d10
	movlw	d'60'
	movwf	d11
	movlw	d'61'
	movwf	d12
	movlw	d'62'
	movwf	d13
	movlw	d'63'
	movwf	d14
	movlw	d'63'
	movwf	d15
	movlw	d'64'
	movwf	d16
	movlw	d'64'
	movwf	d17
	movlw	d'64'
	movwf	d18
	movlw	d'64'
	movwf	d19	
	movlw	d'65'
	movwf	d20
	movlw	d'65'
	movwf	d21
	movlw	d'65'
	movwf	d22
	movlw	d'65'
	movwf	d23
	movlw	d'65'
	movwf	d24
	movlw	d'65'
	movwf	d25
	movlw	d'65'
	movwf	d26
	movlw	d'66'
	movwf	d27
	movlw	d'66'
	movwf	d28
	movlw	d'66'
	movwf	d29
	movlw	d'66'
	movwf	d30
	movlw	d'66'
	movwf	d31
	movlw	d'67'
	movwf	d32
	movlw	d'67'
	movwf	d33
	movlw	d'67'
	movwf	d34
	movlw	d'67'
	movwf	d35
	movlw	d'67'
	movwf	d36
	movlw	d'67'
	movwf	d37
	movlw	d'67'
	movwf	d38
	movlw	d'68'
	movwf	d39
	movlw	d'68'
	movwf	d40
	movlw	d'68'
	movwf	d41
	movlw	d'68'
	movwf	d42
	movlw	d'68'
	movwf	d43
	movlw	d'68'
	movwf	d44
	movlw	d'68'
	movwf	d45
	movlw	d'69'
	movwf	d46
	movlw	d'69'
	movwf	d47
	movlw	d'69'
	movwf	d48
	movlw	d'69'
	movwf	d49
	movlw	d'69'
	movwf	d50
	movlw	d'69'
	movwf	d51
	movlw	d'70'
	movwf	d52
	movlw	d'70'
	movwf	d53
	movlw	d'70'
	movwf	d54
	movlw	d'71'
	movwf	d55
	movlw	d'72'
	movwf	d56
	movlw	d'73'
	movwf	d57
	movlw	d'74'
	movwf	d58
	movlw	d'97'
	movwf	d59
	movlw	d'98'
	movwf	d60
	movlw	d'99'
	movwf	d61
	movlw	d'100'
	movwf	d62
	movlw	d'101'
	movwf	d63
	movlw	d'102'
	movwf	d64
	movlw	d'103'
	movwf	d65
	movlw	d'104'
	movwf	d66
	movlw	d'105'
	movwf	d67

;-----Fin carga de valores en la tabla -------------------------

	clrf	alarm; pone en cero registro de sonar alarma

;----bloque principal---


;primera lectura e inicializacion del conversor
	call	leercv; realiza lectura inicial de salida del LM386


	clrf	promedio
	clrf	aux2
	clrf	np
	bcf		portb,2; asegura bit 2 de portb en 0

eleccion
	call	menu
	
;---Rutina selectora------
;Pensada para opciones 0-1-2-3 estando disponibles en version 15 solo la 0 y1
	movf	opc,0; carga opc -registro que guarda la opcion elegida- en w 
	xorlw	d'0'; hace xor entre decimal 0 y w
	btfsc	status,2; salta siguiente instrucción si el bit 2 de status es 0 - o sea si no se eligio opcion0
	goto	opcion0; se eligio opcion0 (opcion normal)

	xorlw	d'1';
	btfsc	status,2; salta si no se eligio opcion1
	goto	opcion1; se eligio opcion1


;---------------fin rutina selectora----------------

;Comienza listado de opciones
;---------opción 1-----------------------------------
;La opción 1 corresponde a funcionamiento como timer
opcion1
	
	call	beep2
	call	beep
	
	call	timer

	call	sonisalida
	goto	eleccion

;---------Fin opción 1-----------------------------------


;---------opción 0-----------------------------------
;la opción 0 es la opcion normal- sonometro + termometro
opcion0
	call	calibra
	call	midiendo
	call	varios

medir	

	call	temperatura

;muestra de l valor de temperatura
	
	call	decimal; va a convertir el contenido de leido a decimal y lo carga en registros centena-decena-unidad
;(aqui leido ya no contiene el valor original)

	movlw	090h; carga en w  dirección de centenas-LO MANDO FUERA DEL DISPLAY para evitar mostrar centenas
	movwf	dcent; carga registro dcent con dirección
	movlw	08Dh; carga en w  dirección de decenas
	movwf	ddece; carga registro ddece con dirección
	movlw	08Eh; carga en w  dirección de unidades
	movwf	dunid; carga registro dunid con dirección

	call	mostrar; muestra contenido de centena-decena-unidad en el display- temperatura

;----- fin de medir y mostrar temperatura----

	call	tecla2; llama subrutina para verificar si se presionó la tecla de establecer alarma (RA4)

	btfsc	bandera,2; prueba si bit2 de bandera es 0-si lo es salta siguiente instrucción- bit2=1 alarma activada
	call	tempalarm


	call	tecla1; llama subrutina para verificar si se presionó la tecla de cambio de escala (RA2)

	

	call	escala; verifica la escala seleccionada- seteando la entrada del conversor a mostrar

	call	leercv2; realiza lectura de salida del LM386- queda guardada en leido

	movf	leido,0; carga leido en w

	movwf	leido2; guarda leido en leido2 para promediar sucesivamente


	call	splinstantaneo

	call	promednp; llama subrutina de promediar sucesivamente

	call	covdb; llama a subrutina que hace pasaje a db

	call	decimal; va a convertir el valor promedio que se encuentra almacenado en leido


	movlw	0CDh; carga en w  dirección de centenas
	movwf	dcent; carga registro dcent con dirección
	movlw	0CEh; carga en w  dirección de decenas
	movwf	ddece; carga registro ddece con dirección
	movlw	0CFh; carga en w  dirección de unidades
	movwf	dunid; carga registro dunid con dirección


	
	call	mostrar; va a mostrar en las posiciones prefijadas del LCD el valor promedio

		

	goto	medir


;---fin programa principal-----------


	end




    Source: geocities.com/ar/bolanosdj/circuitos_archivos

               ( geocities.com/ar/bolanosdj)                   ( geocities.com/ar)