11 Ejercicios Micros en C V2 PDF
11 Ejercicios Micros en C V2 PDF
MICROCONTROLADORES EN C
                          1
Contenido
14. Uso del TMR0 como contador o temporizador utilizando interrupción .............................................. 37
21. Teclado 4x4 y enviar el valor a una PC vía Rs232 (serial) y a un display 7 segmentos ...................... 58
23. Comunicación serie entre dos PICs con la USART y Teclado ............................................................ 65
24. Medir temperatura con LM35 y mostrarla por LCD 2x16 ................................................................... 70
25. Mandar un mensaje por Rs232 y mostrarlo por un LCD 2x16 ............................................................ 72
                                                                                                                                                      2
26. Medir temperatura con LM35 y mandar el valor vía RS232 (serial) ................................................... 74
BIBLIOGRAFÍA ............................................................................................................................................. 76
                                                                                                                                                           3
1. Construcción de un simple secuenciador a LED
Ejemplo:
Realizar un circuito para encender en forma secuencial un diodo LED en el pin RB0, cuya
frecuencia de intermitencia es de 1 seg. El PIC a utilizar es el PIC16F877 a una frecuencia de
oscilación de 4Mhz.
El código de este ejemplo en lenguaje Assembly está disponible en el capítulo "Los Puertos
Paralelos de Entrada/Salida".
/******************************************************************************
*                                                                             *
* DESCRIPCIÓN: Frecuencia de intermitencia de 1 seg.                          *
* Led_On-Off.c                                                                *
*                                                                             *
******************************************************************************/
#include <16F877.h>
#use delay(clock=4000000)
#use fixed_io(b_outputs = PIN_B0)
void main()
{
    while(1) {
      output_high(PIN_B0);
      delay_ms(1000);
      output_low(PIN_B0);
      delay_ms(1000);
    }
                                                                                            4
Se va analizar línea por línea el contenido del código Led_On-Off.c, desde de la primera línea de
código.
   #include esta directiva del compilador del lenguaje C, indica al compilador que incluya en el
    archivo fuente el texto que contiene el archivo especificado, en este caso la directiva que
    permite definir el PIC a utilizar.
    #include <16F877.h>
   #fuses es una directiva del compilador del lenguaje C que permite definir la palabra de
    configuración del PIC, esta directiva define qué fusibles deben activarse o desactivarse en el
    dispositivo cuando se programe. En este caso se informa al compilador que se usa un reloj en
    modo XT, no usa Watch Dog y el código no es protegido:
#fuses XT,NOWDT,NOPROTECT
   #use delay es una directiva que sirve para establecer el reloj con el cual va a trabajar el PIC.
    En este caso trabajará el PIC con un reloj de 4 MHz:
#use delay(clock=4000000)
   #use fixed es una directiva que indica al compilador C que genere código para hacer que un
    pin de I/O sea de entrada o salida cada vez que se utiliza. En este caso PIN_B0 se configura
    como salida:
   void main() es la función principal del programa, que tiene un lazo infinito que pone en alto
    la salida RB0, a continuación hay un delay de 1 seg, y realiza lo mismo para cuando la salida
    se pone en bajo:
      while(1) {
        output_high(PIN_B0);
        delay_ms(1000);
        output_low(PIN_B0);
        delay_ms(1000);
      }
                                                                                                  5
C1
22pF
                        U1                                           D1
                                                               R1
         X1        13
                         OSC1/CLKIN            RB0/INT
                                                          33
         CRYSTAL   14                                     34   100
                         OSC2/CLKOUT              RB1
                                                          35         LED-RED
C2                                                RB2
                    2                                     36
                         RA0/AN0              RB3/PGM
                    3                                     37
                         RA1/AN1                  RB4
                    4                                     38
                         RA2/AN2/VREF-/CVREF      RB5
22pF                5                                     39
                         RA3/AN3/VREF+        RB6/PGC
                    6                                     40
                         RA4/T0CKI/C1OUT      RB7/PGD
                    7
                         RA5/AN4/SS/C2OUT
                                                          15
                                       RC0/T1OSO/T1CKI
       R2           8
                         RE0/AN5/RD      RC1/T1OSI/CCP2
                                                          16
       4k7          9                                     17
                         RE1/AN6/WR            RC2/CCP1
                   10                                     18
                         RE2/AN7/CS        RC3/SCK/SCL
                                                          23
                                            RC4/SDI/SDA
                    1                                     24
                         MCLR/Vpp/THV           RC5/SDO
                                                          25
                                              RC6/TX/CK
                                                          26
                                              RC7/RX/DT
                                                          19
                                              RD0/PSP0
                                                          20
                                              RD1/PSP1
                                                          21
                                              RD2/PSP2
                                                          22
                                              RD3/PSP3
                                                          27
                                              RD4/PSP4
                                                          28
                                              RD5/PSP5
                                                          29
                                              RD6/PSP6
                                                          30
                                              RD7/PSP7
                        PIC16F877
                                                                               6
2. Encender un led más un pulsador
Ejemplo:
En este programa al presionar el pulsador conectado en el pin RA0 se encenderá un led conectado en el
pin RB0 por 0.5 seg, que estará dentro de un bucle infinito para que el programa se ejecute infinitamente.
El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
void main(void)
{
    set_tris_A(0b00000001); // Programa el puerto A para que RA0 sea entrada
    set_tris_B(0b00000000); // Programa el puerto B para que sea salida
    port_B=0x00;               // En un inicio todo el puerto B estara apagado
    while (true)              // Bucle infinito para que el programa se ejecute infinitamente
    {
        if (input(pin_A0)==0)      // Pregunta si RA0 es cero
        {
              port_B=0b00000001; // Cuando se cierra el pulsador ejecuta esta tarea
              delay_ms(500);        // la cual es encender un led conectado en RB0
              port_b=0b00000000;
        }
    }
}
                                                                                                        7
5v
     R1         U2                                            D1
           13                                     33
                                                       R2
     10k         OSC1/CLKIN            RB0/INT
           14                                     34   220R
                 OSC2/CLKOUT              RB1
                                                  35          LED-BLUE
                                          RB2
            2                                     36
                 RA0/AN0              RB3/PGM
            3                                     37
                 RA1/AN1                  RB4
            4                                     38
                 RA2/AN2/VREF-/CVREF      RB5
            5                                     39
                 RA3/AN3/VREF+        RB6/PGC
            6                                     40
                 RA4/T0CKI/C1OUT      RB7/PGD
            7
                 RA5/AN4/SS/C2OUT
                                                  15
                               RC0/T1OSO/T1CKI
            8                                     16
                 RE0/AN5/RD      RC1/T1OSI/CCP2
            9                                     17
                 RE1/AN6/WR            RC2/CCP1
           10                                     18
                 RE2/AN7/CS        RC3/SCK/SCL
                                                  23
                                    RC4/SDI/SDA
            1                                     24
                 MCLR/Vpp/THV           RC5/SDO
                                                  25
                                      RC6/TX/CK
                                                  26
                                      RC7/RX/DT
                                                  19
                                      RD0/PSP0
                                                  20
                                      RD1/PSP1
                                                  21
                                      RD2/PSP2
                                                  22
                                      RD3/PSP3
                                                  27
                                      RD4/PSP4
                                                  28
                                      RD5/PSP5
                                                  29
                                      RD6/PSP6
                                                  30
                                      RD7/PSP7
                PIC16F877A
                                                                         8
3. Dos secuencias de luces más dos pulsadores
Ejemplo:
En este programa al presionar el pulsador conectado en el pin RA0 se hará una secuencia de luces por
el puerto B, y al presionar el pulsador conectado en el pin RA1 se hará otra secuencia de luces por el
puerto B. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
void main()
{
  set_tris_A(0b000011);        // Programa para que RA0 y RA1 sean entradas
  set_tris_B(0b00000000);      // Programa para que todo el puerto B sea salida
  portB=0b00000000;            // En un inicio todo el puerto B estara apagado
                                                                                     10
4. Contador Binario de 0-255 mostrado por leds
Ejemplo:
En este programa cada vez que se presiona el pulsador conectado en el pin RA0 se mostrará una cuenta
binaria de 0 a 255, a través de unos leds conectados en el puerto B. El programa debe tener un bucle
infinito para que se ejecute infinitamente. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación
de 4Mhz.
void main(void)
{
  set_tris_b(0b00000000); // Programa todo el Puerto B como salida
  portB=0b00000000;        // En un inicio todo el Puerto B estara apagado
                                                                                                         11
5v
                                                              D9
                                                       R10
     R18        U2                                     220R
           13                                     33          LED-GREEN
     10k
           14
                 OSC1/CLKIN            RB0/INT
                                                  34          D10
                 OSC2/CLKOUT              RB1
                                                  35
                                                       R11
                                          RB2
            2                                     36   220R
                 RA0/AN0              RB3/PGM
            3                                     37          LED-GREEN
            4
                 RA1/AN1                  RB4
                                                  38          D11
            5
                 RA2/AN2/VREF-/CVREF      RB5
                                                  39
                                                       R12
                 RA3/AN3/VREF+        RB6/PGC
            6                                     40   220R
                 RA4/T0CKI/C1OUT      RB7/PGD
            7                                                 LED-GREEN
                 RA5/AN4/SS/C2OUT
                                                  15          D12
            8
                               RC0/T1OSO/T1CKI
                                                  16
                                                       R13
                 RE0/AN5/RD      RC1/T1OSI/CCP2
            9                                     17   220R
                 RE1/AN6/WR            RC2/CCP1
           10                                     18          LED-GREEN
                 RE2/AN7/CS        RC3/SCK/SCL
                                                  23          D13
            1
                                    RC4/SDI/SDA
                                                  24
                                                       R14
                 MCLR/Vpp/THV           RC5/SDO
                                                  25   220R
                                      RC6/TX/CK
                                                  26          LED-GREEN
                                      RC7/RX/DT               D14
                                                  19
                                                       R15
                                      RD0/PSP0
                                                  20   220R
                                      RD1/PSP1
                                                  21          LED-GREEN
                                      RD2/PSP2
                                                  22          D15
                                      RD3/PSP3
                                                  27
                                                       R16
                                      RD4/PSP4
                                                  28   220R
                                      RD5/PSP5
                                                  29          LED-GREEN
                                      RD6/PSP6
                                                  30          D16
                                      RD7/PSP7         R17
                PIC16F877A                             220R
                                                              LED-GREEN
                                                                          12
5. Contador de 0-9 con 7 segmentos
Ejemplo:
En este programa cada vez que se presiona el pulsador conectado en el pin RA0 se irá incrementando
una cuenta de 0 a 9 y se visualizará por un display 7 segmentos. El programa debe tener un bucle infinito
para que se ejecute infinitamente. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de
4Mhz.
void main(void)
{
  int A=0;                   // Constante A con el valor inicial cero
En la variable A se asigna el valor 255, porque si se asigna a 0, la cuenta empieza desde 1 hasta 9, y se
necesita que empiece desde 0 hasta 9.
                                                                                                      13
5v
     R9         U2
     10k   13                                     33
                 OSC1/CLKIN            RB0/INT
           14                                     34
                 OSC2/CLKOUT              RB1
                                                  35
                                          RB2
            2                                     36
                 RA0/AN0              RB3/PGM
            3                                     37
                 RA1/AN1                  RB4
            4                                     38
                 RA2/AN2/VREF-/CVREF      RB5
            5                                     39
                 RA3/AN3/VREF+        RB6/PGC
            6                                     40
            7
                 RA4/T0CKI/C1OUT      RB7/PGD          R1
                 RA5/AN4/SS/C2OUT
                                                  15
                                                       R2
            8
                               RC0/T1OSO/T1CKI
                                                  16
                                                       R3
                                                       220R
            9
                 RE0/AN5/RD      RC1/T1OSI/CCP2
                                                  17
                                                       R4
                                                       220R
                 RE1/AN6/WR            RC2/CCP1        220R
           10                                     18   220R
                 RE2/AN7/CS        RC3/SCK/SCL
                                                  23
                                    RC4/SDI/SDA
            1                                     24
                 MCLR/Vpp/THV           RC5/SDO
                                                  25
                                      RC6/TX/CK
                                                  26
                                      RC7/RX/DT
                                                  19
                                      RD0/PSP0
                                                  20
                                      RD1/PSP1
                                                  21
                                      RD2/PSP2
                                                  22
                                      RD3/PSP3
                                                  27
                                      RD4/PSP4
                                                  28
                                      RD5/PSP5
                                                  29
                                      RD6/PSP6
                                                  30
                                      RD7/PSP7
                PIC16F877A
                                                              14
6. Secuencia de luces utilizando funciones
Ejemplo:
En este proyecto al presionar el pulsador conectado en el pin RA0 se mostraáa una secuencia por el
puerto B, de igual manera al presionar el pulsador conectado en el pin RA1 se mostrará otra secuencia
por el puerto B. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
La diferencia que tiene este proyecto con el PROYECTO 3 es que éste es realizado con FUNCIONES.
void main(void)
{
  set_tris_B(0b00000000); // Se programa el puerto B como salida
  portB=0b00000000;       // En un inicio todo el puerto B estara apagado
void funcion_1()
{
  portB=0b00011000;
  delay_ms(200);
  portB=0b00100100;
  delay_ms(200);
  portB=0b01000010;
  delay_ms(200);
  portB=0b10000001;
  delay_ms(200);
  portB=0b00000000;
  delay_ms(200);
}
void funcion_2()
{
  portB=0b11111111;
                                                                                                  15
    delay_ms(200);
    portB=0b01111110;
    delay_ms(200);
    portB=0b00111100;
    delay_ms(200);
    portB=0b00011000;
    delay_ms(200);
    portB=0b00000000;
    delay_ms(200);
}
                      U2                                     R1
     R12   R11   13
                       OSC1/CLKIN            RB0/INT
                                                        33
                                                             R2
                 14                                     34
     10k   10k         OSC2/CLKOUT              RB1
                                                        35
                                                             R3
                                                             220R
                  2
                                                RB2
                                                        36
                                                             R4
                                                             220R
                  3
                       RA0/AN0              RB3/PGM
                                                        37
                                                             R6
                                                             220R
                  4
                       RA1/AN1                  RB4
                                                        38
                                                             R7
                                                             220R
                  5
                       RA2/AN2/VREF-/CVREF      RB5
                                                        39
                                                             R8
                                                             220R
                  6
                       RA3/AN3/VREF+        RB6/PGC
                                                        40
                                                             R9
                                                             220R
                       RA4/T0CKI/C1OUT      RB7/PGD          220R
                  7                                          220R
                       RA5/AN4/SS/C2OUT
                                                        15
                                     RC0/T1OSO/T1CKI
                  8
                       RE0/AN5/RD      RC1/T1OSI/CCP2
                                                        16          D1   D2    D3    D4    D5    D6    D7    D8
                  9                                     17          LED-GREEN
                                                                          LED-GREEN
                                                                                LED-GREEN
                                                                                      LED-GREEN
                                                                                            LED-GREEN
                                                                                                  LED-GREEN
                                                                                                        LED-GREEN
                                                                                                              LED-GREEN
                       RE1/AN6/WR            RC2/CCP1
                 10                                     18
                       RE2/AN7/CS        RC3/SCK/SCL
                                                        23
                                          RC4/SDI/SDA
                  1                                     24
                       MCLR/Vpp/THV           RC5/SDO
                                                        25
                                            RC6/TX/CK
                                                        26
                                            RC7/RX/DT
                                                        19
                                            RD0/PSP0
                                                        20
                                            RD1/PSP1
                                                        21
                                            RD2/PSP2
                                                        22
                                            RD3/PSP3
                                                        27
                                            RD4/PSP4
                                                        28
                                            RD5/PSP5
                                                        29
                                            RD6/PSP6
                                                        30
                                            RD7/PSP7
                      PIC16F877A
                                                                                                                    16
7. Secuencia de luces utilizando operadores aritméticos
Los operadores aritméticos en los programas también se pueden utilizar para realizar
desplazamientos de bits a la izquierda y a la derecha, de la siguiente manera: una multiplicación
por 2 (en binario) hace desplazar el bit que está a uno hacia la izquierda, y al dividir entre 2 se
desplaza el bit a uno hacia la derecha.
Ejemplo:
Este ejemplo simula 8 luces del coche fantástico; desplaza el bit que está a uno hacia la izquierda
y desplaza el bit a uno hacia la derecha, con lo que se tiene una secuencia. El PIC a utilizar es el
PIC16F877 a una frecuencia de oscilación de 4Mhz.
/******************************************************************************
*                                                                             *
* Coche fantástico (utilizando operadores aritmeticos).                       *
* Desplaza el bit que está a uno hacia la izquierda y desplaza                *
* el bit a uno hacia la derecha.                                              *
* Secuencia_Luces_Op_Aritméticos.c                                            *
*                                                                             *
******************************************************************************/
#include <16F877.h>
#use delay(clock=4000000)
#fuses XT,NOWDT
#byte puerto_b=0x06
void main() {
    set_tris_b(0x00);
    puerto_b=1;
    delay_ms(1000);
    while(true)
    {
        while(puerto_b<=0b01000000)
        {
            puerto_b*=2;
            delay_ms(1000);
        }
        while(puerto_b>=0b00000010)
        {
            puerto_b/=2;
            delay_ms(1000);
        }
    }
}
Para poder explicar el código, se muestra a continuación con numeración en cada sentencia:
                                                                                                 17
    En la línea 9: #byte puerto_b=6
     Crea un identificador llamado puerto_b para referenciar el registro de propósito
     específico (SFR) con dirección 0x06, que corresponde al Puerto B. Esta es una forma de
     acceder a los puertos del PIC.
                                                                                        18
     U1                                         RN1             U2
13                                     33   1         16    1            20
      OSC1/CLKIN            RB0/INT
14                                     34   2         15    2            19
      OSC2/CLKOUT              RB1
                                       35   3         14    3            18
                               RB2
 2                                     36   4         13    4            17
      RA0/AN0              RB3/PGM
 3                                     37   5         12    5            16
      RA1/AN1                  RB4
 4                                     38   6         11    6            15
      RA2/AN2/VREF-/CVREF      RB5
 5                                     39   7         10    7            14
      RA3/AN3/VREF+        RB6/PGC
 6                                     40   8         9     8            13
      RA4/T0CKI/C1OUT      RB7/PGD
 7                                                          9            12
      RA5/AN4/SS/C2OUT
                                       15       220        10            11
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17                       LED-BARGRAPH-GRN
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA
 1                                     24
      MCLR/Vpp/THV           RC5/SDO
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT
                                       19
                           RD0/PSP0
                                       20
                           RD1/PSP1
                                       21
                           RD2/PSP2
                                       22
                           RD3/PSP3
                                       27
                           RD4/PSP4
                                       28
                           RD5/PSP5
                                       29
                           RD6/PSP6
                                       30
                           RD7/PSP7
     PIC16F877A
                                                                                   19
8. Decodificador de Binario a 7 Segmentos
Ejemplo:
Circuito que hace las funciones de un decodificador de binario a decimal de un dígito decimal y
muestra los resultados en un display de siete segmentos de cátodo común, lo que quiere decir que
el PIC debe proporcionar valores activados en alto en su salida del Puerto B.
La relación entre los pines del display y el valor de las letras de cada segmento es la siguiente:
Luego se hace una tabla de verdad que muestre por cada combinación binaria en la entrada, a
qué pines del PIC se tienen que activar:
La lógica del programa lo único que hace es chequear el estado de las entradas, en este caso
representadas por los interruptores A0, A1 y A2 y activa el conjunto de pines correspondientes
en el PIC que alimentarán los ánodos del display.
/******************************************************************************
                                                                                                     20
*                                                                             *
* Decodificador de binario a decimal                                          *
* Decodificador_Binario_7Segmentos.c                                          *
*                                                                             *
******************************************************************************/
#include <16F877.h>
void main()
{
    set_tris_b( 0x00 ); // Se configura Puerto B como salida.
    set_tris_a( 0x3F ); // Se configura Puerto A como entrada
    while( true )
    {
        switch( port_A )
        {
            case 0:
                    port_B   = 0x3F;
                    break;
            case 1:
                    port_B   = 0x06;
                    break;
            case 2:
                    port_B   = 0x5B;
                    break;
            case 3:
                    port_B   = 0x4F;
                    break;
            case 4:
                    port_B   = 0x66;
                    break;
            case 5:
                    port_B   = 0x6D;
                    break;
            case 6:
                    port_B   = 0x7D;
                    break;
            case 7:
                    port_B   = 0x07;
                    break;
        }
    }
}
#include "kbd_lib.c"
    Esta librería es una modificación de "kbd.c" que incluye CCS en la carpeta Drivers, creada
    en la instalación del programa. La que viene por defecto controla un teclado de 4 (filas) x 3
    (Columnas). La modificación que se ha hecho permite controlar un teclado de 4 x 4. Al ver el
                                                                                              21
    código original es fácil hacer las modificaciones pertinentes para poder controlar un teclado
    personalizado.
   Una forma más simple de seleccionar el valor decodificado para ser mostrado en el display
    de 7 segmentos, que se utiliza en la sentencia switch(port_A){}, es asignando los valores
    decodificados en un vector como se muestra a continuación:
    int valor_B = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07};
                         U1                                         RN1
                    13                                     33   1         16
                          OSC1/CLKIN             RB0/INT
                    14                                     34   2         15
                          OSC2/CLKOUT               RB1
                                                           35   3         14
                                                    RB2
                     2                                     36   4         13
    0                3
                          RA0/AN0
                          RA1/AN1
                                                RB3/PGM
                                                    RB4
                                                           37   5         12
                     4                                     38   6         11
    1                5
                          RA2/AN2/VREF-/CVREF
                          RA3/AN3/VREF+
                                                    RB5
                                                RB6/PGC
                                                           39   7         10
                     6                                     40   8         9
    1                7
                          RA4/T0CKI/C1OUT
                          RA5/AN4/SS/C2OUT
                                                RB7/PGD
                                                           15       RX8
                                         RC0/T1OSO/T1CKI
                     8                                     16
                          RE0/AN5/RD      RC1/T1OSI/CCP2
                     9                                     17
                          RE1/AN6/WR            RC2/CCP1
                    10                                     18
                          RE2/AN7/CS         RC3/SCK/SCL
                                                           23
                                             RC4/SDI/SDA
                     1                                     24
                          MCLR/Vpp/THV           RC5/SDO
                                                           25
                                               RC6/TX/CK
                                                           26
                                               RC7/RX/DT
                                                           19
                                               RD0/PSP0
                                                           20
                                               RD1/PSP1
                                                           21
                                               RD2/PSP2
                                                           22
                                               RD3/PSP3
                                                           27
                                               RD4/PSP4
                                                           28
                                               RD5/PSP5
                                                           29
                                               RD6/PSP6
                                                           30
                                               RD7/PSP7
                         PIC16F877A
                                                                                              22
9. Multiplexación de Displays 7 Segmentos
Ejemplo:
/******************************************************************************
*                                                                             *
* Multiplezar dos Displays.                                                   *
* Multiplexación_7Segmentos.c                                                 *
*                                                                             *
******************************************************************************/
#include <16F877.h>
void Mostrar_Dato()
{
   int uni,deci;
    deci=cuenta/10;
    uni=cuenta%10;
    puerto_C=0b00000001;
    puerto_B=(DISPLAY[uni]);
    delay_ms(5);
    puerto_C=0b00000010;
    puerto_B=(DISPLAY[deci]);
    delay_ms(5);
}
void Delay_1seg()
{
   retardo=250;
   while(retardo>0)
   {
      Mostrar_Dato();
      retardo--;
   }
}
void main()
                                                                                     23
{
    port_b_pullups(true);                     // Activa los pull ups del puerto B
    cuenta=0;
    while(true)
    {
        if (cuenta<100)
        {
           Delay_1seg();
           cuenta++;
        }
        else
          cuenta=0;
    }
}
                                                                                 RN1
                                                                             1         16
                                                                             2         15
                                                                             3         14
                                                                             4         13
                                                                             5         12
                                                                             6         11
                                                                             7         10
        C3                                                                   8         9
                                                                                 RX8
        22pF                   U1
                          13                                      33
                                OSC1/CLKIN              RB0/INT
                X2        14
                                OSC2/CLKOUT                RB1
                                                                  34
                CRYSTAL                                           35
                                                           RB2
                           2                                      36
        C4                      RA0/AN0                RB3/PGM
                           3                                      37
                                RA1/AN1                    RB4
                           4                                      38
                                RA2/AN2/VREF-/CVREF        RB5
                           5                                      39
                                RA3/AN3/VREF+          RB6/PGC
        22pF               6                                      40
                                RA4/T0CKI/C1OUT        RB7/PGD
                           7
                                RA5/AN4/SS/C2OUT
                                                                  15
                                              RC0/T1OSO/T1CKI
                           8                                      16
                                RE0/AN5/RD      RC1/T1OSI/CCP2
                           9                                      17
                                RE1/AN6/WR            RC2/CCP1
                          10                                      18
                                RE2/AN7/CS        RC3/SCK/SCL
                                                   RC4/SDI/SDA
                                                                  23                        R3       R4
                           1                                      24                        1k       1k
                                MCLR/Vpp/THV           RC5/SDO
                                                                  25
                                                     RC6/TX/CK
                                                                  26
                                                     RC7/RX/DT
                                                                  19
                                                      RD0/PSP0
                                                      RD1/PSP1
                                                                  20
                                                                       R1                   Q1       Q2
                                                                  21                        BC548C   BC548C
                                                      RD2/PSP2
                                                                  22   220
                                                      RD3/PSP3
                                                                  27
                                                      RD4/PSP4
                                                                  28
                                                      RD5/PSP5
                                                                  29
                                                                       R2
                                                      RD6/PSP6
                                                                  30   220
                                                      RD7/PSP7
                               PIC16F877A
                                                                                                              24
10. Uso de la interrupción externa por RB0/INT
Una señal externa que se aplica al pin RB0/INT produce la interrupción externa en el PIC y se
podrá determinar por software que flanco de la señal producirá la interrupción, el de subida
(cuando la señal pasa de un nivel 0 a 1) o el de bajada (cuando pasa de 1 a 0).
Ejemplo:
En este ejemplo se usa la interrupción externa a través del pin RB0/INT, para implementar una
alarma sencilla, que funciona de la siguiente manera:
   Cuando se pulse el sensor de alarma RB0 en la transición de alto a bajo y no esté cerrado el
    interruptor de desactivación de alarma RB1, se pondrá a uno el pin RB7 del PIC el cual
    polarizará directamente el transistor Q1, que a su vez activará el Micro-relé RL1 (Relé
    auxiliar), este a su vez activará un relé de potencia que activará una alarma conectada a
    220V.
   Una vez activada la alarma, permanecerá activa hasta que no desactivarla por medio del
    interruptor de desactivación de alarma (interruptor cerrado).
/*--------------------------------------------------------*\
| Ejemplo uso de interrupción externa por RB0             |
|                                                         |
| InterrupcionRB0.c                                       |
\*--------------------------------------------------------*/
#include <16F877.h>
#int_EXT
void EXT_isr(void){
    if (RB1)     //Si el interruptor de desactivación está abierto
    {
        RB7=1;   // activa la alarma conectada en RB7
        while(RB1); //mientras el RB1=1 bucle infinito
        RB7=0;   //cuando RB1=0, se desacactiva la alarma
    }
}
void main(){
    set_tris_b(0b01111111); //configura el Puerto B
    RB7=0;                  //inicializa RB7
    enable_interrupts(GLOBAL); //habilita interrupción global
    enable_interrupts(INT_EXT); //habilita interrupción externa
                                                                                             25
    ext_int_edge( H_TO_L );//habilita el flanco interrupción de H a L
   Para activar una carga con una potencia considerable, es necesario adaptar el circuito de
    salida para controlar con los pocos miliamperios que da el PIC la carga que se desea. Hay
    muchas formas de hacer esto, se puede utilizar un par de transistores en configuración
    Darlington y atacar directamente el relé de potencia o no utilizar relés y controlar la carga
    por medio de un Triac de potencia.
   Al igual que la directiva #byte para mapear un registro en la memoria RAM y utilizarlo
    como una variable más, con la directiva #bit identificador registro.bit se puede mapear un
    bit en concreto de un registro. Aunque CCS incluye funciones para el manejo de bits, está
    opción es muy cómoda de utilizar y hará que el código sea más portable para utilizar en otros
    compiladores.
   Dentro del bloque principal de la función main(), se tiene las sentencias que habilitan las
    interrupciones globales y la particular a RB0:
    enable_interrupts(GLOBAL);
    globalenable_interrupts(INT_EXT);
ext_int_edge(flanco)
Por ejemplo:
#bit INTEDG=0x81.6
                                                                                               26
   INTEDG=1; // Flanco ascendente
   INTEDG=0; // Flanco descendente
Para ver como CCS gestiona está interrupción, se simula el circuito en Proteus cargando el
archivo .cof en el PIC, para que permita la simulación paso a paso. Se para la simulación en el
bucle while de la función principal obteniéndose lo que se muestra en la siguiente figura:
                                                                                               27
El bit de señalización INTF no fue usado en este ejemplo, pero en cualquier otro ejemplo se
puede leer su valor y utilizarlo para lo que se desea.
                                                                           R2
                                                                           330R
       C1                                                                         Sensor de Alarma
                                                                                               R3
                                                                                              1k
       15p
                                    U1
                            13                                        33                                Activación/Desactivación de Alarma
                                     OSC1/CLKIN             RB0/INT
                X1          14
                                     OSC2/CLKOUT               RB1
                                                                      34
                CRYSTAL                                               35
                                                               RB2
                                2                                     36
       C2                            RA0/AN0               RB3/PGM
                                3                                     37
                                     RA1/AN1                   RB4
                                4                                     38
                                     RA2/AN2/VREF-/CVREF       RB5
                                5                                     39
                                     RA3/AN3/VREF+         RB6/PGC
       15p                      6                                     40               12 V                 12 V
                                     RA4/T0CKI/C1OUT       RB7/PGD
                                7
                                     RA5/AN4/SS/C2OUT
                                                                      15
                                                    RC0/T1OSO/T1CKI
                             8                                        16
                             9
                                     RE0/AN5/RD      RC1/T1OSI/CCP2
                                                                      17                      Micro-Relé
                                     RE1/AN6/WR            RC2/CCP1
                            10                                        18
                                     RE2/AN7/CS         RC3/SCK/SCL
                                                                      23
                                                        RC4/SDI/SDA
                                1
                                     MCLR/Vpp/THV           RC5/SDO
                                                                      24                                               RL1
                                                          RC6/TX/CK
                                                                      25                       D1                      12V
                                                                      26    R4                 1N4007
                                                          RC7/RX/DT
                          R1                              RD0/PSP0
                                                                      19    330R
                          330                                         20
                                                          RD1/PSP1                                                   R.Potencia
                                                          RD2/PSP2
                                                                      21                      Q1                                             Alarma
                                                                      22                      BC547
                                                          RD3/PSP3
                                                                      27
                                                          RD4/PSP4
                                                                      28                                                               RL2       L1
                                                          RD5/PSP5                                                                               12V
                                                                      29                                                               12V
                                                          RD6/PSP6
                                                          RD7/PSP7
                                                                      30                                              D2
                                                                                                                      1N4007
                                    PIC16F877A
                                                                                                                                                   28
11. Uso de la Interrupción por cambio de estado en RB4-RB7
Para que se produzca la interrupción por cambio del estado lógico en alguna de las 4 líneas de
mayor peso del Puerto B (RB7-RB4) del PIC, dichas líneas tienen que estar previamente
configuradas como entradas. Este recurso hardware es muy utilizado para el control de teclados.
Ejemplo:
En este ejemplo se trata de la gestión de un mini teclado formado solo por cuatro teclas
representadas por los pulsadores del 1 al 4. El valor en decimal de la tecla pulsada se mostrará en
un display de cátodo común. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de
4Mhz.
Los cuatro bits menos significativos del Puerto B en el circuito están fijados a uno mediante la
resistencia R0, por ejemplo si se pulsa el pulsador 1 se pone RB4=0 y el valor binario a la
entrada del Puerto B será:
Que en decimal tendrá un valor de 239, de la misma forma se determinan los valores para las
otras posibles entradas, teniendo en cuenta que solo un pulsador esté pulsado; el resto de valores
son: 223, 191 y 127.
En la siguiente tabla se muestran los valores a utilizar para configurar el display de siete
segmentos en cátodo común.
                                                              Valor
                              Display Dígito g f e d c b a
                                                              Hex.
                                         0    011 1 1 1 1       3F
                                         1    000 0 1 1 0       06
                                         2    101 1 0 1 1       5B
                                         3    100 1 1 1 1       4F
                                         4    110 0 1 1 0       66
                                         5    1 1 0 1 1 0 1 6D
                                         6    1 1 1 1 1 0 1 7D
                                         7    000 0 1 1 1       07
                                         8    111 1 1 1 1       7F
                                         9    110 1 1 1 1       6F
#include <16F877.h>
#int_RB
void RB_isr(void)             // Función de interrupcion
{
    switch(puerto_B)
    {
    case 239:
             puerto_D    = 0x06;
             break;
    case 223:
             puerto_D    = 0x5B;
             break;
    case 191:
             puerto_D    = 0x4F;
             break;
    case 127:
             puerto_D    = 0x66;
             break;
    default:
             break;
    }
}
void main()
{
    set_tris_b(0xFF);               // Puerto B como entrada
    set_tris_d(0x00);               // Puerto D como salida.
    while(True)
    {
        //codigo principal
    }
}
   Dentro de la función principal se configura el puerto B como entradas digitales, (recordar que
    es un requisito que RB4-RB7 estén configuradas como entradas para la utilización de esta
    interrupción) y el Puerto D como salida ya que es donde se conecta el display de siete
    segmentos (como es de cátodo común, sus entradas serán activas con nivel alto).
puerto_D=0x00;
   Luego viene un bucle while infinito, la ejecución del programa permanecerá aquí, hasta que
    se produzca la interrupción.
   Dentro de la función de interrupción se chequea el valor en decimal del puerto B por medio
    de una sentencia de control switch y según sea la tecla pulsada muestra su valor en el
    display.
Para ver como CCS gestiona está interrupción, se simula el circuito en Proteus cargando el
archivo .cof en el PIC, para que permita la simulación paso a paso, al igual que se hizo con el
ejemplo de la interrupción externa por RB0/INT. Para parar el programa dentro de la función
de interrupción se puede poner un breakpoint dentro de cualquiera de las sentencias case.
El valor del registro INTCON según la secuencia del programa será la siguiente:
Al producirse la interrupción:
Al salir de la interrupción:
Hasta aquí CCS gestiona la interrupción por cambio de estado en RB4:RB7 de forma similar a
como lo hacía con la interrupción externa RB0/INT, es decir, gestionando la habilitación del bit
GIE y controlando el valor del flag RBIF, según se esté dentro o fuera de la función de
interrupción, todo ello de forma transparente para el programador.
Pero en este caso hay un paso que los creadores del compilador se han pasado por alto y obliga al
programador a tener en cuenta cuando se trabaje con este tipo de interrupción y es la siguiente:
                                                                                              31
"Es necesario una lectura (ó escritura) del Puerto B cuando se produzca esta interrupción, en este
ejemplo no hay problema porque nada más entrar en la función de interrupción se lee el estado
del puerto por medio de la sentencia switch (puerto_B). Pero en el ejemplo de la alarma que se
hizo por activación de la interrupción externa RB0/INT, cuando la alarma está desactivada y se
pulsa el sensor de alarma, la secuencia del programa entra en la función de interrupción pero no
hace nada dentro de ella, si se implementaría ese mismo circuito pero con cuatro sensores de
alarma y utilizando la interrupción por cambio de estado en RB4:RB7, si no se incluye una
lectura del puerto dentro de la función de interrupción, aunque no sirva para nada, el programa se
vuelve loco y no funciona bien este recurso del PIC".
        C1
                                                                              R0      R1          R2     R3     R4
        15p                                                                   330R    330R        330R   330R   330R
                                       U1
                               13                                        33
                                        OSC1/CLKIN            RB0/INT
                   X1          14
                                        OSC2/CLKOUT              RB1
                                                                         34
                                                                         35
                   CRYSTAL
                                   2
                                                                 RB2
                                                                         36
                                                                                                                       1
        C2                              RA0/AN0              RB3/PGM
                                   3                                     37
                                        RA1/AN1                  RB4
                                   4                                     38
                                   5
                                        RA2/AN2/VREF-/CVREF      RB5
                                                                         39
                                                                                                                       2
                                        RA3/AN3/VREF+        RB6/PGC
        15p                        6                                     40
                                        RA4/T0CKI/C1OUT      RB7/PGD
                                   7
                                        RA5/AN4/SS/C2OUT
                                                                         15
                                                                                                                       3
                                                      RC0/T1OSO/T1CKI
                                8                                        16
                                        RE0/AN5/RD      RC1/T1OSI/CCP2
                                9                                        17
                               10
                                        RE1/AN6/WR            RC2/CCP1
                                                                         18
                                                                                                                       4
                                        RE2/AN7/CS        RC3/SCK/SCL
                                                                         23
                                                           RC4/SDI/SDA
                                   1                                     24
                                        MCLR/Vpp/THV           RC5/SDO
                                                                         25
                                                             RC6/TX/CK
                                                                         26
                                                             RC7/RX/DT               RN1
                             R5                              RD0/PSP0
                                                                         19      1           16
                             330                                         20      2           15
                                                             RD1/PSP1
                                                                         21      3           14
                                                             RD2/PSP2
                                                                         22      4           13
                                                             RD3/PSP3
                                                                         27      5           12
                                                             RD4/PSP4
                                                                         28      6           11
                                                             RD5/PSP5
                                                                         29      7           10
                                                             RD6/PSP6
                                                                         30      8           9
                                                             RD7/PSP7
                                       PIC16F877A                                    RX8
                                                                                                                           32
12. Uso del TMR0 como contador utilizando interrupción
El Timer0 es un temporizador/contador ascendente de 8 bits, cuando trabaja con el reloj del PIC
se le suele llama temporizador y cundo los pulsos los recibe de una fuente externa a través del
pin RA4/TOCKI se le llama contador.
Ejemplo:
Utilizar el TIMER0 con una frecuencia de reloj externa al microcontrolador, la señal externa se
aplica al pin RA4/TOCKI del PIC, dicha señal se la utilizará para generar una interrupción a
través del TIMER0 cada segundo, en la función de interrupción se implementará el código
necesario para hacer parpadear un Led en el pin RB7 del PIC. El PIC a utilizar es el PIC16F877 a
una frecuencia de oscilación de 4Mhz.
Análisis de programa:
El cálculo del tiempo de interrupción (overflow) del TIMER0 de 1 segundo con una frecuencia
de reloj externa de 400 Hz (no está multiplicada por 4) y un Preescaler de 4 (se podía a ver
elegido otro cualquiera que estuviera en la tabla), se utiliza con la siguiente fórmula:
Entonces, para calcular el valor con el que se tiene que inicializar el TMR0 (N1) para que se
produzca su desbordamiento cada segundo, se despeja ValorTMR0 obteniéndose un valor de 156
que en hexadecimal es de 0x9C.
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
Las palabras utilizadas en esta función para declarar los parámetros definen ya su significado.
#include <16F877.h>
#fuses XT,NOWDT
#use delay(clock=4000000)
#int_TIMER0 //la siguiente función tiene que ser la de interrupción del TMR0
void TIMER0_isr(void) //función interrupción TMR0
{
    if (RB7==0)
    {
                                                                                                  33
            RB7=1;
            set_TIMER0(0x9C); //inicializa el Timer0
     }
     else
     {
         RB7=0;
         set_TIMER0(0x9C); //inicializa el Timer0
     }
void main()
{
    setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
C1
          15p                       U1
                               13                                    33
                                     OSC1/CLKIN            RB0/INT
                               14                                    34
                                     OSC2/CLKOUT              RB1
                    X1          1
                                     MCLR/Vpp/THV             RB2
                                                                     35
                    CRYSTAL                                          36
                                                          RB3/PGM                    A
                                2                                    37
          C2                         RA0/AN0                  RB4
                                3                                    38
                                     RA1/AN1                  RB5                    B
                                4                                    39
                                5
                                     RA2/AN2/VREF-        RB6/PGC
                                                                     40
                                                                          R2
                                     RA3/AN3/VREF+        RB7/PGD                    C
          15p                   6                                         300
                                     RA4/T0CKI
                                7                                    15
                                     RA5/AN4/SS    RC0/T1OSO/T1CKI                   D
                                                                     16
                                                    RC1/T1OSI/CCP2
                                8                                    17
                                     RE0/AN5/RD           RC2/CCP1
                         R3     9
                                     RE1/AN6/WR        RC3/SCK/SCL
                                                                     18         D1
                         10k   10                                    23         LED-RED
                                     RE2/AN7/CS        RC4/SDI/SDA
                                                                     24
                                                           RC5/SDO
                                                                     25
                                                         RC6/TX/CK
                                                                     26
                                                         RC7/RX/DT
                                                                     19
                                                         RD0/PSP0
                                                                     20
                                                         RD1/PSP1
                                                                     21
                                                         RD2/PSP2
                                                                     22
                                                         RD3/PSP3
                                                                     27
                                                         RD4/PSP4
                                                                     28
                                                         RD5/PSP5
                                                                     29
                                                         RD6/PSP6
                                                                     30
                                                         RD7/PSP7
U1(RA4/T0CKI)
                                    PIC16F877
                                                                                          34
13. Uso del TMR0 como temporizador utilizando interrupción
Ejemplo:
Este ejemplo usa el TIMER0 para generar una interrupción cada 32 mseg utilizando el reloj
interno del microcontrolador. La función de interrupción se utilizará para hacer parpadear un Led
en el pin RB7 del PIC. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz..
El cálculo del tiempo de interrupción (overflow) del TIMER0 con una frecuencia de reloj
interna, se utiliza con la siguiente fórmula:
Entonces, para calcular el valor con el que se tiene que inicializar el TMR0 (N1) para que se
produzca su desbordamiento cada 32 mseg, se despeja ValorTMR0 obteniéndose un valor de 131
que en hexadecimal es 0x83.
#include <16F877.h>
#use delay(clock=4000000)
#int_TIMER0
void TIMER0_isr(void)
{
    if (RB7==0)
    {
        RB7=1;
        set_TIMER0(0x83); //inicializa el Timer0
    }
    else
    {
        RB7=0;
        set_TIMER0(0x83); //inicializa el Timer0
    }
}
                                                                                              35
void main()
{
    set_tris_b(0b01111111); //configura RB7 como salida y el resto como entrada
    RB7=0; //inicializa el bit RB7 a 0;
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
C1
         15p                        U1
                               13                                    33
                                     OSC1/CLKIN            RB0/INT
                               14                                    34
                                     OSC2/CLKOUT              RB1
                    X1          1
                                     MCLR/Vpp/THV             RB2
                                                                     35
                    CRYSTAL                                          36
                                                          RB3/PGM                    A
                                2                                    37
         C2                          RA0/AN0                  RB4
                                3                                    38
                                     RA1/AN1                  RB5                    B
                                4                                    39
                                5
                                     RA2/AN2/VREF-        RB6/PGC
                                                                     40
                                                                          R2
                                     RA3/AN3/VREF+        RB7/PGD                    C
         15p                    6                                         300
                                     RA4/T0CKI
                                7                                    15
                                     RA5/AN4/SS    RC0/T1OSO/T1CKI                   D
                                                                     16
                                                    RC1/T1OSI/CCP2
                                8                                    17
                                     RE0/AN5/RD           RC2/CCP1
                                9
                                     RE1/AN6/WR        RC3/SCK/SCL
                                                                     18         D1
                         R1    10
                                     RE2/AN7/CS        RC4/SDI/SDA
                                                                     23         LED-RED
                         10k                                         24
                                                           RC5/SDO
                                                                     25
                                                         RC6/TX/CK
                                                                     26
                                                         RC7/RX/DT
                                                                     19
                                                         RD0/PSP0
                                                                     20
                                                         RD1/PSP1
                                                                     21
                                                         RD2/PSP2
                                                                     22
                                                         RD3/PSP3
                                                                     27
                                                         RD4/PSP4
                                                                     28
                                                         RD5/PSP5
                                                                     29
                                                         RD6/PSP6
                                                                     30
                                                         RD7/PSP7
                                    PIC16F877
                                                                                              36
14. Uso del TMR0 como contador o temporizador utilizando
    interrupción
Ejemplo:
1. Utilizar el TIMER 0 como temporizador. Utilizar el Timer0 para generar una interrupción
   cada 32 mseg, mediante el reloj interno del microcontrolador. La función de interrupción se
   utilizará para hacer parpadear un LED en el pin RB7 del PIC. La frecuencia de la señal de
   reloj que se utiliza será de un cristal de 4 MHz.
Si se despeja el valor del TMR0 sale un valor de 131 que en hexadecimal es 0x83.
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
                                                                                              37
    reloj externa que se utiliza será de 400 Hz y el Timer 0 se configura para que empiece a
    contar en el flanco de subida de la señal de reloj.
    Para el cálculo, debe tener en cuenta que se quiere tener una interrupción cada segundo, en la
    siguiente fórmula la frecuencia de reloj externa no está multiplicada por 4. Se elige un
    Preescaler, en este ejemplo 4, (se puede a ver elegido otro cualquiera que estuviera en la
    tabla) y se calcula el valor con el que se tiene que inicializar el TMR0; para que se produzca
    su desbordamiento cada segundo.
    Si se despeja ValorTMR0, corresponde al valor inicial que se tiene que cargar en el TMR0,
    que será el valor 156 que en hexadecimal es de 0x9C.
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
    NOTA: Si el TMR0 empieza a contar desde 0, se tendrá un Overflow de 2.5 seg, esto es lo
    que saldría en la fórmula.
#include <16F877.h>
#use delay(clock=4000000)
#int_TIMER0
void TIMER0_isr(void)
{
    if (RB6)
    {
         setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
         set_TIMER0(0x83); // Inicializa el timer0
    }
    else
    {
        setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
        set_TIMER0(0x9C); // Inicializa el timer0
    }
    if (RB7==0)
        RB7=1;
    else
        RB7=0;
}
void main()
{
    set_tris_b(0b01111111); // Configura RB7 como salida el resto como entrada
    RB7=0;                  // Inicializo el bit RB7 a 0;
                                                                                               38
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
C1
          15p                        U1                                          R3
                                13                                    33         300
                                      OSC1/CLKIN            RB0/INT
                                14                                    34
                                      OSC2/CLKOUT              RB1
                      X1         1
                                      MCLR/Vpp/THV             RB2
                                                                      35
                      CRYSTAL                                         36
                                                           RB3/PGM
                                 2                                    37
          C2                          RA0/AN0                  RB4
                                 3                                    38
                                      RA1/AN1                  RB5
                                 4                                    39
                                 5
                                      RA2/AN2/VREF-        RB6/PGC
                                                                      40
                                                                           R2
                                      RA3/AN3/VREF+        RB7/PGD
          15p                    6                                         300
                                      RA4/T0CKI
                                 7                                    15
                                      RA5/AN4/SS    RC0/T1OSO/T1CKI
                                                                      16
                                                     RC1/T1OSI/CCP2
                                 8                                    17
                                      RE0/AN5/RD           RC2/CCP1
                       R4        9
                                      RE1/AN6/WR        RC3/SCK/SCL
                                                                      18          D1
                       10k      10                                    23          LED-RED
                                      RE2/AN7/CS        RC4/SDI/SDA
                                                                      24
                                                            RC5/SDO
                                                                      25
                                                          RC6/TX/CK
                                                                      26
                                                          RC7/RX/DT
                                                                      19
                                                          RD0/PSP0                          A
                                                                      20
                                                          RD1/PSP1
                                                                      21
                                                          RD2/PSP2                          B
                                                                      22
                                                          RD3/PSP3
                                                                      27
                                                          RD4/PSP4                          C
                                                                      28
                                                          RD5/PSP5
                                                                      29
                                                          RD6/PSP6                          D
                                                                      30
                                                          RD7/PSP7
    U1(RA0/AN0)
                                     PIC16F877
                                                                                                39
15. Uso del TMR1 como Temporizador utilizando interrupción
   La primera de ellas, es que se trata de un contador de 16 bits cuyo valor se almacena en dos
    registros de 8 bits el TMR1H y el TMR1L, ambos registros se pueden leer y escribir su valor
    durante la ejecución del programa.
   Cuando el Timer1 está habilitado, el valor de los registros TMR1H y TMR1L se incrementan
    desde 0000h a FFFFh, y una vez que llega a su máximo valor empieza otra vez desde 0
    notificando de ello por medio de la bandera TMR1F.
     El Timer1 puede funcionar con un oscilador externo y trabajar a una frecuencia distinta a
      la del oscilador principal del PIC.
     Al igual que el TMR0 el Timer1 puede operar en dos modos: como temporizador y como
      contador. El modo de funcionamiento está determinado por el tipo de reloj seleccionado
      (interno como temporizador, externo como contador), se lo configura por medio del bit
      TMR1CS del registro TICON. Cuando está en modo contador su valor se incrementa en
      cada flanco de subida de la señal de reloj externa.
     El tiempo que se tarda en incrementarse el contador se le suele llamar paso, el paso del
      contador depende de la frecuencia del oscilador y del preescaler seleccionado.
     La fórmula para determinar los tiempos del Timer1 cuando es utilizado como temporizador
      (reloj interno) es la siguiente:
       El Timer1 se puede habilitar o deshabilitar por medio del bit TMR1ON del registro
        T1CON.
Ejemplo:
En este ejemplo se utiliza el Timer1 como temporizador usando el reloj interno del micro. El
ejemplo consiste simplemente en hacer parpadear un led a un intervalo de 0.5 segundos, usando
el Timer1 con la interrupción por desbordamiento habilitada. El PIC a utilizar es el PIC16F877 a
una frecuencia de oscilación de 4Mhz.
                                                                                             40
La resolución es el tiempo que tarda el contador en incrementar su valor, es decir, el paso del
contador. Este valor depende del Preescaler seleccionado y de la frecuencia del reloj principal.
Por ejemplo, si se selecciona la última opción corresponde al preescaler de 8 y se selecciona una
frecuencia de 4MHz para el reloj principal, el paso del contador será igual a:
El Overflow del Timer1 es el tiempo que tardará el contador en desbordarse. Suponiendo que se
carga el TMR1 con valor 0, que es como viene por defecto, al aplicar la fórmula se obtiene el
valor de 524 mseg (desbordamiento_Timer1= 4/4MHz x 8(65536-0)= 524 mseg).
En vez de 524 mseg, se quiere obtener 500 mseg, se sustituye ese valor en la fórmula y
despejando el valor a cargar en el TMR1, se tiene:
#int_TIMER1
void TIMER1_isr(void)//Función de interrupción por desbordamiento TMR1
{
    RB7=~RB7; //Togle RB7
    set_timer1(0x0BDC);//carga del TMR1
}
void main()
{
    set_tris_b(0b01111111); //configura RB7 como salida y el resto como entrada
    RB7=0;//Inicializa RB7
    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//Setup timer: Reloj interno, preescaler= 8
    enable_interrupts(INT_TIMER1);//Habilita interrupción particular del TIMER1
    enable_interrupts(GLOBAL);//Habilita interrupciones globales
    set_timer1(0x0BDC);//Carga del TMR1
    while(true);//Bucle infinito hasta la interrupción
}
En el programa está explicado con los comentarios hechos en el código fuente. Falta solo
comentar las funciones que incluye CCS para el control del Timer1:
              Este pequeño detalle que parece poco importante, no lo es en el caso de que se quiera
              contar de manera precisa los pulsos de entrada.
              setup_timer_1 ( T1_DISABLED );
              setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_4 );
              setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
C1
        15p                            U1
                                  13                                    33
                                        OSC1/CLKIN            RB0/INT
                                  14                                    34
                                        OSC2/CLKOUT              RB1
                        X1         1
                                        MCLR/Vpp/THV             RB2
                                                                        35
                                                                                             A
                        CRYSTAL                                         36
                                                             RB3/PGM
                                   2                                    37
        C2                              RA0/AN0                  RB4                         B
                                   3                                    38
                                        RA1/AN1                  RB5
                                   4                                    39
                                   5
                                        RA2/AN2/VREF-        RB6/PGC
                                                                        40
                                                                             R2              C
                                        RA3/AN3/VREF+        RB7/PGD
        15p                        6                                         300
                                        RA4/T0CKI                                            D
                                   7                                    15
                                        RA5/AN4/SS    RC0/T1OSO/T1CKI
                                                                        16
                                                       RC1/T1OSI/CCP2
                                   8                                    17
                                        RE0/AN5/RD           RC2/CCP1
                         R1        9
                                        RE1/AN6/WR        RC3/SCK/SCL
                                                                        18         D1
                         10k      10                                    23         LED-RED
                                        RE2/AN7/CS        RC4/SDI/SDA
                                                                        24
                                                              RC5/SDO
                                                                        25
                                                            RC6/TX/CK
                                                                        26
                                                            RC7/RX/DT
                                                                        19
                                                            RD0/PSP0
                                                                        20
                                                            RD1/PSP1
                                                                        21
                                                            RD2/PSP2
                                                                        22
                                                            RD3/PSP3
                                                                        27
                                                            RD4/PSP4
                                                                        28
                                                            RD5/PSP5
                                                                        29
                                                            RD6/PSP6
                                                                        30
                                                            RD7/PSP7
                                       PIC16F877
                                                                                                 42
16. Uso de la memoria EEPRO interna
La memoria EEPROM de datos no está mapeada en la zona de la memoria de datos de propósito
específico y general, donde se ubican los registros SFR y GPR.
CCS permite separar por completo del proceso de lectura y escritura de la memoria EEPROM, lo
único que se tiene que saber es las funciones que se deben aplicar y los parámetros y valores que
devuelven dichas funciones. CCS implementa muchas funciones para trabajar con las memorias
EEPROM, algunas de ellas son:
CCS también incorpora funciones para leer y escribir en memorias EEPROM externas:
Como se ve CCS aporta una serie de funciones para trabajar fácilmente con este tipo de
memorias, estas funciones son algunas de ellas, pero todavía hay más.
   Son rápidas en el proceso de lectura, pero pueden tardar varios mseg en realizar un proceso
    de escritura.
   Se pueden hacer operaciones de lectura sobre el valor de sus registros el número de veces
    que se quiera, pero soportan un número limitado de ciclos de escritura / borrado. Ese número
    según Microchip es de aproximadamente un millón.
Ejemplo:
                                                                                               43
En este ejemplo se va a utilizar las funciones básicas para leer y escribir datos en la memoria
interna EEPROM del PIC: read_eeprom (address) y write_eeprom (address, value), para lo cual
se va a realizar un contador del tipo "su turno" que se encuentra en algunos establecimientos
como carnicerías y pescaderías. Como funcionalidades mínimas se ha puesto que sea capaz de
contar del 0 al 99. Y por supuesto que si se va la corriente guarde en memoria el último valor. El
PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
Analizar el problema:
Cuando se quiere utilizar más de un display para minimizar el número de pines en el PIC, hay
varias formas de hacer su control, a continuación se muestran dos formas:
2. Otra forma es multiplexar las líneas de datos (la que se ha utilizado en este ejemplo), es decir
   en cada instante solo habrá un display activo pero el cambio de uno a otro será tan rápido que
   para el ojo humano parecerá que los dos están activos a la vez, este sistema es bueno porque
   ahorra los decodificadores, pero si se utiliza más de cuatro display, se nota un parpadeo
   molesto.
/******************************************************************************
*                                                                             *
* DESCRIPCIÓN: Uso de la memoria EEPROM del PIC                               *
* Memoria_EEPROM.c                                                            *
*                                                                             *
******************************************************************************/
#include <16F877.h>
void Mostrar_Dato();
void Delay_1seg();
#int_EXT
void EXT_isr( void )
{
    if ((read_eeprom(0)==0x99)||(read_eeprom(0)==0xFF))
    {
        write_eeprom(0,0);
        cuenta=read_eeprom(0);
                                                                                                44
      }
      else
      {
          write_eeprom(0,(read_eeprom(0))+1);
          cuenta=read_eeprom(0);
      }
      Delay_1seg();
 }
void Mostrar_Dato()
{
   int uni,deci;
     deci=cuenta/10;
     uni=cuenta%10;
     puerto_D=0b00000001;
     puerto_C=(DISPLAY[uni]);
     delay_ms(5);
     puerto_D=0b00000010;
     puerto_C=(DISPLAY[deci]);
     delay_ms(5);
}
void Delay_1seg()
{
   retardo=250;
   while(retardo>0)
   {
      Mostrar_Dato();
      retardo--;
   }
}
void main()
{
   port_b_pullups(true);           // Activa los pull ups del puerto B
         while(true)
     {
         //Resto del programa
     }
}
   La primera vez que se ejecute el programa el valor de la EEPROM es 0xFF (viene así de
    fábrica) por lo que se tiene que sobrescribir su valor a 0x00 para iniciar la cuenta, después de
    esto esta condición solo se cumplirá cuando el contador llegue a 99.
    if ((read_eeprom(0)==0x99)||(read_eeprom(0)==0xFF))
    {
        write_eeprom(0,0);      // Escribe el valor 0 en la dirección 0 de la
                                // memoria EEPROM.
        cuenta=read_eeprom(0); // Asigna al puerto D el valor devuelto por la
                                // funcion de lectura de la EEPROM.
    }
    else
    {
        write_eeprom(0,(read_eeprom(0))+1); // Escribe el valor leído de la
                                 // memoria EPROM incrementado en 1 en la
                                 // direccion 0 de la memoria EEPROM.
        cuenta=read_eeprom(0);
    }
    En la función de escritura permite poner como parámetro la función de lectura, por lo que no
    es necesario declarar una variable local para hacer la lectura y escritura a la vez.
   Para poder ver los registros de la EEPROM interna del PIC en Proteus, se selecciona Debug
    --> PIC CPU EPROM Memory. Proteus simula bastante bien el uso de la memoria EEPROM
    del PIC, si se para la simulación y se vuelve a iniciarla se ve como los valores de la
    EEPROM se mantienen.
                                                                                                 46
                                                        R5
                                                        10k
                                                                         RN1
                                                                     1         16
                                                                     2         15
                                         Su Turno                    3         14
                                                                     4         13
                                                                     5         12
                                                                     6         11
                                                                     7         10
C3                                                                   8         9
                                                                         RX8
22pF                  U1
                 13                                       33
                       OSC1/CLKIN             RB0/INT
       X2        14
                       OSC2/CLKOUT               RB1
                                                          34
       CRYSTAL                                            35
                                                 RB2
                  2                                       36
C4                     RA0/AN0               RB3/PGM
                  3                                       37
                       RA1/AN1                   RB4
                  4                                       38
                       RA2/AN2/VREF-/CVREF       RB5
                  5                                       39
                       RA3/AN3/VREF+         RB6/PGC
22pF              6                                       40
                       RA4/T0CKI/C1OUT       RB7/PGD
                  7
                       RA5/AN4/SS/C2OUT
                                                          15
                                     RC0/T1OSO/T1CKI
                  8                                       16
                       RE0/AN5/RD      RC1/T1OSI/CCP2
                  9                                       17
                       RE1/AN6/WR            RC2/CCP1
                 10                                       18
                       RE2/AN7/CS        RC3/SCK/SCL
                                          RC4/SDI/SDA
                                                          23                        R3       R4
                  1                                       24                        1k       1k
                       MCLR/Vpp/THV           RC5/SDO
                                                          25
                                            RC6/TX/CK
                                                          26
                                            RC7/RX/DT
                                                          19
                                            RD0/PSP0
                                            RD1/PSP1
                                                          20
                                                               R1                   Q1       Q2
                                                          21                        BC548C   BC548C
                                            RD2/PSP2
                                                          22   220
                                            RD3/PSP3
                                                          27
                                            RD4/PSP4
                                                          28
                                            RD5/PSP5
                                                          29
                                                               R2
                                            RD6/PSP6
                                                          30   220
                                            RD7/PSP7
                      PIC16F877A
                                                                                                      47
17. Control de varia interrupciones
Ejemplo:
La aplicación establece la ejecución de las tres siguientes tareas a una velocidad tal que se
asemeja con una ejecución paralela:
/******************************************************************************
*                                                                             *
* DESCRIPCIÓN: Control de varias interrupciones                               *
* Varias_Interrupciones.c                                                     *
*                                                                             *
******************************************************************************/
#include <16f877a.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT,NOLVP
#define LED1 1
#define LED2 2
#define LED3 3
int nTick;
#int_RTCC
void RTCC_isr() //realiza cambio de estado de D3 en cada overflow del TMR0
{
   if (bit_test(PORTB, LED3))
      output_low(PIN_B3);
   else
      output_high(PIN_B3);
}
void main()
{
   set_tris_b(0xF0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);
    enable_interrupts(INT_RTCC);
    enable_interrupts(INT_RB);
    enable_interrupts(GLOBAL);
    while(TRUE) {
       delay_ms(1000);                    //Cambio de estado del led D1
        if (bit_test(PORTB, LED1))
           output_low(PIN_B1);
        else
           output_high(PIN_B1);
        if (bit_test(PORTB, LED2)) {
           nTick--;
           if ( nTick == 0)
              output_low(PIN_B2);
        }
    }
}
El control de interrupción verifica el evento generado por una interrupción, por lo cual, no es
necesario realizar una verificación para determinar qué evento fue generado, por lo que se
ejecuta la función correspondiente. Es este caso la funciones para los eventos: sobre flujo del
Timer0 y cambio de estado de las patitas RB3, … RB0, serían:
#int_RTCC
RTCC_isr()
#int_RB
RB_isr()
                                                                                            49
                                                                 A
                                                                       D1
                                                           R2
                                                           300
                                                                       LED-RED
C1
                                                                       D2
                                                           R3
15p                  U1                                    300
                13                                    33               LED-RED
                      OSC1/CLKIN            RB0/INT
                14                                    34
                      OSC2/CLKOUT              RB1                     D3
      X1         1
                      MCLR/Vpp/THV             RB2
                                                      35
                                                           R4
      CRYSTAL                                         36
                                           RB3/PGM
                 2                                    37   300
C2                    RA0/AN0                  RB4
                 3                                    38               LED-RED
                      RA1/AN1                  RB5
                 4                                    39
                      RA2/AN2/VREF-        RB6/PGC
                 5                                    40
                      RA3/AN3/VREF+        RB7/PGD
15p              6
                      RA4/T0CKI
                 7                                    15
                      RA5/AN4/SS    RC0/T1OSO/T1CKI
                                                      16
                                     RC1/T1OSI/CCP2
                 8                                    17
                      RE0/AN5/RD           RC2/CCP1
                 9
                      RE1/AN6/WR        RC3/SCK/SCL
                                                      18         R6    R7        R8    R9
      R1        10
                      RE2/AN7/CS        RC4/SDI/SDA
                                                      23         300   300       300   300
      330                                             24
                                            RC5/SDO
                                                      25
                                          RC6/TX/CK
                                                      26
                                          RC7/RX/DT
                                                      19
                                          RD0/PSP0
                                                      20
                                          RD1/PSP1
                                                      21
                                          RD2/PSP2
                                                      22
                                          RD3/PSP3
                                                      27
                                          RD4/PSP4
                                                      28
                                          RD5/PSP5
                                                      29
                                          RD6/PSP6
                                                      30
                                          RD7/PSP7
                     PIC16F877
                                                                                             50
18. Mostrar un mensaje por un LCD conectado al puerto B
Ejemplo:
En este programa muestra un mensaje por una LCD conectada en el puerto B. El PIC a utilizar es el
PIC16F877 a una frecuencia de oscilación de 4Mhz.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// B2 -- E
// B3 ---RS
// B4 ---D4
// B5 ---D5
// B6 ---D6
// B7 ---D7
// (Sin 'RW') este pin del LCD se pone a tierra o masa.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
  lcd_init();               // inicializa el LCD
  lcd_putc(" Mensaje_LCD"); // Escribe en la LCD
}
                                                                                                               51
                                            LCD1
                                            LM016L
     U2
13                                     33
      OSC1/CLKIN            RB0/INT
14                                     34
      OSC2/CLKOUT              RB1
                                       35
                               RB2
 2                                     36
      RA0/AN0              RB3/PGM
 3                                     37
      RA1/AN1                  RB4
                                               VDD
                                               VSS
                                               VEE
 4                                     38
                                                     RW
                                                     RS
                                                          D0
                                                          D1
                                                          D2
                                                          D3
                                                          D4
                                                          D5
                                                          D6
                                                          D7
      RA2/AN2/VREF-/CVREF      RB5
                                                     E
 5                                     39
      RA3/AN3/VREF+        RB6/PGC
 6                                     40
      RA4/T0CKI/C1OUT      RB7/PGD
                                              1
                                              2
                                              3
                                                     4
                                                     5
                                                     6
                                                           7
                                                           8
                                                           9
                                                          10
                                                          11
                                                          12
                                                          13
                                                          14
 7
      RA5/AN4/SS/C2OUT
                                       15
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA
 1                                     24
      MCLR/Vpp/THV           RC5/SDO
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT
                                       19
                           RD0/PSP0
                                       20
                           RD1/PSP1
                                       21
                           RD2/PSP2
                                       22
                           RD3/PSP3
                                       27
                           RD4/PSP4
                                       28
                           RD5/PSP5
                                       29
                           RD6/PSP6
                                       30
                           RD7/PSP7
     PIC16F877A
                                                               52
19. Contador con LCD 2x16 conectada por puerto B
Ejemplo:
En este programa al pulsar a P1 se incrementará una cuenta de 0-255 y se mostrara por una pantalla
LCD 2x16, de igual manera al presionar a P2 se decrementará dicha cuenta. El PIC a utilizar es el
PIC16F877 a una frecuencia de oscilación de 4Mhz.
int A=0;
void main(void)
{
  lcd_init();                   // Inicia LCD
  lcd_putc(" Contador\n");     // Muestra texto en el LCD
  lcd_putc(" Digital");         // Muestra texto en el LCD
  delay_ms(2000);              // Retardo de 2 seg.
  lcd_putc("\f");               // Limpia pantalla del LCD
  lcd_putc(" Conteo\n");       // Muestra texto en el LCD
    while(true)
    {
      if(input(pin_A0)==0)      // Pregunta si RA0 es cero
      {
          A++;                    // Incrementa el conteo
          delay_ms(500);         // Para visualizar correctamente el conteo
          if(A>=255)              // Preguta si A es mayor o igual a 255,
          {                        // cuando sea igual iguala A a cero
             A=0;
          }
      }
      if(input(pin_A1)==0)       // Pregunta si RA1 es cero
      {
          A--;                    // Decrementa el conteo
          delay_ms(500);         // Para visualizar mejor la cuenta
          if(A==0)               // Pregunta si A llego a cero, cuando sea
          {                      // 0 iguala A a 255
             A=255;
          }
      }
                                                               LCD1
                                                               LM016L
P1
          R1R2          U2
          10k10k
                   13                                     33
                         OSC1/CLKIN            RB0/INT
                   14                                     34
                         OSC2/CLKOUT              RB1
                                                          35
P2                  2
                                                  RB2
                                                          36
                         RA0/AN0              RB3/PGM
                    3                                     37
                         RA1/AN1                  RB4
                                                                  VDD
                                                                  VSS
                                                                  VEE
                    4                                     38
                                                                        RW
                                                                        RS
                                                                             D0
                                                                             D1
                                                                             D2
                                                                             D3
                                                                             D4
                                                                             D5
                                                                             D6
                                                                             D7
                         RA2/AN2/VREF-/CVREF      RB5
                                                                        E
                    5                                     39
                         RA3/AN3/VREF+        RB6/PGC
                    6                                     40
                         RA4/T0CKI/C1OUT      RB7/PGD
                                                                 1
                                                                 2
                                                                 3
                                                                        4
                                                                        5
                                                                        6
                                                                              7
                                                                              8
                                                                              9
                                                                             10
                                                                             11
                                                                             12
                                                                             13
                                                                             14
                    7
                         RA5/AN4/SS/C2OUT
                                                          15
                                       RC0/T1OSO/T1CKI
                    8                                     16
                         RE0/AN5/RD      RC1/T1OSI/CCP2
                    9                                     17
                         RE1/AN6/WR            RC2/CCP1
                   10                                     18
                         RE2/AN7/CS        RC3/SCK/SCL
                                                          23
                                            RC4/SDI/SDA
                    1                                     24
                         MCLR/Vpp/THV           RC5/SDO
                                                          25
                                              RC6/TX/CK
                                                          26
                                              RC7/RX/DT
                                                          19
                                              RD0/PSP0
                                                          20
                                              RD1/PSP1
                                                          21
                                              RD2/PSP2
                                                          22
                                              RD3/PSP3
                                                          27
                                              RD4/PSP4
                                                          28
                                              RD5/PSP5
                                                          29
                                              RD6/PSP6
                                                          30
                                              RD7/PSP7
                        PIC16F877A
                                                                                  54
20. Teclado 4x3 LCD
Ejemplo:
#include <16F877A.h>
#fuses XT,NOCPD
#use delay(clock=4M)
#include <kbd_lib.c>
#include <lcd.c>
void main()
{
    int k;
    kbd_init();
    lcd_init();
lcd_putc("\fPresione...\n");
    while(TRUE)
    {
       k=kbd_getc();
       if(k!=0)
       {
          lcd_gotoxy(1,2);
          lcd_putc(k);
       }
    }
}
 En primer lugar se incluye las librerías para usar el teclado y el LCD, respectivamente:
    #include <kbd_lib.c>
                                                                                               55
    #include <lcd.c>
    lcd_init();
    kbd_init();
   Se puede envíar mensajes al LCD, en este caso "\fPresione...\n", que limpia la pantalla y
    pone el mensaje Presione..., y luego cambia de línea:
lcd_putc("\fPresione...\n");
   Para recibir la información del teclado, se realiza en un lazo infinito mediante una variable
    entera k, con la siguiente sentencia:
k=kbd_getc();
 Por último, se muestra la tecla pulsada en el LCD, fila 2 columna 1, mediante las sentencias:
       lcd_gotoxy(1,2);
       lcd_putc(k);
                                                                                               56
                                                      1
                                                                 3
                                                  A
                                                      1     2    3
                                                  B
                                                      4     5    6
                                                  C
                                                      7     8    9
     U1
13                                     33
14
      OSC1/CLKIN
      OSC2/CLKOUT
                            RB0/INT
                               RB1
                                       34
                                                  D
                                                            0    #
                                       35
                               RB2
 2                                     36
      RA0/AN0              RB3/PGM
 3                                     37
 4
      RA1/AN1                  RB4
                                       38
                                            R1    LCD2
 5
      RA2/AN2/VREF-/CVREF      RB5
                                       39
                                            R2    LM016L
 6
      RA3/AN3/VREF+        RB6/PGC
                                       40
                                            R3
                                            10k
 7
      RA4/T0CKI/C1OUT      RB7/PGD          R4
                                            10k
      RA5/AN4/SS/C2OUT                      10k
                                       15   10k
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA
                                                      VDD
                                                      VSS
                                                      VEE
 1                                     24
                                                            RW
                                                            RS
                                                                 D0
                                                                 D1
                                                                 D2
                                                                 D3
                                                                 D4
                                                                 D5
                                                                 D6
                                                                 D7
      MCLR/Vpp/THV           RC5/SDO
                                                            E
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT
                                                      1
                                                      2
                                                      3
                                                            4
                                                            5
                                                            6
                                                                  7
                                                                  8
                                                                  9
                                                                 10
                                                                 11
                                                                 12
                                                                 13
                                                                 14
                                       19
                           RD0/PSP0
                                       20
                           RD1/PSP1
                                       21
                           RD2/PSP2
                                       22
                           RD3/PSP3
                                       27
                           RD4/PSP4
                                       28
                           RD5/PSP5
                                       29
                           RD6/PSP6
                                       30
                           RD7/PSP7
     PIC16F877A
                                                                      57
21. Teclado 4x4 y enviar el valor a una PC vía Rs232 (serial) y a un
     display 7 segmentos
Ejemplo:
En este programa se ingresa una tecla desde un teclado 4x4 y se envía el valor a una PC vía RS232
(serial) y a un display 7 segmentos. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de
4Mhz.
/*----------------------------------------------------------------------------------------*\
| Ingreso tecla para enviar por la USART y a la PC.                                     |
|                                                                                          |
\*----------------------------------------------------------------------------------------*/
#include <16F877.h>
#FUSES XT, NOPROTECT
#use delay (clock = 4000000)
#define use_portb_kbd TRUE                 // Para usar puerto B, caso contrario usa puerto D
#include "kbd_lib.c"
void main()
{
  char c;
  port_b_pullups(true);      // Activa los pull ups del puerto B
printf("Comunicacion serie.\r\n");
    while(true)
    {
      c = kbd_getc();
      if(c != 0 )           // Si se ha pulsado una tecla
      {
          putc(c);         // Envia el caracter via serie por la USART del PIC
          Caracter_Display (c);
      }
    }
}
#include "kbd_lib.c"
        Esta librería es una modificación de "kbd.c" que incluye CCS en la carpeta Drivers, creada
        en la instalación del programa. La que viene por defecto controla un teclado de 4 (filas) x 3
        (Columnas). La modificación que se ha hecho permite controlar un teclado de 4 x 4. Al ver el
        código original es fácil hacer las modificaciones pertinentes para poder controlar un teclado
        personalizado.
                                                                                                  59
    NOTA: La configuración de las teclas se debe realizar de acuerdo al teclado a usar.
#define use_portb_kbd TRUE // Para usar puerto B, caso contrario usa puerto D
    Para usar el teclado elige el puerto B en lugar del puerto D, para usar el puerto D no se
    necesita esta instrucción.
   Una forma más simple de seleccionar el valor decodificado para ser mostrado en el display
    de 7 segmentos, que se utiliza en la sentencia switch(dato){}, es asignando los valores
    decodificados en un vector como se muestra a continuación:
puerto_D = valor_D[datos];
                                                                                               60
                                                                 A
                                                                     1   2   3   A
     U1
                                                                 B
                                                                     4   5   6   B
13                                     33
      OSC1/CLKIN            RB0/INT
14                                     34
      OSC2/CLKOUT              RB1
 2
                               RB2
                                       35
                                       36
                                                                 C
                                                                     7   8   9   C
      RA0/AN0              RB3/PGM
 3                                     37
      RA1/AN1                  RB4
 4                                     38
      RA2/AN2/VREF-/CVREF      RB5
 5
 6
      RA3/AN3/VREF+        RB6/PGC
                                       39
                                       40
                                                                 D
                                                                         0   #   D
      RA4/T0CKI/C1OUT      RB7/PGD
 7
                                                                                 4
      RA5/AN4/SS/C2OUT
                                       15
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA
 1                                     24
      MCLR/Vpp/THV           RC5/SDO
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT                  RN1
                                       19         1         16
                           RD0/PSP0
                                       20         2         15
                           RD1/PSP1
                                       21         3         14
                           RD2/PSP2
                                       22         4         13
                           RD3/PSP3
                                       27         5         12
                           RD4/PSP4
                                       28         6         11
                           RD5/PSP5
                                       29         7         10
                           RD6/PSP6
                                       30         8         9
                           RD7/PSP7
     PIC16F877A                                       RX8
RXD
TXD
RTS
CTS
                                                                                     61
22. Comunicación serie entre dos PICs con la USART
La comunicación serie vía serie RS-232 tiene dos tipos: síncrona o asíncrona:
      Síncrona: necesita una conexión adicional para la señal de reloj. Una USART hace de
       Master y la otra de esclava. La comunicación es del tipo half duplex (bidireccional por
       turnos). Se emplea cuando se quiere comunicar un PIC con otro dispositivo electrónico,
       como una memoria EEPROM externa.
      Asíncrona: no se necesita una conexión para la señal de reloj, los relojes del transmisor y
       del receptor son independientes, aunque deben tener la misma frecuencia, y la
       sincronización entre ambos se hace añadiendo unos bits adicionales (bit de inicio y bit de
       parada) al byte de datos, que puede estar formado por 8 o 9 bits. La comunicación puede
       llegar a ser hasta dúplex completo (bidireccional simultanea). Este tipo de conexión es la
       que se utiliza normalmente para comunicar un PIC con un PC o para comunicar dos PIC's
       entre sí, que es la más usada.
Ejemplo
En este ejemplo se va a comunicar dos PIC's entre sí vía serie RS-232 del tipo asíncrona,
haciendo uso del módulo USART (Universal Synchronous/Asynchronous Receiver Transmiter),
que incorporan la mayoría de los PIC’s de la gama media/alta. El PIC transmisor envía los
caracteres '1' y '2' y el PIC receptor recibe estos dos caracteres y almacena en la EEPROM. Por
último, se muestran los caracteres en la PC. El PIC a utilizar es el PIC16F877 a una frecuencia
de oscilación de 4Mhz.
Al haber dos PIC’s se tendrá que hacer dos programas independientes, uno para el transmisor y
otro para el receptor.
Transmisor:
/*--------------------------------------------------------*\
| Comunicación entre dos PIC's por USART. Transmisor      |
|                                                         |
|                                                         |
\*--------------------------------------------------------*/
#include <16F877.h>
void main()
{
    char dato1='1';
    char dato2='2';
    putc(dato1);
    putc(dato2);
}
                                                                                               62
Análisis del Código del Transmisor
    En el caso de utilizar la USART del PIC, CCS permite configurar fácilmente el bit de
    transmisión (XMIT) y el bit de recepción (RCV) dentro de la directiva #use rs232, el "1" es
    porque hay PIC's que tienen más de una USART.
Receptor:
/*--------------------------------------------------------*\
| Comunicación entre dos PIC's por USART. Receptor        |
|                                                         |
|                                                         |
\*--------------------------------------------------------*/
#include <16F877.h>
#int_RDA
void RDA_isr(void)
{
    char cdecenas, cunidades;
    if (contador == 0)
    {
        cdecenas=getch();
        write_eeprom(0,cdecenas);
        contador++;
    }
    else
    {
        cunidades=getch();
        write_eeprom(1,cunidades);
    }
}
void main()
{
    enable_interrupts(INT_RDA);
    enable_interrupts(GLOBAL);
   El PIC receptor recibe los datos con la interrupción de la recepción de la comunicación serie
    asincrónica RS232, por lo que tiene que activarse las interrupciones INT_RDA y GLOBAL.
                                                                                              63
   Al final el programa receptor muestra los datos almacenados en la EEPROM en la PC.
                                 U1
                            13                                     33
                                  OSC1/CLKIN            RB0/INT
                            14                                     34
                                  OSC2/CLKOUT              RB1
                                                                   35
                                                           RB2
                             2                                     36
                                  RA0/AN0              RB3/PGM
                             3                                     37
                                  RA1/AN1                  RB4
                             4                                     38
                                  RA2/AN2/VREF-/CVREF      RB5
                             5                                     39
                                  RA3/AN3/VREF+        RB6/PGC
                             6                                     40
                                  RA4/T0CKI/C1OUT      RB7/PGD
                             7
                                  RA5/AN4/SS/C2OUT
                                                                   15
                                                RC0/T1OSO/T1CKI
                             8                                     16
                                  RE0/AN5/RD      RC1/T1OSI/CCP2
                             9                                     17
                                  RE1/AN6/WR            RC2/CCP1
                            10                                     18
                                  RE2/AN7/CS        RC3/SCK/SCL
                                                                   23
                                                     RC4/SDI/SDA
                             1                                     24
                                  MCLR/Vpp/THV           RC5/SDO
                                                                   25
                                                       RC6/TX/CK
                                                                   26   RXD
                                                       RC7/RX/DT
                                                                   19   TXD
                                                       RD0/PSP0
                                                                   20
                                                       RD1/PSP1
                                                                   21   RTS
                                                       RD2/PSP2
                                                                   22
                                                       RD3/PSP3
                                                                   27   CTS
                                                       RD4/PSP4
                                                                   28
                                                       RD5/PSP5
                                                                   29
                                                       RD6/PSP6
                                                                   30
                                                       RD7/PSP7
                                 PIC16F877A
                                 U2
                            13                                     33
                                  OSC1/CLKIN            RB0/INT
                            14                                     34
                                  OSC2/CLKOUT              RB1
                                                                   35
                                                           RB2
                             2                                     36
                                  RA0/AN0              RB3/PGM
                             3                                     37
                                  RA1/AN1                  RB4
                             4                                     38
                                  RA2/AN2/VREF-/CVREF      RB5
                             5                                     39
                                  RA3/AN3/VREF+        RB6/PGC
                             6                                     40
                                  RA4/T0CKI/C1OUT      RB7/PGD
                             7
                                  RA5/AN4/SS/C2OUT
                                                                   15
                                                RC0/T1OSO/T1CKI
                             8                                     16
                                  RE0/AN5/RD      RC1/T1OSI/CCP2
                             9                                     17
                                  RE1/AN6/WR            RC2/CCP1
                            10                                     18
                                  RE2/AN7/CS        RC3/SCK/SCL
                                                                   23
                                                     RC4/SDI/SDA
                             1                                     24
                                  MCLR/Vpp/THV           RC5/SDO
                                                                   25
                                                       RC6/TX/CK
                                                                   26
                                                       RC7/RX/DT
                                                                   19
                                                       RD0/PSP0
                                                                   20
                                                       RD1/PSP1
                                                                   21
                                                       RD2/PSP2
                                                                   22
                                                       RD3/PSP3
                                                                   27
                                                       RD4/PSP4
                                                                   28
                                                       RD5/PSP5
                                                                   29
                                                       RD6/PSP6
                                                                   30
                                                       RD7/PSP7
                                 PIC16F877A
                                                                                         64
23. Comunicación serie entre dos PICs con la USART y Teclado
Ejemplo:
En este ejemplo se va a comunicar dos PIC’s entre sí vía serie RS-232 del tipo asíncrona,
haciendo uso del módulo USART (Universal Synchronous/Asynchronous Receiver Transmiter),
que incorporan la mayoría de los PIC’s de la gama media/alta. El PIC U1 hará de PIC transmisor
de datos, que se encargará de comprobar si se pulsa alguna tecla en el teclado y en el caso de que
así sea, mandará el valor del caracter (1 byte) de la tecla pulsada, correspondiente al código del
teclado. El segundo PIC U2 implementará en su código una interrupción por recepción de datos
serie en la USART, que recibirá el carácter procedente de U1 y visualizará su valor en un display
de siete segmentos de cátodo común.
Al haber dos PIC’s se tendrá que hacer dos programas independientes, uno para el transmisor y
otro para el receptor.
Transmisor:
/*-----------------------------------------------------------*\
| Comunicación entre dos PIC's por USART. Transmisor          |
|                                                             |
\*-----------------------------------------------------------*/
#include <16F877.h>
#FUSES XT, NOPROTECT
#use delay (clock = 4000000)
#define use_portb_kbd TRUE // Para usar puerto el B, caso contrario usa puerto el D
#include "kbd_lib.c"
void main()
{
    char c;
    port_b_pullups(true);      // Activa los pull ups del puerto B
printf("Comunicacion serie.\r\n");
    while(true)
    {
        c = kbd_getc();
        if(c != 0 )            //si se ha pulsado una tecla
        {
            putc(c);           //Envia el caracter via serie por la USART del PIC
        }
    }
}
#include "kbd_lib.c"
                                                                                               65
    Esta librería es una modificación de "kbd.c"que incluye CCS en la carpeta Drivers, creada en
    la instalación del programa. La que viene por defecto controla un teclado de 4 (filas) x 3
    (Columnas). La modificación que se ha hecho permite controlar un teclado de 4 x 4. Al ver el
    código original es fácil hacer las modificaciones pertinentes para poder controlar un teclado
    personalizado.
#define use_portb_kbd TRUE // Para usar puerto B, caso contrario usa puerto D
    Para usar el teclado elige el puerto B en lugar del puerto D, para usar el puerto D no se
    necesita esta instrucción.
 Solo son necesarias dos funciones para utilizar la librería "kbd_lib.c" que son:
    El uso de estas librerías tiene un problema y es que tienen copyright, que muestra un
    comentario en el encabezado de esta librería, indicando, entre otras cosas, que se puede crear
    programas derivados de este software y distribuir el código objeto generado al compilar pero
    no se puede distribuir el código fuente. Por lo que este es el motivo de no mostrar la
    modificación hecha sobre esta librería.
    Entonces, para que funcione el ejemplo al completo se tiene que modificar la librería para
    que sea capaz de controlar el teclado 4x4 o modificar el circuito para tener un teclado de 4x3.
    En el caso de utilizar la USART del PIC, CCS permite configurar fácilmente el bit de
    transmisión (XMIT) y el bit de recepción (RCV) dentro de la directiva #use rs232, el "1" es
    porque hay PIC's que tienen más de una USART.
Receptor:
                                                                                                66
/*--------------------------------------------------------*\
| Comunicación entre dos PIC's por USART. Receptor        |
|                                                         |
|                                                         |
\*--------------------------------------------------------*/
#include <16F877.h>
#FUSES XT, NOPROTECT
#use delay (clock = 4000000)
#byte puerto_D = 0x08
#use rs232(uart1, baud=9600)
char dato;
#int_rda
void rd_isr(void)   // Funcion de interrupcion por recepción de datos USART
{
    dato= getc();
                                                                              67
         default:
             break;
    }
}
void main()
{
    enable_interrupts(global);//Habilita interrupción USART
    enable_interrupts(int_rda);
    while(true){
        //Código principal
    }
}
   En la parte del código del receptor se utiliza el recurso de interrupción por recepción de datos
    de la USART.
   Una forma más simple de seleccionar el valor decodificado para ser mostrado en el display
    de 7 segmentos, que se utiliza en la sentencia switch(dato){}, es asignando los valores
    decodificados en un vector como se muestra a continuación:
Luego se realiza:
puerto_D = valor_D[datos];
                                                                                                 68
     U1
13                                     33
      OSC1/CLKIN            RB0/INT
14                                     34
      OSC2/CLKOUT              RB1
                                       35
                               RB2
 2                                     36
 3
      RA0/AN0
      RA1/AN1
                           RB3/PGM
                               RB4
                                       37
                                                           A
                                                               7        8   9
 4                                     38
      RA2/AN2/VREF-/CVREF      RB5
 5                                     39
      RA3/AN3/VREF+        RB6/PGC
 6                                     40
 7
      RA4/T0CKI/C1OUT
      RA5/AN4/SS/C2OUT
                           RB7/PGD                         B
                                                               4        5   6
                                       15
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
10
      RE1/AN6/WR
      RE2/AN7/CS
                            RC2/CCP1
                        RC3/SCK/SCL
                                       18
                                                           C
                                                               1        2   3
                                       23
                         RC4/SDI/SDA
 1                                     24
      MCLR/Vpp/THV           RC5/SDO                           ON
                           RC6/TX/CK
                           RC7/RX/DT
                                       25
                                       26
                                                           D
                                                                    C   0   =   +
                                                                                4
                                       19
                           RD0/PSP0
                                       20
                           RD1/PSP1
                                       21
                           RD2/PSP2
                                       22
                           RD3/PSP3
                                       27
                           RD4/PSP4
                                       28
                           RD5/PSP5
                                       29
                           RD6/PSP6
                                       30
                           RD7/PSP7
     PIC16F877A
     U2
13                                     33
      OSC1/CLKIN            RB0/INT
14                                     34
      OSC2/CLKOUT              RB1
                                       35
                               RB2
 2                                     36
      RA0/AN0              RB3/PGM
 3                                     37
      RA1/AN1                  RB4
 4                                     38
      RA2/AN2/VREF-/CVREF      RB5
 5                                     39
      RA3/AN3/VREF+        RB6/PGC
 6                                     40
      RA4/T0CKI/C1OUT      RB7/PGD
 7
      RA5/AN4/SS/C2OUT
                                       15
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA
 1                                     24
      MCLR/Vpp/THV           RC5/SDO
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT            RN1
                                       19   1         16
                           RD0/PSP0
                                       20   2         15
                           RD1/PSP1
                                       21   3         14
                           RD2/PSP2
                                       22   4         13
                           RD3/PSP3
                                       27   5         12
                           RD4/PSP4
                                       28   6         11
                           RD5/PSP5
                                       29   7         10
                           RD6/PSP6
                                       30   8         9
                           RD7/PSP7
     PIC16F877A                                 RX8
                                                                                    69
24. Medir temperatura con LM35 y mostrarla por LCD 2x16
Ejemplo:
En este programa sensa la temperatura con un LM35 y muestra por una LCD. El PIC a utilizar es el
PIC16F877 a una frecuencia de oscilación de 4Mhz.
#include "16f877.h"
#include "lcd.c"
#use standard_io (D)              //Selecciona el puerto D para el LCD
    while (TRUE)
    {
      lcd_gotoxy(8,2);           // Ubica el cursor LCD en la columna 8 y fila 2
      lcd_putc(" ");             // Limpia ese sector de la pantalla del LCD
      lcd_gotoxy(8,2);           // Ubica el cursor LCD en la columna 14 y fila 2
        setup_adc (adc_clock_internal);
        setup_adc_ports (all_analog);
        set_adc_channel (0);     // Elige canal RA0
        delay_us (20);
        medicion=read_adc (); // Hace conversión AD
        setup_adc (adc_off);    // Apaga ADC
        temper=medicion*(0.48875); // Pasa binario a °C
Si se utiliza la resolución de 8 bits del conversor análogo digital, donde el número máximo posible es de
255, la fórmula sería:
1.96 = (5/255)*100
C1
             22p                                        U1
                                                   13                                    33   LCD1
                                                         OSC1/CLKIN            RB0/INT        LM032L
                                         X1        14
                                                         OSC2/CLKOUT              RB1
                                                                                         34
                                         CRYSTAL    1                                    35
             C2                                          MCLR/Vpp/THV             RB2
                                                                                         36
                                                                              RB3/PGM
                                                    2                                    37
                                                         RA0/AN0                  RB4
                                                    3                                    38
                                                         RA1/AN1                  RB5
             22p                                    4                                    39
                                                         RA2/AN2/VREF-        RB6/PGC
                                                    5                                    40
                                                         RA3/AN3/VREF+        RB7/PGD
                                                                                                 VDD
                                                                                                 VSS
                                                                                                 VEE
                                           5v       6
                                                                                                       RW
                                                                                                       RS
                                                                                                            D0
                                                                                                            D1
                                                                                                            D2
                                                                                                            D3
                                                                                                            D4
                                                                                                            D5
                                                                                                            D6
                                                                                                            D7
                                                         RA4/T0CKI
                                                                                                       E
                     5v                             7                                    15
                                                         RA5/AN4/SS    RC0/T1OSO/T1CKI
                                                                                         16
                                                                        RC1/T1OSI/CCP2
                                                                                                1
                                                                                                2
                                                                                                3
                                                                                                       4
                                                                                                       5
                                                                                                       6
                                                                                                             7
                                                                                                             8
                                                                                                             9
                                                                                                            10
                                                                                                            11
                                                                                                            12
                                                                                                            13
                                                                                                            14
                                                    8                                    17
                                  U3                     RE0/AN5/RD           RC2/CCP1
                          1                         9                                    18
                                                         RE1/AN6/WR        RC3/SCK/SCL
                                                   10                                    23
                                                         RE2/AN7/CS        RC4/SDI/SDA
                                                                                         24
                                                                               RC5/SDO
                                                                                         25
                          67.0                                               RC6/TX/CK
                                                                                         26
                                                                             RC7/RX/DT
                                   2                                                     19
                          VOUT                                               RD0/PSP0
                                                                                         20
                                                                             RD1/PSP1
                                                                                         21
                                                                             RD2/PSP2
                                                                                         22
                                                                             RD3/PSP3
                              3   LM35                                                   27
                                                                             RD4/PSP4
                                                                                         28
                                                                             RD5/PSP5
                                                                                         29
                                                                             RD6/PSP6
                                                                                         30
                                                                             RD7/PSP7
                                                        PIC16F877
                                                                                                                 71
25. Mandar un mensaje por Rs232 y mostrarlo por un LCD 2x16
Ejemplo:
En este programa envía un mensaje por el puerto Rs232 de la PC al PIC y muestra dicho mensaje por
una LCD 2x16. El PIC a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
#include <16F877A.h>
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7)
                           // Configura el puerto serie a una velocidad de 9600 baudios
#include <lcd.c>         // Libreria para el manejo del LCD
char dato_recibido[16];  // Variable para recibir los datos del RS232
void main()
{
  enable_interrupts(int_rda);     // Se habilita la interrupcion por escritura del puerto serial
  enable_interrupts(global);
set_tris_d(0b00000000);
    lcd_init();
    lcd_gotoxy(1,1);
    lcd_putc(" com RS232 ");
    while(TRUE)
    {
      lcd_gotoxy(1,2);
      printf(lcd_putc,"%s",dato_recibido); // Se envia al LCD lo que se recibió de la PC
    }
}
                                                                                                   72
     U1
13                                     33
      OSC1/CLKIN            RB0/INT
14                                     34
      OSC2/CLKOUT              RB1
                                       35
                               RB2          RXD
 2                                     36
      RA0/AN0              RB3/PGM
 3                                     37
      RA1/AN1                  RB4          TXD
 4                                     38
      RA2/AN2/VREF-/CVREF      RB5
 5                                     39
      RA3/AN3/VREF+        RB6/PGC          RTS
 6                                     40
      RA4/T0CKI/C1OUT      RB7/PGD
 7
      RA5/AN4/SS/C2OUT                      CTS
                                       15
                    RC0/T1OSO/T1CKI
 8                                     16
      RE0/AN5/RD      RC1/T1OSI/CCP2
 9                                     17
      RE1/AN6/WR            RC2/CCP1
10                                     18
      RE2/AN7/CS        RC3/SCK/SCL
                                       23
                         RC4/SDI/SDA              LCD1
 1                                     24
      MCLR/Vpp/THV           RC5/SDO              LM016L
                                       25
                           RC6/TX/CK
                                       26
                           RC7/RX/DT
                                       19
                           RD0/PSP0
                                       20
                           RD1/PSP1
                                       21
                           RD2/PSP2
                                       22
                           RD3/PSP3
                                       27
                           RD4/PSP4
                                                                 VDD
                                                                 VEE
                                                                 VSS
                                       28
                                                            RW
                                                            RS
                                                       D7
                                                       D6
                                                       D5
                                                       D4
                                                       D3
                                                       D2
                                                       D1
                                                       D0
                           RD5/PSP5
                                                            E
                                       29
                           RD6/PSP6
                                       30
                           RD7/PSP7
                                                      14
                                                      13
                                                      12
                                                      11
                                                      10
                                                       9
                                                       8
                                                       7
                                                            6
                                                            5
                                                            4
                                                                 3
                                                                 2
                                                                 1
     PIC16F877A
                                                                       73
26. Medir temperatura con LM35 y mandar el valor vía RS232 (serial)
Ejemplo:
En este programa sensa la temperatura con un LM35 y envía el valor a una PC vía Rs232 (serial). El PIC
a utilizar es el PIC16F877 a una frecuencia de oscilación de 4Mhz.
void main(void)
{
  float medicion, temper;
    setup_adc_ports(AN0);
    setup_adc(ADC_CLOCK_INTERNAL);
    lcd_init();
    while(true)
    {
      set_adc_channel (0);
      delay_us (20);
      medicion=read_adc ();
        temper=(medicion*(0.48875));
        printf(lcd_putc, "\f Voltage = %02.1fV", temper);
        printf("Voltage = %01.2fV\r", temper);
        delay_ms(50);
    }
}
                                                                                                   74
                              U1
U2(+VS)                  13                                     33
                               OSC1/CLKIN            RB0/INT
                         14                                     34
                               OSC2/CLKOUT              RB1
                                                                35
                  U2                                    RB2
          1               2                                     36
                               RA0/AN0              RB3/PGM          RXD
                          3                                     37
                               RA1/AN1                  RB4
                          4                                     38
                               RA2/AN2/VREF-/CVREF      RB5          TXD
                          5                                     39
          44.0                 RA3/AN3/VREF+        RB6/PGC
                          6                                     40
                               RA4/T0CKI/C1OUT      RB7/PGD          RTS
                          7
                               RA5/AN4/SS/C2OUT
                   2                                            15
          VOUT                               RC0/T1OSO/T1CKI         CTS
                          8                                     16
                               RE0/AN5/RD      RC1/T1OSI/CCP2
                          9                                     17
                               RE1/AN6/WR            RC2/CCP1
                         10                                     18
                               RE2/AN7/CS        RC3/SCK/SCL
              3   LM35                                          23
                                                  RC4/SDI/SDA              LCD1
                          1                                     24
                               MCLR/Vpp/THV           RC5/SDO              LM016L
                                                                25
                                                    RC6/TX/CK
                                                                26
                                                    RC7/RX/DT
                                                                19
                                                    RD0/PSP0
                                                                20
                                                    RD1/PSP1
                                                                21
                                                    RD2/PSP2
                                                                22
                                                    RD3/PSP3
                                                                27
                                                    RD4/PSP4
                                                                                          VDD
                                                                                          VEE
                                                                                          VSS
                                                                28
                                                                                     RW
                                                                                     RS
                                                                                D7
                                                                                D6
                                                                                D5
                                                                                D4
                                                                                D3
                                                                                D2
                                                                                D1
                                                                                D0
                                                    RD5/PSP5
                                                                                     E
                                                                29
                                                    RD6/PSP6
                                                                30
                                                    RD7/PSP7
                                                                               14
                                                                               13
                                                                               12
                                                                               11
                                                                               10
                                                                                9
                                                                                8
                                                                                7
                                                                                     6
                                                                                     5
                                                                                     4
                                                                                          3
                                                                                          2
                                                                                          1
                              PIC16F877A
                                                                                                75
BIBLIOGRAFÍA
[1] uControl, "Programas PIC en C", URL: uControl.com.ar, accedido el 21 de octubre de 2016.
76