PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE ESCUELA DE INGENIERÍA DPTO. DE CIENCIA DE LA COMPUTACIÓN ICC2342 ARQUITECTURA DE COMPUTADORES Entrega 2 Proyecto: Senfort Integrantes: Ivan Kleiman Diego Rios Tal Rosen Sang Woo Sin Luis Soffia Jorge Vera Fecha: Lunes 5 de Octubre del 2009 Descripción Senfort es un dispositivo que detecta la cantidad de papel higiénico restante en el baño mediante un sensor infrarrojo que mide la distancia entre un punto fijo y el rollo de papel el cual envía esa medida al micro procesador para determinar si es necesario reponer el rollo. Además, el microprocesador lleva la cuenta de cuantos rollos de papel se han utilizado al mes y genera predicciones de consumo para el futuro. La idea detrás de esto, es poder comprar de manera más eficiente el comúnmente conocido "papel confort", manteniendo una política de inventario ajustada a la demanda del lugar. Es por esto que su uso está pensado para baños públicos, que tienen una gran afluencia de público, y en los cuales se puede observar un ahorro más considerable al tener un inventario ajustado a la demanda real. Ilustración En el siguiente diagrama se puede apreciar el concepto detrás de “Senfort”: Eso está mal. El microprocesador no es este sistema de componentes sino que es lo que está dentrol del PIC Componentes 1. LCD Display reflectivo Display LCD caract.4,89mm, Utilizaremos una pantalla para informar al operario de la central del nivel de papel higiénico en los diversos baños, además de desplegar la información relativa al consumo mensual de papel. No dicen cómo lo van a usar, cuál es el código de los caracteres, cómo conectar cada pin, etc. PRECIO: $5.200 (RS) 2. Sensor Infrarrojo de proximidad. Este sensor será utilizado para medir la distancia entre el porta papel y el rollo de papel higiénico para así determinar la cantidad de papel restante en función de esa distancia. PRECIO: $9.437 (Olimex) Nada dice del rango de medición, condiciones de operación, etc. Faltó 3. Interruptor luminoso tecla redondo negro. Utilizaremos este interruptor para implementar el botón de pánico que permite al usuario del WC alertar a la central. PRECIO: 5 Unidades por $364 (RS) ¿Y qué es cada pin? Circuitería Muy bien las citas El circuito consta de 4 elementos, el primero y común a todos los proyectos es el PIC16F877 que controla todas las operaciones del dispositivo. Luego tenemos una pantalla LCD de 16 caracteres con 2 filas. Del PIC se obtienen los datos a desplegar en la pantalla, estos se sacan de las salidas del puerto C, y además se envían señales para escritura, habilitar y seleccionar registros internos del panel. La tercera pieza es el sensor de distancia GP2Y0A21YK, el cual medirá la distancia hasta el objeto (rollo de papel higiénico) para calcular el nivel. La señal analógica que entrega se conecta a la entrada analógica AN1 del puerto A, y se entrega el voltaje de referencia para el ADC del PIC en el puerto RA3/AN3/Vref+ que en este caso serán cinco volts. Finalmente tenemos el botón de pánico el cual se conectará a la entrada RA0/AN0, para interrumpir el programa y avisar casos de emergencia. Faltaron los esquemáticos particulares, sólo pusieron el general, donde no es posible observar qué sale escrito en cada pin. Generalmente el código se pone en font tipo "máquina de escribir" Código Asembler ; Ayudantía 2, José Luis Honorato list p=16f877a ; Tipo dispositivo include <P16F877A.inc> ; Para que reconozca los registros ORG H'00' GOTO PARTIDA ; Ubicación de partida ORG H'04' GOTO INT ; Ubicación de interrupciones ; Variables a almacenar, registros ; de propósito general en el banco 0 LED EQU H'20' ; Led de uso actual POT1 EQU H'21' ; Vin POT2 EQU H'22' ; LED LEVEL EQU H'23' ; Nivel de corte 1 CONT EQU H'24' ; Contador de overflows del timer DIST EQU H'26' ; Valor del Vin aceptable, entre 0 y 127 LEVEL2 EQU H'27' ; Nivel de corte 2 (CAMBIO) PARTIDA BCF STATUS,RP1 BSF STATUS,RP0 ; Me cambio al banco 1 ;Configuración de Puertos (Output = 0 , Input = 1) MOVLW B'11111000' MOVWF TRISC ; RC0 , RC1 y RC2 como outputs para leds ;CAMBIO MOVLW H'FF' MOVWF TRISA ;Todos los canales de A como input CAMBIO MOVLW H'FF' ;Todos los canales de B como input (Vamos a usar RB2 para el switch) MOVWF TRISB ;CAMBIO BCF STATUS,RP0 BCF STATUS,RP1 ; Vuelvo al Banco 0 CLRF CONT CLRF LED CLRF LEVEL CLRF LEVEL2 ; CAMBIO CLRF POT1 CLRF POT2 CLRF DIST ;borro el contenido de las variables ;INTERRUPCIONES MOVLW B'11000000' MOVWF INTCON ; Interrupciones Globales y Periféricas BCF STATUS,RP1 BSF STATUS,RP0 ; BANCO 1 MOVLW B'00000001' MOVWF PIE1 ; Activo la interrupcion Timer1 Overflow ; Aqui se puede usar la interr. del USART, etc. BCF STATUS,RP0 BCF STATUS,RP1 ; BANCO 0 ;CONFIGURACION TIMER 1 CLRF TMR1L CLRF TMR1H MOVLW B'00000000' MOVWF T1CON ;CONFIGURACION ADC BCF STATUS,RP1 BSF STATUS,RP0 MOVLW B'01000000' ; Borro registros TMR1 ; Uso de clock interno, prescaler 1:4, Timer1 OFF ;BANCO 1 ; Justificado Izquierdo FOSC/2 Todos análogos MOVWF ADCON1 BCF STATUS,RP0 BCF STATUS,RP1 MOVLW B'01000000' MOVWF ADCON0 ;BANCO 0 ;FOSC/8, CH0 por ahora, ADC=OFF MOVLW D'40' ; CAMBIO MOVWF LEVEL MOVLW D'80' ; CAMBIO MOVWF LEVEL2 LOOP ; Leo los valores de los potenciómetros CALL LEER_CH0 CALL UBICAR ; Veo en qué lado de "level" estoy CALL LEER_CH1 BTFSC PORTB,2 ; Si RB2 está en 1, parpadea CALL BLINK BTFSS PORTB,2 ; Si RB2 está en 0, lo prendo CALL LED_ON GOTO LOOP ; Vuelvo a hacer lo anterior UBICAR; CAMBIO BCF STATUS,C ; Me aseguro de bajar el flag CAMBIO (a puerto B) CAMBIO (a puerto B) MOVF DIST,0 ; DIST en F SUBWF LEVEL,0 ; (DIST - LEVEL) (el primer valor de corte) BTFSS STATUS,C ; Según el resultado, activo el led correspondiente CALL UBICAR2 ; Si el valor de la resta es positivo BTFSC STATUS,C ; CALL LED_1 ; Si el valor de la resta es negativo RETURN UBICAR2; CAMBIO BCF STATUS,C ; Me aseguro de bajar el flag MOVF DIST,0 ; DIST en F SUBWF LEVEL2,0 ; (DIST - LEVEL2) (el segundo valor de corte) BTFSS STATUS,C ; Según el resultado, activo el led correspondiente CALL LED_3 ; Si el valor de la resta es positivo BTFSC STATUS,C ; CALL LED_2; Si el valor de la resta es negativo BCF STATUS, C; Cambio el status, para que en UBICAR no entre en LED_1 RETURN LED_3 ;RC2 CAMBIO MOVLW B'00000100' ;CAMBIO MOVWF LED ;CAMBIO BCF STATUS,C ;CAMBIO RETURN ;CAMBIO LED_2 MOVLW B'00000010' MOVWF LED BCF STATUS,C RETURN LED_1 ;RC0 MOVLW B'00000001' MOVWF LED BSF STATUS,C RETURN ;RC1 La indentación está para cualquier lado; no favorece la lectura. LED_ON MOVLW B'00000000' ; Uso de clock interno, prescaler 1:4, Timer1 OFF MOVWF T1CON MOVF LED,0 MOVWF PORTC RETURN BLINK MOVLW B'00000001' ; Uso de clock interno, prescaler 1:1 (tercer y cuarto bit), Timer1 ON MOVWF T1CON MOVF CONT,0 ; CONT en W XORWF POT2,0 ; Comparo CONT con POT2, si son iguales (Z=1), cambio el estado del LED BTFSC STATUS,Z CALL CAMBIA_LED BCF STATUS,Z RETURN INT BCF INTCON,GIE ;APAGO INTERRUPCIONES BTFSC PIR1,TMR1IF ; Si la interrupcion es por TMR1 overflow, voy al método CALL CONTAR ; Aqui se pueden agregar otras interrupciones BSF INTCON,GIE ;REACTIVO INTERRUPCIONES RETURN CONTAR BCF PIR1,TMR1IF ; Bajo el flag de la interrupción MOVLW H'EE' MOVWF TMR1H MOVLW H'00' MOVWF TMR1L ; El tiempo de parpadeo dependerá del valor de TMR1H + TMR1L INCF CONT,1 ; Incremento el contador RETURN CAMBIA_LED BCF STATUS,Z CLRF CONT MOVF PORTC,0; Cambio BTFSC STATUS,Z CALL PRENDE_LED BTFSS STATUS,Z CALL APAGA_LED RETURN PRENDE_LED MOVF LED,0 MOVWF PORTC BSF STATUS,Z RETURN APAGA_LED BCF PORTC,0 BCF PORTC,1 BCF STATUS,Z RETURN LEER_CH0 ; Revisa en que lado estoy MOVLW B'01000001' ; Me cambio a CH0 MOVWF ADCON0 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ;BCF ADCON0,CHS0 BSF ADCON0,GO ; Le digo GO PAUSA0 BTFSC ADCON0,GO GOTO PAUSA0 MOVF ADRESH,0 MOVWF POT1 ; Si está en Clear, movemos el dato ;MOVLW H'00' ;MOVWF ADRESH BCF STATUS,C BCF STATUS,DC BCF STATUS,Z RRF POT1,1 ; Maximo 127 BCF STATUS,C MOVF POT1,0 MOVWF DIST RETURN LEER_CH1 ; Blink MOVLW B'01001001' ; Me cambio a CH1 MOVWF ADCON0 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ;BSF ADCON0,CHS0 BSF ADCON0,GO ; Le digo GO PAUSA1 BTFSC ADCON0,GO GOTO PAUSA1 MOVF ADRESH,0 MOVWF POT2 ;MOVLW H'00' ;MOVWF ADRESH RETURN END ; Si está en Clear, movemos el dato Diagramas de Flujo Faltan la conexión entre las salidas de: Primero se definen las variables a usar, en las cuales agregamos una nueva llamada “LEVEL2” que es un segundo corte para el potenciómetro que regula el led que tiene que estar activo. A continuación se definen las configuraciones pertinentes a usar en el programa, como por ejemplo, los puertos a usar, y los dispositivos del mismo PIC a usar, como el timer. También realizamos cambios menores en la configuración, lo más importante es que cambiamos los leds al puerto C (RC0, RC1 y RC2) , el switch al puerto B (RB2) y definimos LEVEL1 = D’40’ y LEVEL2 = D’80’. Con todo esto hecho comienza el programa en sí. Primero se lee el valor del potenciómetro que define que led está activo con LEER_CH0, a continuación se llama a UBICAR que ve a qué lado de LEVEL o LEVEL2 estoy. Este último se modifico ya que se necesitaba un nuevo valor de corte para que sea posible activar el tercer led, su funcionamiento se puede ver en el diagrama. Por último, se lee el valor del segundo potenciómetro para saber si el led activo tiene que parpadear o solo estar prendido (Si RB2 está en 1 parpadea, en 0 lo prendo). En el caso de tener que estar solo prendido se llama a LED_ON que simplemente prende el led. En el caso que tiene que parpadear se llama a BLINK el cual define a qué velocidad parpadear dependiendo del valor del segundo potenciómetro. El segundo potenciómetro era para cambiar la frecuecia de oscilación. El switch era para seleccionar modo de operación.