28 feb 2016

LCD, Interrupción RB0 INT, ADC y Transmision RS232 por Software



    Cada vez que se produce la interrupción RB0_INT por flanco de subida en RB0, se transmite vía serial RS232 datos correspondientes a los valores del puerto B y del Convertidor Analógico Digital, a su vez se puede observar la información en el LCD,  representados como altura (puerto B)  y peso (ADC).

    El ejemplo muestra en forma sencilla y ordenada como deben ser configurados y ubicados los codigos correspondientes a las  interrupciones; así como de el resto de los periféricos.


'****************************************************************

Device 16F877
Xtal 20
PortB_Pullups FALSE      'DESHABILITA LAS RESISTENCIAS PULL-UP DEL PUERTO B
On_Interrupt GoTo INTERRUPCION

; DEFINICIONES PARA LA CONFIGURACION INTERUPCIONES

Symbol INTEDG = OPTION_REG.6     ' BIT  SELECCION DEL FALNCO DE INTERRUPCION
Symbol GIE =  INTCON.7           ' BIT HABILITADOR GLOBAL DE INTERRUPCIONES
Symbol INTE =  INTCON.4          ' BIT DE HABILITACION DE LA INTERRPCION RB0/INT
Symbol INTF =  INTCON.1          ' BIT DE HABILITACION DE LA INTERRPCION RB0/INT

;CONFIGURACION DEL CONVERTIDOR ANALOGICO DIGITAL


 Declare Adin_Res 10       '  Resultado ADC - 10 bit

 Declare Adin_Tad FRC      ' RC OSC 
 Declare Adin_Stime 50     ' 50us sample time 


 TRISA = 000001         ' Configura AN0 (PORTA.0) como entrada

 ADCON1 = %10000000        ' Configura PORTA.0 Analogico

;CONFIGURACION DEL LCD 

Declare LCD_Type 0      
Declare LCD_DTPin PORTD.4
Declare LCD_ENPin PORTD.3 
Declare LCD_RSPin PORTD.2 

;CONFIGURACION DEL PUERTO SE COMUNICACION SERIAL

 Declare SERIAL_DATA 8       ' 8 bits de datos
 Symbol  RS232 = 84                 ' 9600 bps/sin bit de paridad
 Symbol  tx_pin = PORTC.6
 Symbol  rx_pin = PORTC.7

' Declaracion de Variables


Dim ADC As Word

Dim PESO As Float
Dim ALTURA As Byte
Dim flag As Byte
Dim cont As Word
Symbol BUZZER = PORTD.0

;EL CÓDIGO DE LA INTERRUPCIÓN SIEMPRE DEBE SER COLOCADO  EN ESTA UBICACIÓN 

;(NO COLOCAR DEBAJO DEL PROGRAMA PRINCIPAL ESTO SE DEBE A QUE LA DIRECCIÓN 
; DE MEMORIA DE PROGRAMA DE ATENCIÓN DE INTERRUPCIONES ES LA ORG 0x004)

GoTo Salta_Int

INTERRUPCION:
    flag = 1
    INTF = 0
Context Restore
Salta_Int:


'CONFIGURACION DE PUERTOS
TRISA = %11111111
TRISB= %11111111
TRISC = %10111111
TRISD.0  = 0
TRISD.1  = 1

;CONFIGURACIÓN DEL LA INTERRUPCIÓN POR FLANCO DE SUBIDA DEL PIN RBO (RB0/INT)

GIE=1                ;HABILITADOR GLOBAL DE INTERRUPCIONES 
INTEDG = 1     ;SELECCIÓN DE FLANCO DE SUBIDA PARA INTERRUPCION RB0/INT
INTE = 1           ; HABILITADOR DE INTERRUPCION RB0/INT
INTF = 0           ; BANDERA DE INTERRUPCION RB0/INT

cont = 0

flag = 0 
BUZZER = 0 
PESO =0
ALTURA =0 

Print At 1,1,"Peso   : ", Dec2 PESO, "  "

Print At 2,1,"Altura : ", Dec ALTURA, "  "

