;*************************************************************************************************************************************************
;
;  	PROGRAMA DE PRUEBA PARA LA TARJETA EVOLUPIC BOOTLOADER DE LA EMPRESA PUNTO FLOTANTE, S.A. QUE GENERA NOTAS MUSICALES MIENTRAS SE OPRIME EL 
;														BOTON DEL TECLADO.
;						CÓDIGO ESCRITO POR MOISÉS RAFAEL GUTIÉRREZ DAMIÁN BAJO ENCARGO DE PUNTO FLOTANTE, S.A.
;
;*************************************************************************************************************************************************

;	CABECERA	**********************************************************************************************************************************

		LIST	P=16F88			; MICROCONTROLADOR A USAR
		INCLUDE	<P16F88.INC>	; LLAMADA A CABECERA

;	CONSTANTES, DECLARACIONES Y MACROS	**********************************************************************************************************

#DEFINE		BOCINA			PORTA,3

		CBLOCK	0x20			
		BARRIDO					; USADA PARA BARRER LAS COLUMNAS.
		SEMICICLO				; PARA IDENTIFICAR EL SEMICICLO
		VALOR					; TECLA OPRIMIDA.
		R_ContA					; Contadores para los retardos.
		R_ContB
		ENDC

TECLADO MACRO	
		BANKSEL	TRISB
		MOVLW	0xF0			; RB0 - RB3 = SALIDAS, RB4 - RB7 = ENTRADAS
		MOVWF	TRISB			
		BCF		OPTION_REG,NOT_RBPU	; HABILITAMOS LAS RESISTENCIAS DE PULL-UP
		BANKSEL	PORTB
		ENDM

;	CABECERA	*********************************************************************************************************************************

		ORG		0				; INICIO DEL PROGRAMA EN LA PRIMERA LOCACIÓN DE MEMORIA
		CLRF	PCLATH			; SOLICITADO POR EL BOOTLOADER.
		GOTO	INICIO			; DIRECCIONAMOS AL "INICIO" DEL BLOQUE DE INSTRUCCIONES
		ORG		3		

INICIO
		
;	PRINCIPAL	*********************************************************************************************************************************


;	CONFIGURAMOS EL MICROCONTROLADOR E INICIALIZAMOS VARIABLES	*********************************************************************************
		
		CLRF	SEMICICLO
		BANKSEL	TRISA			; CONFIGURAMOS EL PUERTO A
		CLRF	TRISA			; PUERTO A COMO SALIDAS
		CLRF	ANSEL			; DESHABILITAMOS EL CAD.
		MOVLW	.7
		MOVWF	CMCON
		CLRF	CVRCON			; DESHABILITAMOS LOS COMPARADORES.	
		BCF		RCSTA,SPEN		; DESHABILITAMOS EL PUERTO SERIE.			
		
		CLRF	PORTA			; LIMPIAMOS LAS SALIDAS DEL PUERTO A.
			

;	NOTAS:	************************************************************************************************************************************

;	LA TECLA 0: PRODUCE LA NOTA DO   (261 HZ).
;	LA TECLA 1: PRODUCE LA NOTA DO#  (277 HZ).
;	LA TECLA 2: PRODUCE LA NOTA RE   (294 HZ).
;	LA TECLA 3: PRODUCE LA NOTA RE#  (311 HZ).
;	LA TECLA 4: PRODUCE LA NOTA MI   (330 HZ).
;	LA TECLA 5: PRODUCE LA NOTA FA   (349 HZ).
;	LA TECLA 6: PRODUCE LA NOTA FA#  (370 HZ).
;	LA TECLA 7: PRODUCE LA NOTA SOL  (392 HZ).
;	LA TECLA 8: PRODUCE LA NOTA SOL# (415 HZ).
;	LA TECLA 9: PRODUCE LA NOTA LA   (440 HZ).
;	LA TECLA A: PRODUCE LA NOTA LA#  (466 HZ).
;	LA TECLA B: PRODUCE LA NOTA SI   (494 HZ).

;	TODAS LAS NOTAS REPRODUCIDAS PERTENECEN A LA 4a OCTAVA.

;	ASIGNACION DE TECLAS CON RESPECTO A LA VARIABLE VALOR:

; COLUMNA 1:

;	VALOR = 0 => TECLA 0 => DO
;	VALOR = 1 => TECLA 4 => MI
;	VALOR = 2 => TECLA 8 => SOL#
;	VALOR = 3 => TECLA C 

; COLUMNA 2:

;	VALOR = 4 => TECLA 1 => DO#
;	VALOR = 5 => TECLA 5 => FA
;	VALOR = 6 => TECLA 9 => LA
;	VALOR = 7 => TECLA D

;COLUMNA 3:

