;****************************************************************************************** ; SENSORES 6 ; "Medir distacia entre pulsos (período)" ; ;Este programa visualiza en el LCD, y con una precisión de 100us, el período. ;El sensor se conecta en J4 y debe ser óptico de reflexión. Puede usarse para ;medir el período de giro de una rueda colocando en la rueda una tira de ;cinta aislante negra. ; Autor: Iván Trueba ; (c) Microsystems Engineering ; c/ Gral. Concha Nº39 - 8º ; 48012 Bilbao Tfno. 4223263 ; ;****************************************************************************************** list p=16F84 ;Se selecciona el PIC 16f84 RADIX HEX ;Sistema de numeraci¢n hexadecimal. include "Regx84.inc" ;Incluye definición de registros del 16F84 TEMP EQU 0x0E ;Registros de propósito general. Temp_1 EQU 0x0F ANCHO EQU 0X10 Buffer_L EQU 0x11 Buffer_H EQU 0x12 Lcd_var EQU 0x13 ;Registros para el uso del LCD. RESUL EQU 0x15 OFFSET EQU 0x16 MS EQU 0x16 ;Variables para contabilizar la duración del período. CS EQU 0x17 SEGUNDOS EQU 0x18 ORG 0x00 ;El programa comienza en la direción 0. goto INICIO ORG 0x05 ;Se salta el vector de interrupción. include "LCD_CXX.ASM" ;Incluye rutinas de manejo del LCD. ;********************************************************************************************* ;Rutinas para la visualización de los mensajes que aparecen en el LCD. DATO_1 addwf PCL,1 retlw 'P' retlw 'e' retlw 'r' retlw 'i' retlw 'o' retlw 'd' retlw 'o' retlw ':' retlw 0x00 MENS_1 clrf RESUL clrf OFFSET MENS movf OFFSET, W addwf RESUL,W call DATO_1 ;Saca caracter iorlw 0 btfsc STATUS,2 ;¿Es el último? return ;Si call LCD_DATO ;Visualiza caracter incf RESUL,1 ;Incrementa contador de caracteres goto MENS VISUALIZA_1: call VISUALIZA ;Rutina que llama a VISUALIZA y goto BUCLE ;regresa a la rutina bucle para esperar un nuevo ;cambio de flanco. VISUALIZA: call UP_LCD ;Configura RB y RA como salidas call LCD_INI ;Rutina de inicialización del LCD movlw b'00001100' call LCD_REG ;LCD en ON movlw b'00000001' call LCD_REG ;Borra LCD y HOME movlw 0x80 ;Dirección del primer carácter, primera línea. call LCD_REG call MENS_1 ;Se visualiza el mensaje de la primera línea. movf SEGUNDOS, W ;Se transforma la variable SEGUNDOS en un call BIN_BCD ;número en ASCII que se visualiza en el LCD. call ASCII movlw '.' call LCD_DATO movf CS, W ;Se transforma la variable CS en un número call BIN_BCD ;en código ASCII que se visualiza en el LCD. call ASCII movf MS, W ;Se pasa la variable MS al código ASCII y se call BIN_BCD ;visualiza en el LCD. call ASCII movlw 's' call LCD_DATO bsf STATUS, RP0 ;Selección del banco 1. movlw b'00010000' ;Se configura RA4 como entrada. movwf PORTA bcf STATUS, RP0 ;Selección del banco 0. return ;************************************************************************************** ;BIN_BCD: Convierte el valor binario presente en el acumulador (W) en BCD. El resul- ;tado se deposita en las variables Buffer_H y Buffer_L. BIN_BCD clrf Buffer_L ;Limpiar regs.de trabajo. clrf Buffer_H BIN_BCD_1 addlw 0xf6 ;Resta 10 por suma de complemento a 2. btfss STATUS,C ;Hay Carry? goto BIN_BCD_3 ;NO. movwf Temp_1 ;SI.Guardar en reg.Temporal. incf Buffer_L,F ;Incrementar byte bajo guardarlo y enviar... movf Buffer_L,W ;..copia al ==> W... xorlw b'00001010' ;..0Ah xor W(BCDL). btfss STATUS,Z ;Es "0" el resultado de la operación? goto BIN_BCD_2 ;NO. clrf Buffer_L ;SI.Limpiar el byte bajo e... incf Buffer_H,F ;incrementar el alto. BIN_BCD_2 movf Temp_1,W ;Recuperar el dato. goto BIN_BCD_1 ;Continuar la operación. BIN_BCD_3 addlw H'0A' ;TEMPO + 0Ah swapf Buffer_L,F ;<3:0> <==> <7:4> y ==> BCDL iorwf Buffer_L,F ;W or BCDL ==> BCDL return ;************************************************************************************** ;ASCII: Esta rutina convierte las variables Buffer_H y Buffer_L en carácteres ASCII para ;ser visualizados en el LCD. ASCII: swapf Buffer_L,w ;Guarda octeto andlw b'00001111' iorlw b'00110000' ;Convierte el primer nible call LCD_DATO ;Lo visualiza movf Buffer_L,w andlw b'00001111' iorlw b'00110000' ;Convierte el segundo nible call LCD_DATO ;Lo visualiza return ;********************************************************************************************** ;PROGRAMA PRINCIPAL ;********************************************************************************************** INICIO: BSF STATUS, RP0 clrf OPTION_REG ;Se asigna el divisor de frecuencia al Timer 0. BCF STATUS, RP0 clrf MS ;Se inicializan las variables del programa a 0. clrf CS clrf SEGUNDOS clrf OFFSET call VISUALIZA BUCLE: btfss PORTA, 4 ;Se mira el estado de RA4. Si es 0 se ha producido ;un cambio de nivel. goto BUCLE clrf MS ;Si se detecta el flanco, inicializa las variables clrf CS ;para contar el período clrf SEGUNDOS clrf OFFSET ;************************************************************************************************** ;Esta parte del programa es la que se encarga de ir contabilizando la dureación del período ;una vez que se detecta el cambio de flanco correspondiente al inicio del período. PERIODO_1 btfsc PORTA, 4 ;Se espera a que finalice el pulso y se va contando goto PERIODO1_ON ;el período. PERIODO_2 btfss PORTA, 4 ;Cuando el pulso ha finalizado se espera a que se GOTO PERIODO2_ON ;produzca el siguiente pulso que señalaría que ha goto VISUALIZA_1 ;finalizado la cuenta del período. PERIODO1_ON CALL DELAY ;Esta rutina la utiliza PERIODO_1 para contabilizar GOTO PERIODO_1 ;el período cuando aún no ha finalizado el primer pulso. PERIODO2_ON CALL DELAY ;Esta rutina la utiliza PERIODO_2 para contar el GOTO PERIODO_2 ;el período cuando finalizado el primer pulso ;se espera a que se produzca el inicio del siguiente. DELAY bcf INTCON, 2 ;Se carga al Timer 0. movlw 0xD2 movwf OPTION_REG DELAY_1 btfss INTCON, 2 ;Se espera a que se desborde el TMR0. goto DELAY_1 movf MS, w ;Si el pulso no ha finalizado se aumenta la addlw 0x01 ;variable MS que cuenta los ms. movwf MS movf MS, W xorlw .100 ;Si la variable ms ha llegado a 100, se pondrá btfss STATUS, Z ;a 0 y se aumentará la variable CS que cuenta return ;las centésimas de segundo clrf MS movf CS, W addlw 0x01 movwf CS ;Se mira si la variable CS ha llegado a 100 en movf CS, W ;cuyo caso se pone a 0 y se aumenta la variable xorlw .100 ;segundos. btfss STATUS, Z return clrf CS movf SEGUNDOS, W addlw 0x01 movwf SEGUNDOS movf SEGUNDOS, W ;Si la variable segundos llega a 100 entonces se xorlw .100 ;vuelve a poner a 0. btfss STATUS, Z return clrf SEGUNDOS return END ;Fin del programa. ;********************************************************************************************