'Inicio del programa principal 

 While 1 = 1
    
    If flag = 1 Then
        
        DelayMS 2700 
        
        ALTURA = PORTB

        BUZZER = 1

        DelayMS 300 
        BUZZER = 0

        ADC = ADIn 0                                ' Efectua la conversion ADC y almacena el resultado en la variable ADC

        PESO = ADC 

  Select Case PORTB

        Case 1 : ALTURA = 1
        Case 3 : ALTURA = 2
        Case 7 : ALTURA = 3
        Case 15 : ALTURA = 4
        Case 31 : ALTURA = 5
        Case 63 : ALTURA = 6
        Case 127 : ALTURA = 7
        Case Else: ALTURA = 0 
        
    End Select
        
        cont = cont + 1 
        
        SerOut tx_pin, RS232, [Dec cont, ".- Peso: ", Dec2 PESO, " - ALTURA : " ,Dec ALTURA, 13]    ' envio rs232
        flag = 0
        Print At 1,1,"Peso   : ", Dec2 PESO, "  "
        Print At 2,1,"Altura : ", Dec ALTURA, "  "
   End If

 Wend

20 feb 2013

MULTIMETRO DIGITAL


MONTAJE EN ISIS 7.7 SP2



MICROCONTROLADOR :   PIC16F877
LCD 2x16

FUNCIONES :
  1. VOLTIMETRO
  2. AMPERIMETRO
  3. CONTADOR
  4. FRECUENCIA
  5. PERIODO
  6. CICLO UTIL
  7. OHMETRO
  8. CAPACIMETRO


CODIGO :


; MULTIMETRO DIGITAL
    Device 16F877           ;SE SELCCIONA EL PIC
    Declare XTAL    20      ;SE CONFIGURA UN CRISTAL DE 20MHZ
PORTB_PULLUPS = 1       ;SE CONFIGURAS LAS RESISTENCIAS INTERNAS PULL-UP DEL PUERTO B
          
'***************************CONFIGURACION CONVERTIDOR ANALOGICO DIGITAL ******************
    Declare ADIN_RES 10                     'CONFIGURA EL ADC A 10 BIT DE RESOLUCION
    Declare ADIN_TAD FRC                    'ASIGNA EL OSCILADOR INTERNO PARA EL MUESTREO 
    Declare ADIN_STIME 50                   ' CONFIGURA A 50uSEG EL TIEMPO DE MUESTREO
    ADCON1 = %10000010                      ' Se CONFIGURA EL ADC TODO ANALOGICO
    
;******************************************************************************************************
;CONFIGURACION DE PUERTOS

   TRISD=001111          ;SE CONFIGURA EL PUERTO  D 
   TRISC=000000          ;SE CONFIGURA EL PUERTO  C 
   TRISB=000001          ;SE CONFIGURA EL PUETO B   
   TRISA=011111          ;SE CONFIGURA EL PUERTO A 
   TRISE=000001          ;SE CONFIGURA EL PUERTO E
   
   Clear PORTD              ; LIMPIA EL PUERTO D
   Clear PORTB              ; LIMPIA EL PUERTO B
   Clear PORTC              ; LIMPIA EL PUERTO C
   Clear PORTE              ; LIMPIA EL PUERTO E


'INICIALIZACON DE PANTALLA LCD

Declare LCD_TYPE 0             ;PANTALLA ALFANUMERICA
    Declare LCD_DTPIN PORTB.4      ;SE USAN 4 LINEAS DE DATOS
    Declare LCD_RSPIN PORTB.3      ;SE CONFIGURA EL PIN RB3 PARA EL RS DEL LCD 
Declare LCD_ENPIN PORTB.2      ;SE CONFIGURA EL PIN RB2 PARA EL PIN EN DEL LCD
    Declare LCD_LINES 2            ;LCD DE DOS LINEAS
  
    
'DECLARACION DE VARIABLES

   Dim Frec As Word                ;SE DECLARA LA VAR FREC DE 16 BITS
   Dim Cont As Byte
   Dim var1 As Byte

   Dim volt As Float
   Dim OHM As Float
   Dim CAD  As Word
   Dim amper As Float
   Dim temp As Float
   Dim periodo As Float
   Dim ciclo_h As Word
   Dim ciclo_l As Word
   Dim porc_ciclo_util As Float
   Dim capacitancia2 As Word
   Dim capacitancia As Float
  