;	VALOR = 8  => TECLA 2 => RE
;	VALOR = 9  => TECLA 6 => FA#
;	VALOR = 10 => TECLA A => LA#
;	VALOR = 11 => TECLA E

; COLUMNA 4:

;	VALOR = 12 => TECLA 3 => RE#
;	VALOR = 13 => TECLA 7 => SOL
;	VALOR = 14 => TECLA B => SI
;	VALOR = 15 => TECLA F

		
		
		TECLADO					; CONFIGURAMOS PUERTO B PARA EL TECLADO
	
CICLO
		MOVLW	.4
		MOVWF	BARRIDO			; PARA BARRES LAS COLUMNAS
		CLRF	VALOR			; PARA SABER QUE TECLA OPRIMIMOS
		MOVLW	0XFF
		MOVWF	PORTB
		BCF		STATUS,C		; CARRY = 0 PARA INICIAR EL BARRIDO	
LIN1
		RLF		PORTB,F			; RECORREMOS A LA IZQUIERDA PARA BARRER LAS COLUMNAS.
		BTFSS	PORTB,4			; ES LA TECLA DE LA PRIMERA LINEA?.
		GOTO	LECTURAFIN		; SÍ, TERMINA DE BUSCAR.
		INCF	VALOR,F			; NO, INCREMENTA EL VALOR.
LIN2
		BTFSS	PORTB,5			; ES LA TECLA DE LA SEGUNDA LINEA?.
		GOTO	LECTURAFIN		; SÍ, TERMINA DE BUSCAR.
		INCF	VALOR,F			; NO, INCREMENTA EL VALOR.
LIN3
		BTFSS	PORTB,6			; ES LA TECLA DE LA SEGUNDA LINEA?.
		GOTO	LECTURAFIN		; SÍ, TERMINA DE BUSCAR.
		INCF	VALOR,F			; NO, INCREMENTA EL VALOR.
LIN4	
		BTFSS	PORTB,7			; ES LA TECLA DE LA SEGUNDA LINEA?.
		GOTO	LECTURAFIN		; SÍ, TERMINA DE BUSCAR.
		INCF	VALOR,F			; NO, INCREMENTA EL VALOR.
COLU
		DECFSZ	BARRIDO,F		; YA BARRIMOS LAS 4 COLUMNAS?.
		GOTO	LIN1			; NO, SEGUIMOS LEYENDO EL TECLADO.
		GOTO	CICLO

LECTURAFIN	
		MOVLW	.40				; RETARDO DE 40 mS PARA EVITAR EL REBOTE DEL PULSADOR
		CALL	Retardos_ms	

		MOVFW	VALOR			; CARGA VALOR A W
		ADDWF	PCL,F			; SALTO INDIZADO
		GOTO	DO				
		GOTO	MI
		GOTO	SOL_S
		GOTO	CICLO
		GOTO	DO_S
		GOTO	FA
		GOTO	LA
		GOTO	CICLO
		GOTO	RE
		GOTO	FA_S
		GOTO	LA_S
		GOTO	CICLO
		GOTO	RE_S
		GOTO	SOL
		GOTO	SI
		GOTO	CICLO


;	RUTINAS DE FRECUENCIAS	*******************************************************************************************************************************************	

DO		
		BTFSC	PORTB,4				; SIGUE OPRIMIDO EL BOTON?
		GOTO	CICLO				; NO.	
		BSF		BOCINA				; SI. BOCINA ENCENDIDA. SUPONEMOS QUE VENIMOS DE UN CICLO BAJO
		BTFSC	SEMICICLO,0			; VENIMOS DEL CICLO ALTO O BAJO?
		BCF		BOCINA				; ALTO. APAGA BOCINA Y ESPERA
		CALL	Retardo_500micros	; 
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_200micros
		CALL	Retardo_10micros
		CALL	Retardo_5micros
		NOP
		COMF	SEMICICLO,F			; COMPLEMENTA EL FLAG DE SEMICICLO PARA IDENTIFICAR SI VENIMOS DE UN ESTADO ALTO O BAJO
		GOTO	DO					; REINICIA RUTINA.

MI
		BTFSC	PORTB,5
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_10micros
		CALL	Retardo_5micros
		COMF	SEMICICLO,F
		GOTO	MI

SOL_S	
		BTFSC	PORTB,6
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_5micros
		COMF	SEMICICLO,F
		GOTO	SOL_S

DO_S
		BTFSC	PORTB,4
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_100micros
		CALL	Retardo_5micros
		COMF	SEMICICLO,F
		GOTO	DO_S

FA
		BTFSC	PORTB,5
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_200micros
		CALL	Retardo_20micros
		CALL	Retardo_10micros
		NOP
		NOP
		NOP
		COMF	SEMICICLO,F
		GOTO	FA

LA
		BTFSC	PORTB,6
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_100micros
		CALL	Retardo_20micros
		CALL	Retardo_10micros
		CALL	Retardo_5micros
		NOP
		COMF	SEMICICLO,F
		GOTO	LA

RE
		BTFSC	PORTB,4
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		NOP
		COMF	SEMICICLO,F
		GOTO	RE

FA_S
		BTFSC	PORTB,5
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_100micros
		CALL	Retardo_50micros
		NOP
		COMF	SEMICICLO,F
		GOTO	FA_S

LA_S
		BTFSC	PORTB,6
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_50micros
		CALL	Retardo_20micros
		NOP
		NOP
		NOP
		COMF	SEMICICLO,F
		GOTO	LA_S

RE_S
		BTFSC	PORTB,4
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_100micros
		COMF	SEMICICLO,F
		GOTO	RE_S

SOL
		BTFSC	PORTB,5
		GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_200micros
		CALL	Retardo_50micros
		CALL	Retardo_20micros
		CALL	Retardo_5micros
		NOP
		COMF	SEMICICLO,F
		GOTO	SOL

SI		
		BTFSC	PORTB,6
	GOTO	CICLO
		BSF		BOCINA
		BTFSC	SEMICICLO,0
		BCF		BOCINA
		CALL	Retardo_500micros
		CALL	Retardo_500micros
		CALL	Retardo_10micros
		NOP
		NOP
		COMF	SEMICICLO,F
		GOTO	SI

;	RUTINAS AUXILIARES************************************************************************************************************************************************

Retardos_ms
		movwf	R_ContB				; Aporta 1 ciclo máquina.
R1ms_BucleExterno
		movlw	d'249'				; Aporta Mx1 ciclos máquina. Este es el valor de "K".
		movwf	R_ContA				; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
		nop							; Aporta KxMx1 ciclos máquina.
		decfsz	R_ContA,F			; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
		goto	R1ms_BucleInterno	; Aporta (K-1)xMx2 ciclos máquina.
		decfsz	R_ContB,F			; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
		goto	R1ms_BucleExterno 	; Aporta (M-1)x2 ciclos máquina.
		return						; El salto del retorno aporta 2 ciclos máquina.

Retardo_10micros				; La llamada "call" aporta 2 ciclos máquina.
	nop							; Aporta 1 ciclo máquina.
	nop							; Aporta 1 ciclo máquina.
	nop							; Aporta 1 ciclo máquina.
	nop							; Aporta 1 ciclo máquina.
	nop							; Aporta 1 ciclo máquina.
Retardo_5micros					; La llamada "call" aporta 2 ciclos máquina.
	nop							; Aporta 1 ciclo máquina.
Retardo_4micros					; La llamada "call" aporta 2 ciclos máquina.
	return						; El salto del retorno aporta 2 ciclos máquina.
;
; RETARDOS de 20 hasta 500 microsegundos ------------------------------------------------
;
Retardo_500micros				; La llamada "call" aporta 2 ciclos máquina.
	nop							; Aporta 1 ciclo máquina.
	movlw	d'164'				; Aporta 1 ciclo máquina. Este es el valor de "K".
	goto	RetardoMicros		; Aporta 2 ciclos máquina.
Retardo_200micros				; La llamada "call" aporta 2 ciclos máquina.
	nop							; Aporta 1 ciclo máquina.
	movlw	d'64'				; Aporta 1 ciclo máquina. Este es el valor de "K".
	goto	RetardoMicros		; Aporta 2 ciclos máquina.
Retardo_100micros				; La llamada "call" aporta 2 ciclos máquina.
	movlw	d'31'				; Aporta 1 ciclo máquina. Este es el valor de "K".
	goto	RetardoMicros		; Aporta 2 ciclos máquina.
Retardo_50micros				; La llamada "call" aporta 2 ciclos máquina.
	nop							; Aporta 1 ciclo máquina.
	movlw	d'14'				; Aporta 1 ciclo máquina. Este es el valor de "K".
	goto	RetardoMicros		; Aporta 2 ciclos máquina.
Retardo_20micros				; La llamada "call" aporta 2 ciclos máquina.
	movlw	d'5'				; Aporta 1 ciclo máquina. Este es el valor de "K".

; El próximo bloque "RetardoMicros" tarda:
; 1 + (K-1) + 2 + (K-1)x2 + 2 = (2 + 3K) ciclos máquina.

RetardoMicros
	movwf	R_ContA				; Aporta 1 ciclo máquina.
Rmicros_Bucle
	decfsz	R_ContA,F			; (K-1)x1 cm (cuando no salta) + 2 cm (al saltar).
	goto	Rmicros_Bucle		; Aporta (K-1)x2 ciclos máquina.
	return						; El salto del retorno aporta 2 ciclos máquina.
		
; 	**********************************************************************************************************************************************	
	END