;SE ALMACENAN LOS SIMBOLOS ESPECIALES EN LA MEMORIA CGRAM DE LA PANTALLA LCD
       ' CARGANDO EL 1ER. CARACTER PERSONALIZADO EN LA CGRAM   BORDE ESQUINA SUPE IZ - CARACTER 0
        Print 254,64, $1F,$1E,$1C,$1C,$18,$18,$10,$00
       'CARGANDO EL 2DO. CARACTER PERSONALIZADO EN LA CGRAM    BORDE ESQUINA INF IZQ- CARACTER 1
        Print 254,72, $00,$10,$18,$18,$1C,$1C,$1E,$1F
        'CARGANDO EL 3RO. CARACTER PERSONALIZADO EN LA CGRAM   SUPER DER - CARACTER 2
        Print 254,80, $1F,$0F,$0F,$07,$07,$03,$03,$01
        'CARGANDO EL 4TO. CARACTER PERSONALIZADO EN LA CGRAM    INF DER - CARACTER 3
        Print 254,88, $01,$03,$03,$07,$07,$0F,$0F,$1F
        'CARGANDO EL 5TO. CARACTER PERSONALIZADO EN LA CGRAM    SIGNO MENOS  - CARACTER 4
        Print 254,96, $00,$00,$00,$1F,$1F,$00,$00,$00
       'CARGANDO EL 6TO. CARACTER PERSONALIZADO EN LA CGRAM    FLECHA DER  - CARACTER 5
        Print 254,104, $00,$10,$18,$1C,$1C,$18,$10,$00
        'CARGANDO EL 7MO. CARACTER PERSONALIZADO EN LA CGRAM    FACHA ARRIBA - CARACTER 6
        Print 254,112, $00,$00,$00,$04,$0E,$0E,$1F,$1F
        'CARGANDO EL 8VO. CARACTER PERSONALIZADO EN LA CGRAM     FLECHA ABAJO - CARACTER 7
        Print 254,120, $1F,$1F,$0E,$0E,$04,$00,$00,$00  

        Cls     ;LIMPIA EL LCD
       
        Print At 1,1,0, "  MULTIMETRO  ",2     ;
        Print At 2,1,1, "    DIGITAL   ",3

        DelayMS 3000
        Cls

;INICIO PROGRAMA PRINCIPAL

Cont = 0                     ; CONTADOR DE INDICADOR DE FUNCION A SELECCIONAR

INICIO:

     If PORTD.1 = 1 Then
        DelayMS 300
        Cont= Cont + 1
        If Cont = 7 Then
            Cont = 6
        End If
     End If 
     
     If PORTD.0 = 1 Then
        DelayMS 300
        Cont= Cont - 1
        If Cont = 255 Then
            Cont = 0
        End If
     End If 
     
; SE SELECCIONA UNA OPCION DEPENDIENDO DEL VALOR DE LA VARIABLE CONT
     Select Case Cont 
         Case 0 :
             Print At 1,1,"1-",5, $FE, $0C,  "VOLTIMETRO   "  
             Print At 2,1,"2-", " AMPERIMETRO ",7
             If PORTD.2=1 Then
                Call VOLTIMETRO
             End If
                          
         Case 1 :
             Print At 1,1,"2-",5, "AMPERIMETRO ",6
             Print At 2,1,"3-", " MED. FREC   ",7
             If PORTD.2=1 Then
                Call AMPERIMETRO
             End If
         Case 2 :
             Print At 1,1,"3-",5, "MED. FREC   ",6
             Print At 2,1,"4-", " MED. PERIODO",7
             If PORTD.2=1 Then
                Call FRECUENCIMETRO
             End If             
         Case 3 :
             Print At 1,1,"4-",5, "MED. PERIODO",6
             Print At 2,1,"5-", " % CICLO UTIL",7
             If PORTD.2=1 Then
                Call MED_PERIODO
             End If
         Case 4 :          
             Print At 1,1,"5-",5, "% CICLO UTIL",6
             Print At 2,1,"6-", " OHMETRO     ",7        
             If PORTD.2=1 Then
                Call CICLO_UTIL
             End If                
         Case 5 :       
             Print At 1,1,"6-",5, "OHMETRO     ",6
             Print At 2,1,"7-", " CAPACIMETRO ",7       
             If PORTD.2=1 Then
                Call OHMETRO
             End If         
         Case 6 :        
              Print At 1,1,"7-",5, "CAPACIMETRO ",6
              Print At 2,1,"  ", "              "        
             If PORTD.2=1 Then
                Call Capacimetro
             End If              
     End Select 

GoTo INICIO                                     ; REGRESA A LA ETIQUETA INICIO
;;FIN DEL PROGRAMA PRNCIPAL
    

;;****************** RUTINA PARA EL FRECUENCIMETRO ***********************************
FRECUENCIMETRO:
Cls
    Repeat
        Frec = Counter PORTB.0,200                 ;RELIZA UN CONTEO DE PULSOS EN EL PUERTO B PIN 0  POR UN PERIODO DE 200 MS
        Frec = Frec * 5
        Print At 1,1, " FREC = ",Dec Frec , " HZ        "  
    Until PORTD.3=1       ;SE EJECUTA LA RUTIMA HASTA QUE SE PRESIONES SALIR       

Return


;*********** RUTINA PARA LA MEDICION DE PERIODOS ************************************
MED_PERIODO:
Cls
    Repeat
        Frec = Counter PORTB.0,200                 ;RELIZA UN CONTEO DE PULSOS EN EL PUERTO B PIN 0  POR UN PERIODO DE 200 MS
        Frec = Frec * 5
        periodo = 1000 / Frec
        Print At 1,1, " T = ",DEC2 periodo , " mSeg        "  
    Until PORTD.3=1              ;SE EJECUTA LA RUTIMA HASTA QUE SE PRESIONES SALIR
Return



;**************** RUTINA DEL VOLTIMETRO*************************
VOLTIMETRO:
Cls
    Repeat    
        CAD = ADIn 1       ; DEVUELVE UN VALOR ENTRE 0 Y 1023   PORQUE ES 10 BIT
        volt = CAD * 10/1023
        Print At 1,1, "Volt = ", DEC2 volt , " VDC    "  ;
    Until PORTD.3=1          ;SE EJECUTA LA RUTIMA HASTA QUE SE PRESIONES SALIR

Return

;*********RUTINA PARA LA MEDICION DE RESISTENCIA ******************************* 
OHMETRO:
Cls
;SE UTILIZA UN DIVISOR DE TENSION VOUT = R2*VIN/(R1+R2)
    Repeat    
        CAD = ADIn 3
        volt = CAD * 5000/1023
        OHM = (volt * 10000 )
        OHM = OHM /( 5000 - volt)
       Print At 1,1, " RES = ", DEC2 OHM , " OHM      "  ;
    
    Until PORTD.3=1       ;SE EJECUTA LA RUTIMA HASTA QUE SE PRESIONES SALIR
Return

;*********************** RUTINA PARA EL AMPERIMETRO*********************************
AMPERIMETRO:
Cls    
     Repeat
        CAD = ADIn 2
        amper= CAD  * 20 /1023
        Print At 1,1, " Corr = ", DEC2 amper , " mA     "  ;
    Until PORTD.3=1   ;SE EJECUTA LA RUTIMA HASTA QUE SE PRESIONES SALIR
Return  
       
;******************************* RUTINA PARA LA MEDICION DE CICLO UTIL****************
CICLO_UTIL:
Cls    
     Repeat
        ciclo_l = PulsIn PORTB.0,0       ;CUENTA EL TIEMPO DE DURACION DEL UN PULSO EN ESTADO BAJO
        DelayMS 10
        ciclo_h = PulsIn PORTB.0,1       ;CUENTA EL TIEMPO DE DURACION DEL UN PULSO EN ESTADO ALTO
        porc_ciclo_util = (ciclo_h*100)
        porc_ciclo_util= porc_ciclo_util /(ciclo_l + ciclo_h)
        Print At 1,1, "Ciclo Ut= ", DEC1  porc_ciclo_util ,"     "  ;
    Until PORTD.3=1       
Return



;************************* RUTINA PARA CALCULAR LA CAPACITACIA **********************
Capacimetro:
Cls
    Repeat    
        For var1   = 1 To 100
            High PORTE.0                  ' Discharge the cap 
            DelayMS 10           
            capacitancia2 = RCIn PORTE.0 , High            ;CALCULA EL TIEMPO DE DESCARGA DEL CAPACITOR
            capacitancia = (capacitancia2/64) + capacitancia     ; SE SUMA EL RESULTADO EN LA VARIABLE 100 VECES
        Next
        capacitancia= capacitancia /100   ; SE DIVIDE ENTRE 100 PARA SACAR EL PROMEDIO
        Print At 1,1, " Cap = ", Dec  capacitancia , 223, " uF      "  ;
    Until PORTD.3=1                
Return