programacionpic18enc.pdf

47

Upload: luciano-ezequiel-quinto-contreras

Post on 01-Feb-2016

215 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: ProgramacionPIC18enC.pdf

República Bolivariana de VenezuelaUniversidad Nacional Experimental Politécnica

�Antonio José de Sucre�Vicerrectorado �Luís Caballero Mejías�

Programación de proyectos básicos en

microcontroladores PIC18 usando lenguaje C

Prof. Alexis Cabello

Caracas, Marzo 2013

Page 2: ProgramacionPIC18enC.pdf

ÍNDICE GENERAL

Compilador MPLAB C para PIC18 1

1. Proyecto 1 71.1. Programa Proyecto1.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2. Diseño en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.3. Simulación en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2. Proyecto 2 112.1. Programa Proyecto2.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.2. Diseño en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3. Proyecto 3 123.1. Programa Proyecto3.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.2. Diseño en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4. Proyecto 4 144.1. Programa Proyecto4.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144.2. Diseño en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5. Proyecto 5 155.1. Convertidor analógico a digital . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155.2. Programa Proyecto5.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195.3. Diseño en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

6. Proyecto 6 216.1. Programa proyecto6.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226.2. Diseño en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

7. Proyecto 7 257.1. Temporizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257.2. Programa proyecto7.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267.3. Diseño en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

8. Proyecto 8 298.1. Módulo CCP (Captura, Comparador y PWM) . . . . . . . . . . . . . . . . . . . . . . . 298.2. Programa proyecto8.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318.3. Diseño en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Anexo A. Manejo de la pantalla LCD 34

Anexo B. Manejo del teclado matricial 42

Page 3: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Índice de algoritmos

1. proyecto1.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72. continuación de proyecto1.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83. proyecto2.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114. proyecto3.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135. proyecto4.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146. proyecto5.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207. continuación proyecto5.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218. proyecto6.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239. continuación de proyecto6.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2410. proyecto7.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2611. continuación de proyecto7.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2712. proyecto8.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3213. Archivo de encabezado LCD.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3714. lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3815. continuación lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3916. continuación lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4017. kdbio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

PROF. ALEXIS CABELLO PÁGINA: 3

Page 4: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Compilador MPLAB C para PIC18

Los proyectos mostrados a continuación son desarrollados en lenguaje C y se utiliza el programa

MPLAB C18 de Microchip como compilador. Se utiliza la versión MPLAB C for PIC18 in LITE mode.

Este compilador y el MPLAB pueden descargarse a través de los enlaces que se encuentran en la página

web del Laboratorio. Primero se debe instalar el MPLAB y luego se instala el compilador C18 con las

con�guraciones por defecto.

A continuación se explica como crear un proyecto con este compilador dentro del entorno MPLAB.Lo primero que se debe crear es un Workspace, o espacio de trabajo, para lo cual se ingresa en el menúProject y se selecciona Project Wizard, Figura 1

Figura 1: Project Wirzard

Esta opción me proporciona un ayudante, se selecciona siguiente y se siguen los siguientes pasos:

1. Seleccionar en Device el dispositivo con el cual se va a trabajar, en nuestro caso el PIC18F4550.

Figura 2

PROF. ALEXIS CABELLO PÁGINA: 1

Page 5: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 2: Seleccionar Dispositivo

2. Seleccionar C18 como la herramienta con la que se desea trabajar. Figura 3

Figura 3: Seleccionar Conjunto de Lenguajes

3. Seleccionar el nombre del proyecto y la carpeta donde se creara el proyecto. Figura 4

PROF. ALEXIS CABELLO PÁGINA: 2

Page 6: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 4: Directorio de Archivos

4. Se deben añadir los archivos existentes y que deseemos agregar al proyecto, sin embargo en estemomento no se tienen archivos existentes, por lo que este paso se puede obviar, y se termina conla creación del Workspace.

5. Crear un archivo nuevo, para lo cual se ingresa a File y se selecciona la opción New, allí se obtieneuna ventana en blanco donde se escribe el programa y luego se guarda con extensión .C. Figura5

PROF. ALEXIS CABELLO PÁGINA: 3

Page 7: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 5: Nuevo Documento

6. Una vez �nalizado el programa se debe añadir el archivo al Workspace creado, para lo cual se

ingresa en el menú Project y se selecciona la opción Add Files to Project; Figura 6, donde se

debe seleccionar el directorio donde se están guardando los archivos, Figura 7

Figura 6: Añadir nuevo Documento al Workspace

PROF. ALEXIS CABELLO PÁGINA: 4

Page 8: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 7: Selección del archivo .C

7. Finalizado todos estos pasos, se procede a compilar nuestro proyecto, para lo cual se ingresa a

Project y se selecciona Build All. Figura 8

8. Como resultado de la compilación podemos observar los posibles errores de sintaxis en las lineasde programación y si todo esta correcto se obtiene un mensaje de compilación exitosa como semuestra en Figura 9

PROF. ALEXIS CABELLO PÁGINA: 5

Page 9: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 8: Compilación del Proyecto

Figura 9: Compilación Exitosa

PROF. ALEXIS CABELLO PÁGINA: 6

Page 10: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Una vez compilado de forma exitosa, se generan dos tipos de archivos .COF y .HEX. El primero contiene

información que permite realizar una simulación a nivel de código fuente. El .HEX sólo contiene el

código de máquina que se descarga al microcontrolador para su ejecución.

1. Proyecto 1

El proyecto uno se basa en aprender a manejar la con�guración de los puertos para encender 8 LED

de forma simultanea e intermitente por un tiempo inde�nido. Para crear este proyecto se utilizará el

entorno de desarrollo MPLAB de microchip y el compilador de lenguaje C de microchip MPLAB C18,

Luego que se haya realizado este paso se realizará el diseño del proyecto en el entorno de simulación

ISIS de PROTEUS, se utilizará éste programa para probar a nivel de simulación el funcionamiento del

proyecto.

1.1. Programa Proyecto1.c

Para comenzar se debe incluir los archivos de encabezado (.h) y se programan los bits de con�gura-

ción mediante la instrucción pragma. Esto se muestra en el listado 1. Mediante los bits de con�guración

se programan ciertas funciones del PIC, como son el Watchdog, el reloj que utilizará el CPU, protección

del código, etc. En este caso, se utiliza un cristal de 20Hz como entrada del Oscilador entre los pines 9

y 10 del PIC. Estos 20Mhz se dividen entre 5 para generar los 4Mhz necesarios para el PLL interno del

PIC. Esto se indica en la linea 3 donde se con�gura PLLDIV con 5. El PLL multiplica esta frecuencia

por 24 para obtener 96Mz, los cuales se dividen entre 2 para generar en de�nitiva el reloj del CPU y

del modulo USB. Esto se indica en las lineas 4 y 5 con�gurando CPUDIV y USBDIV respectivamente.

Luego se indica la fuente de entrada del oscilador con�gurando FOSC con HSPLL_HS y por ultimo

se deshabilita el uso del watchdog (WDT) y la programación con voltaje bajo (LVP).

Listado 1 proyecto1.c

#include <p18cxxx.h>#include <delays.h>#pragma config PLLDIV = 5 // (20 MHz crystal)#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2#pragma config FOSC = HSPLL_HS#pragma config WDT = OFF#pragma config LVP = OFF

Para inicializar el programa se con�guran todos los puertos como salidas, haciendo uso de TRISA,

TRISB, TRISC y TRISD. Para que el usuario pueda observar el encendido y apagado de los LED

se llama a la librería de retardo Delay10KTCYx (n). esta librería de retardo es suministrada por el

compilador MPLAB C18, y permite generar un retardo total de 10.000 ciclos de instrucción por el

numero suministrado como parámetro (n < 256).

PROF. ALEXIS CABELLO PÁGINA: 7

Page 11: ProgramacionPIC18enC.pdf

UNEXPO-LCM

De esta forma y con las especi�caciones dadas, se elabora el programa que será grabado en nuestro

dispositivo como se observa en el listado 2

Listado 2 continuación de proyecto1.c

void main(){

TRISA=TRISB=TRISC=TRISD = 0x00; // set direction to be outputADCON1 |= 0x0F;//A/D port as Digital

do {PORTD = 0x00; // Turn OFF LEDs on PORTDDelay10KTCYx (250); // delayPORTD = 0xFF; // Turn ON LEDs on PORTDDelay10KTCYx (250); // delay

} while(1);}

En el listado anterior se puede observar que se genera una salida de uno lógico por cada bit del

puerto D (PORTD), por un tiempo determinado para encender los diodos LED y posteriormente se

genera una salida con ceros lógicos para poder apagar los diodos LED.

1.2. Diseño en el PROTEUS

Para la realización del diseño lo primero que se debe hacer es colocar los distintos componentes en

la hoja de trabajo, para ello se selecciona el modo componentes que se muestra en la �gura 10 y, luego

realizar una pulsación sobre el botón P de la ventana de componentes que se muestra en la �gura 11

Figura 10: Modo Componentes

Figura 11: Selección de Botón P

Luego de activar el botón P se abre la ventana para la selección y edición del componente y

comprobar sus características; el dispositivo que se quiere utilizar, en nuestro caso el PIC18F4550, al

localizar el componente deseado se realiza una doble pulsación en él de tal forma que aparezca en la

ventana de componentes y librerías como se muestra en la �gura 12

PROF. ALEXIS CABELLO PÁGINA: 8

Page 12: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 12: Selección del Componente

Para situar el componente en el esquema de trabajo solo debemos seleccionarlo de la lista, y hacer

una pulsación sobre la ventana de trabajo y se colocará el componente.

Luego se conectan LEDs al puerto D del PIC, es decir los pines 19 al 30. Los cuales corresponden

a los con�gurados como salida en el programa y como se puede observar en la �gura 13. Para este

proyecto se utilizan 8 LEDs y 8 resistencias de 470 ohm dispuestas como se muestra en la �gura 14,

Figura 13: Dispositivo PIC 18F4550

PROF. ALEXIS CABELLO PÁGINA: 9

Page 13: ProgramacionPIC18enC.pdf

UNEXPO-LCM

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

Figura 14: Diseño Final

1.3. Simulación en PROTEUS

Una vez terminado el diseño y generado el archivo Hex abrimos el Proteus y hacemos click sobre

el PIC para cargar el programa compilado, se hace click en Program File y se selecciona el archivo.

Una vez cargado el programa en la parte inferior vemos los botones que nos permitirán poder correr

el programa, si presionamos Play se observa el funcionamiento del programa tal como se muestra en

la �gura 15

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

Figura 15: Funcionamiento del Proyecto 1

PROF. ALEXIS CABELLO PÁGINA: 10

Page 14: ProgramacionPIC18enC.pdf

UNEXPO-LCM

2. Proyecto 2

El proyecto dos consiste básicamente en la misma lógica y en el mismo diseño del proyecto uno, la

diferencia se encuentra en que en este proyecto no se encenderán todos los 8 LEDs de forma simultanea,

si no por el contrario de forma secuencial, por lo que el programa en C sera totalmente diferente, sin

embargo se mantiene el mismo diseño en el PROTEUS.

2.1. Programa Proyecto2.c

Para comenzar se debe incluir los archivos de encabezado (.h) y se programan los bits de con�gu-

ración mediante la instrucción pragma, como se explicó en el proyecto 1 y se muestran en el listado

1.

Para inicializar el programa se con�guran todos los bits de PORTD como salida, haciendo uso de

TRISD. Para que el usuario pueda observar el encendido y apagado de los LEDs se llama a la librería

de retardo Delay10KTCYx (n); esta librería de retardo es suministrada por el compilador MPLAB

C18, y permite generar un retardo total de 10.000 ciclos de instrucción por el numero suministrado

como parámetro (n < 256).

De esta forma y con las especi�caciones dadas, se elabora el programa, quedando como se muestra

en el listado 3

Listado 3 proyecto2.c

void main(){

unsigned char led=0;TRISD = 0x00; // set direction to be outputADCON1 |= 0x0F;//A/D port as digitaldo {

PORTD=(1 << led);led++;if(led==8) led=0;Delay10KTCYx(100); // delayPORTD=0x0;Delay10KTCYx(100); // delay

}while(1);}

En este caso se utiliza la variable LED, que se inicializa con �0�. Esta variable indicará cuantas

veces se va a rotar de derecha a izquierda el número 1. De esta forma se logra encender un solo LED a

la vez de forma secuencial de derecha a izquierda y no de forma simultanea como se hizo en el proyecto

1. Para observarlo grá�camente se muestra un ejemplo en la tabla 1, con la variable LED en 3.

La variable LED se incrementa en uno y se repite el proceso mientras no llegue a 8. Cuando la

variable LED llegue a 8, se cumple la condición y la inicializamos en 0 nuevamente.

2.2. Diseño en el PROTEUS

El diseño de este proyecto es básicamente el mismo utilizado en el proyecto 1, donde se conectan

PROF. ALEXIS CABELLO PÁGINA: 11

Page 15: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Bit7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

0 0 0 0 0 0 0 1

Número antes de rotar.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

0 0 0 0 1 0 0 0

Número después de rotar 3 veces a la izquierda. Se enciende el LED 3

Tabla 1: Ejemplo del LED a encender

8 LEDs al puerto D del PIC, es decir los pines 19 al 30. Los cuales corresponden a los con�gurados

como salida en el programa.

Al momento de compilar el programa en MPLAB, se obtiene el archivo .HEX, que se debe cargar

en el PIC18F4550 y al ejecutar la simulación, se observa cómo con el mismo diseño, los LEDs ahora

encienden uno por uno a la vez, como se muestra en la �gura 16, así continuamente hasta llegar al

LED 8 y comienza nuevamente en el 1.

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

Figura 16: Encendido del LED 1

3. Proyecto 3

El proyecto 3 se enfoca en el uso de las funciones de manejo de una pantalla LCD mediantela programación del PIC 18F4550 para mostrar cadenas de caracteres en las diferentes líneas de lapantalla.

3.1. Programa Proyecto3.c

Para comenzar a realizar el programa en C, esta vez se necesitan una serie de funciones adicionales osubrutinas, para poder trabajar con la pantalla LCD. Estas rutinas se describen en el Anexo A. Primerose debe incluir los archivos de encabezado (.h) y se programan los bits de con�guración mediante lainstrucción pragma, como se explicó en el proyecto 1 y se muestran en el listado 1. En este proyecto

PROF. ALEXIS CABELLO PÁGINA: 12

Page 16: ProgramacionPIC18enC.pdf

UNEXPO-LCM

se debe agregar el archivo de encabezado (lcd.h) para poder hacer uso de las funciones de manejo delLCD.

Listado 4 proyecto3.c

#include "lcd.h"CHAR buffer1[16]="HELLO WORLD";CHAR buffer2[16]="Hola Mundo";void main() {

ADCON1 |= 0x0F; //A/D port as digitalPORTC = TRISC = 0x00;PORTB = TRISB = 0x00;

lcd_init();lcd_clear();lcd_display(1,1,buffer1);lcd_display(2,3,buffer2);for(;;);

}

3.2. Diseño en el PROTEUS

En el diseño de proteus se agrega la pantalla LCD (LM016L9) y se conectan los terminales de datosal puerto B, los terminales de control al puerto E, los terminales de alimentación de VDD a 5V, VSS yVEE a GND para obtener el mayor contraste. El diseño �nal y la simulación del proyecto se muestraen la �gura 17.

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7kR8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

RB4RB5RB6RB7

RE0

RE2RE1

Figura 17: Diseño del Proyecto 3

PROF. ALEXIS CABELLO PÁGINA: 13

Page 17: ProgramacionPIC18enC.pdf

UNEXPO-LCM

4. Proyecto 4

El proyecto 4 se enfoca en el uso de las funciones de manejo de un teclado matricial de 4x3 mediantela programación del PIC 18F4550. Se realiza un programa de prueba que muestra en una pantalla LCDla tecla presionada.

4.1. Programa Proyecto4.c

Para comenzar a realizar el programa en C, esta vez se necesitan una serie de funciones adicionaleso subrutinas, para poder trabajar con el Teclado. Estas rutinas se describen en el Anexo B. En esteproyecto se debe agregar las declaraciones de las funciones del teclado para poder hacer uso de estas,tal como se muestra en el listado 5

Listado 5 proyecto4.c

CHAR buf1[16]="KEYPAD TEST";CHAR buf2[16]="KEY: ";CHAR keycodes[17] = {0,’#’,’0’,’*’,’-’,’9’,’8’,’7’,

’-’,’6’,’5’,’4’,’-’,’3’,’2’,’1’,’-’};unsigned short kp,ka,led=1,sw=1;int delay=0;char keypadread(void);char scankey(void);VOID main() {

ADCON1 |= 0x0F;PORTA = TRISA = 0x00;PORTB = TRISB = 0x00;INTCON2 &= ~0x80; //conecta las resistencias pull-up al puerto Blcd_init();lcd_clear();lcd_display(1,1,buf1);Delay10KTCYx(250);lcd_clear();lcd_display(1,1,buf2);do{

kp=0;do{

kp = keypadread(); // Store key code in kp variableDelay10KTCYx(12);

}while (!kp);ka=keycodes[kp];if(ka==’#’ && led<0x80) led=led<<1;if(ka==’*’ && led>0x01) led=led>>1;PORTD=led;lcd_clear();lcd_display(1,1,buf2);lcd_char(ka); // Print key ASCII value on LCD

} while (1);}

PROF. ALEXIS CABELLO PÁGINA: 14

Page 18: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Como se muestra en el listado 5, se utiliza la función keypadread para leer una tecla, la cual retornael código de la tecla presionada (1 a 12). Este código se utiliza como el indice de la tabla keycodes,la cual guarda el carácter ASCII de la tecla presionada. Luego se utiliza ese carácter ASCII paramostrarlo en la pantalla LCD.

4.2. Diseño en el PROTEUS

En el diseño de proteus se agrega la pantalla LCD (LM016L9) y un teclado matricial (KEYPAD).A las líneas de entrada al microcontrolador (RB1-RB3) se agregan resistencias de 10k conectadas alVCC (Pull-ups ), esto con el �n de detectar niveles alto cuando ninguna tecla sea presionada. Estosólo se requiere a nivel de simulación en proteus, puesto que cuando se implementa físicamente con elmicrocontrolador se pueden utilizar las resistencias pull-up internas del microcontrolador a través dela instrucción (INTCON2 &= ~0x80). El simulador no procesa correctamente esta instrucción. En la�gura 18 se muestra el diseño �nal y una simulación del proyecto.

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

RB4RB5RB6RB7

RE0

RE2RE1

1 2 3

4 5 6

7 8 9

0 #

1 2 3

A

B

C

DRB4

RB5

RB6

RB7

RB3 RB2 RB1

RB1RB2RB3

R910k

R1010k

R1210k

Figura 18: Diseño del proyecto 4

5. Proyecto 5

En el proyecto 5 se utiliza el convertidor analógico a digital (ADC) del PIC 18F4550 para leer elvalor de tensión de una señal analógica y mostrar ese valor expresado en milivoltios por la pantallaLCD. Se emplea un potenciómetro para generar una señal analógica que puede variar entre 0 y 5V, lacual se conecta al canal cero (AN0) del Convertidor ADC.

5.1. Convertidor analógico a digital

En la �gura 19 se muestra un esquema del convertidor analógico a digital (ADC) del PIC 18F4550.Este módulo permite la conversión de una señal analógica a su correspondiente valor digital de 10 bits.El ADC tiene 13 entradas multiplexadas o canales y el canal a convertir se selecciona por medio de losbits CHS3-CHS0 del registro ADCON0 tal como se muestra en la �gura 20.

PROF. ALEXIS CABELLO PÁGINA: 15

Page 19: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 19: Convertidor Analógico a Digital

Registro ADCON0

ADONGo/DoneCHS0CHS1CHS2CHS3----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADONGo/DoneCHS0CHS1CHS2CHS3----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADON: ADC On bit0= Convertidor deshabilitado 1: Convertidor habilitado

Go/Done: Bit de estatus de la conversión0=Conversión lista 1= conversión en progreso

CHS0-CHS3: Bits de selección del canal0000= Canal 0 (AN0)0001= Canal 1 (AN1)0010= Canal 2 (AN2)0011= Canal 3 (AN3)0100= Canal 4 (AN4)0101= Canal 5 (AN5)0110= Canal 6 (AN6)0111= Canal 7 (AN7)1000= Canal 8 (AN8)1001= Canal 9 (AN9)1010= Canal 10 (AN10)1011= Canal 11 (AN11)1100= Canal 12 (AN12)

Figura 20: Registro ADCON0

PROF. ALEXIS CABELLO PÁGINA: 16

Page 20: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Registro ADCON1

PCFG0PCFG1PCFG2PCFG3VCFG0VCFG1----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

PCFG0PCFG1PCFG2PCFG3VCFG0VCFG1----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

PCFG3-0: Bits de configuración de los puertos analógicos.VCFG0: Bit de configuración del voltaje de referencia negativo V

REF-

0=VSS 1=AN2 VCFG1: Bit de configuración del voltaje de referencia positivo V

REF+

0=VDD 1=AN3

DDDDDDDDDDDDD1111

ADDDDDDDDDDDD1110

AADDDDDDDDDDD1101

AAADDDDDDDDDD1100

AAAADDDDDDDDD1011

AAAAADDDDDDDD1010

AAAAAADDDDDDD1001

AAAAAAADDDDDD1000

AAAAAAAADDDDD0111

AAAAAAAAADDDD0110

AAAAAAAAAADDD0101

AAAAAAAAAAADD0100

AAAAAAAAAAAAD0011

AAAAAAAAAAAAA0010

AAAAAAAAAAAAA0001

AAAAAAAAAAAAA0000

AN0AN1AN2AN3AN4AN5AN6AN7AN8AN9AN10AN11AN12PFCG3-PCFG0

DDDDDDDDDDDDD1111

ADDDDDDDDDDDD1110

AADDDDDDDDDDD1101

AAADDDDDDDDDD1100

AAAADDDDDDDDD1011

AAAAADDDDDDDD1010

AAAAAADDDDDDD1001

AAAAAAADDDDDD1000

AAAAAAAADDDDD0111

AAAAAAAAADDDD0110

AAAAAAAAAADDD0101

AAAAAAAAAAADD0100

AAAAAAAAAAAAD0011

AAAAAAAAAAAAA0010

AAAAAAAAAAAAA0001

AAAAAAAAAAAAA0000

AN0AN1AN2AN3AN4AN5AN6AN7AN8AN9AN10AN11AN12PFCG3-PCFG0

Figura 21: Registro ADCON1

D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

Go

TAD

Adquisición Conversión

TACQ

1(Fosc/n)

TAD= n=2,4,8,16,32,64

TACQ= m*TAD m=0,2,4,6,8,12,16,20

Figura 22: Tiempo de adquisición-conversión

PROF. ALEXIS CABELLO PÁGINA: 17

Page 21: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Registro ADCON2

ADCS0ADCS1ADCS2ACQT0ACQT1ACQT2--ADFM

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADCS0ADCS1ADCS2ACQT0ACQT1ACQT2--ADFM

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADCS2-ADCS0: Reloj de Conversión del ADC000= Fosc/2001= Fosc/8010= Fosc/32011= FRC (Oscilador RC Interno)100= Fosc/4 101= Fosc/16110= Fosc/64111= FRC (Oscilador RC Interno)

ADFM: Formato del Resultado del ADC0 = Justificado a la Izquierda1 = Justificado a la derecha

ACQT2-ACQT0: Tiempo de adquisición del ADC

000= 0 Tad001= 2 Tad010= 4 Tad011= 6 Tad100= 8 Tad101= 12 Tad110= 16 Tad111= 20 Tad

Figura 23: Registro ADCON2

ADRESL

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADRESL

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

ADRESH: Byte alto del resultado de la conversión

ADRESL: Byte bajo del resultado de la conversión

ADRESH

Bit 8Bit 9

ADRESH

Bit 8Bit 9

Figura 24: Resultado justi�cado a la derecha

PROF. ALEXIS CABELLO PÁGINA: 18

Page 22: ProgramacionPIC18enC.pdf

UNEXPO-LCM

En las �guras 21 y 23 se muestran el resto de los registros donde se con�gura el funcionamientodel ADC. En el registro ADCON1 se con�gura el voltaje de referencia positivo a VDD y el negativoa GND, así como se de�nen los terminales analógicos y digitales, en éste proyecto se con�guran losterminales AN0-AN3 como analógicos y el resto digitales.

En el registro ADCON2 se con�gura el tiempo de la conversión según se muestra en la �gura 22.El tiempo de conversión de cada bit (TAD) mínimo debe ser 0.8us y el tiempo de adquisición (TACQ)mínimo debe ser de 1.4us según la hoja de especi�caciones. Como se utiliza una Fosc de 48MHz, seutiliza el divisor de 64 y 4 TAD para el TACQ para satisfacer los requerimientos. El resultado de laconversión se obtiene en los registros ADRESH y ADRESL, la cual puede ser ajustado a la derecha oa la izquierda. En la �gura 24 se muestra el resultado justi�cado a la derecha, la cual es la utilizadaen este proyecto. Los valores de los registros se pueden apreciar en el listado 7 donde se con�gura larutina de conversión del ADC.

5.2. Programa Proyecto5.c

El listado 6 muestra la rutina principal del proyecto y el listado 7 muestra la rutina para leer elvalor de la conversión. A esta última se debe pasar como parámetro el canal del ADC que se quiereleer, en este proyecto se lee la señal analógica conectada al canal cero (AN0).

Para mostrar el valor correspondiente en milivoltios con dos dígitos decimales por el LCD, se realizala conversión mostrada en la ecuación 1:

volts =n · 5000mV

1024× 100 (1)

donde: n es el valor del ADC (0-1023) que corresponde a (0-5v). Se multiplica por 100 para tomardos decimales de precisión.

Luego se toma la parte entera diviendo los voltios entre 100 y se toma el resto de la división comola parte decimal, y �nalmente se convierten estos valores en un cadena de caracteres ASCII para suvisualización en la pantalla LCD.

5.3. Diseño en el PROTEUS

En la �gura 25 se muestra el diseño en proteus del proyecto 5. Se utiliza el proyecto 4 como basey se agrega un potenciómetro para generar la señal analógica. El cursor del potenciómetro se conectaal terminal AN0 del PIC. La �gura muestra el cursor del potenciómetro en 50%, lo que corresponde aun valor de 2493.68 mV, el cual se observa en la pantalla LCD. Al variar el cursor del potenciómetrose puede apreciar como se actualiza el valor medido en la pantalla LCD, funcionando el sistema comoun voltímetro digital.

PROF. ALEXIS CABELLO PÁGINA: 19

Page 23: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 6 proyecto5.c

#include <p18cxxx.h>#include <delays.h>#include <stdlib.h>#include "lcd.h"#pragma config PLLDIV = 5 // (20 MHz crystal)#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2#pragma config FOSC = HSPLL_HS //HSPLL_HS#pragma config WDT = OFF#pragma config MCLRE = ON#pragma config LVP = OFF

CHAR lcd[16];CHAR msg[]="mV= ";unsigned int Vin,Vdec,Vfrac;unsigned long volts;unsigned int adc_read(unsigned char ch);unsigned char ch1,ch2;VOID main() {ADCON1 |= 0x0F;PORTE = TRISE = 0x00;PORTB = TRISB = 0x00;lcd_init();

TRISAbits.TRISA0 = 1; //AN0for(;;) // Endless loop{lcd_clear();Vin = adc_read(0); // Read from channel 0 (AN0)lcd_display(1,1,msg); // Display "mV = "volts=Vin;volts = 488*volts; // Scale up the resultVdec = volts / 100; // Decimal partVfrac = volts % 100; // Fractional partitoa(Vdec,lcd); // Convert Vdec to string in "lcd"

// Display result on LCD//lcd_display(1,6,lcd); // Output to LCDlcd_char(’.’); // Display "."ch1 = Vfrac / 10; // Calculate fractional partch2 = Vfrac % 10; // Calculate fractional partlcd_char(48+ch1); // Display fractional partlcd_char(48+ch2); // Display fractional partDelay10KTCYx(250); // delayDelay10KTCYx(250); // delay

}

}

PROF. ALEXIS CABELLO PÁGINA: 20

Page 24: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 7 continuación proyecto5.c

unsigned int adc_read(unsigned char ch){unsigned int result;

ADCON0 = (ch & 0x0F) << 2;ADCON1 = 0x0B; //RA0-RA3 Analog inputs.ADCON2 = 0x96; // right justify,TACQ=4*TAD, TAD=1/(FOSC/64)ADCON0bits.ADON = 1; // ADC on

ADCON0bits.GO_DONE = 1; // start

while (ADCON0bits.GO_DONE == 1);result = ((unsigned int)(ADRESH) << 8) + ADRESL;ADCON0bits.ADON = 0; // ADC Offreturn result;

}

50%

RV1

10k

VDD

AN0

AN0R

E2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

OSC1

VDD

R20

4.7k

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

L7L6L5L4L3

L1L2

L0

RB4RB5RB6RB7

RE0

RE2RE1

RB1RB2RB3

R910k

R1010k

R1210k

Figura 25: Diseño del proyecto 5

6. Proyecto 6

En el proyecto 6 se utilizan las interrupciones para realizar un reloj digital a partir de una fuentede alimentación de corriente alterna de 60Hz. La fuente alterna alimenta un circuito que genera unpulso por cada cruce por cero de la señal (detector de cruce por cero) y esta señal se utiliza como unafuente de interrupción externa para el conteo del tiempo.

PROF. ALEXIS CABELLO PÁGINA: 21

Page 25: ProgramacionPIC18enC.pdf

UNEXPO-LCM

50%

RV1

10k

VDD

AN0

AN0

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

OSC1

VDD

R20

4.7k

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

L7L6L5L4L3

L1L2

L0

RB4RB5RB6RB7

RE0

RE2RE1

RB1RB2RB3

R1210k

R14

10k R13

10k

A

K

C

E

B1

2 4

56

U2

4N25

R11240

VDD

R1010k

RB0

BR1

2W08G

V1VSINEVO=0VA=20FREQ=60

K

RB0

Figura 26: Diseño del proyecto 6

6.1. Programa proyecto6.c

En los listados 8 y 9 se muestra el programa del proyecto6. Lo importante a destacar es la declaraciónde las interrupciones en el compilador MPLAB C18. En los microcontroladores 18F existen dos vectoresde interrupción, uno de alta prioridad y otro de baja prioridad. El vector de alta prioridad se encuentraen la dirección 0x08h y el de baja prioridad en el la dirección 0x18h. El bit IPEN del registro RCONhabilita las prioridades de las interrupciones. Si el bit IPEN=0 como es por defecto no se utilizan lasprioridades de las interrupciones y todas utilizan el vector de interrupción de alta prioridad (0x08h).En este proyecto no se utilizan las prioridades y se emplea la directiva #pragma code para escribir enel vector de interrupción de alta prioridad el salto a la rutina de interrupción y se utiliza la directiva#pragma interrupt para indicar cual es la rutina de interrupción.

Como la frecuencia de la fuente de alimentación es de 60Hz, el circuito detector de cruce por cerogenera 120 pulsos en un segundo. Por esto, en la rutina de interrupción se acumula cada vez que segenera una interrupción y cuando se alcanza 120 se pone en cero y se empienza a incrementar lossegundos. Igualmente se procede con los segundos, cuando se alcanzan los 60 se pone en cero y seempiezan a incrementar los minutos hasta alcanzar los 60 minutos donde se pone en cero y empiezade nuevo el reloj.

En la rutina principal del programa se habilita la interrupción INT0 y luego en un bucle in�nito seconvierten constantemente los minutos y segundos a ASCII y se muestra en la pantalla LCD el tiempo.

6.2. Diseño en PROTEUS

En la Figura 26 se muestra el diseño en proteus. Para la simulación se emplea una fuente alternade 13Vac y el circuito detector de cruce por cero aislado del microcontrolador por medio de un opto-acoplador 4N25, la señal de salida del detector (RB0) se conecta al terminal de interrupción externa(INT0). En la simulación se muestra el reloj indicando que ha transcurrido 1 minuto y 06 segundos.

PROF. ALEXIS CABELLO PÁGINA: 22

Page 26: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 8 proyecto6.c

#include <p18cxxx.h>#include <delays.h>#include <stdlib.h>#include "lcd.h"#pragma config PLLDIV = 5 // (20 MHz crystal)#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2#pragma config FOSC = HSPLL_HS //HSPLL_HS#pragma config WDT = OFF#pragma config LVP = OFF

unsigned char tick=0,seg=0,min=0;unsigned char ch1,ch2;CHAR lcd_seg[16];CHAR lcd_min[16];CHAR msg[16]="Time:";

void InterruptHandlerHigh (void);//----------------------------------------------------------------------------// High priority interrupt vector#pragma code InterruptVectorHigh = 0x08void InterruptVectorHigh (void){

_asmgoto InterruptHandlerHigh //jump to interrupt routine

_endasm}//----------------------------------------------------------------------------// High priority interrupt routine

#pragma code#pragma interrupt InterruptHandlerHighvoid InterruptHandlerHigh (){

if (INTCONbits.INT0IF == 1){

INTCONbits.INT0IF = 0;tick++;if(tick==120){

tick=0;seg++;

}if(seg==60){

seg=0;min++;

}if(min==60) min=0;

}}

PROF. ALEXIS CABELLO PÁGINA: 23

Page 27: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 9 continuación de proyecto6.c

void main() {TRISA=TRISB=TRISC=TRISD = 0x00; // set direction to be outputPORTD=0x0;ADCON1 = 0x0F;

lcd_init();TRISBbits.RB0=1;INTCONbits.GIE = 1; //enable global interruptsINTCONbits.PEIE = 1; //enable peripherical interrupts

INTCONbits.INT0IE =1; //enable INT0 Interruptlcd_clear();lcd_display(1,1,msg);do{

setpos(1,7);ch1 = min / 10; // digit1ch2 = min % 10; // digit2lcd_char(48+ch1); // Display digit1lcd_char(48+ch2); // Display digit2lcd_char(’:’);ch1 = seg / 10; // digit1ch2 = seg % 10; // digit2lcd_char(48+ch1); // Display digit1lcd_char(48+ch2); // Display digit2

}while(1);}

PROF. ALEXIS CABELLO PÁGINA: 24

Page 28: ProgramacionPIC18enC.pdf

UNEXPO-LCM

7. Proyecto 7

En el proyecto 7 se muestra el uso del temporizador del microcontrolador para tener un controlexacto del tiempo y así generar una señal cuadrada de 120Hz. El ciclo de trabajo de la señal cuadradagenerada es de 50% pero cambiando el valor en una variable se puede cambiar el ancho de pulso ociclo de trabajo.

7.1. Temporizador

El microcontrolador PIC 18F4550 tiene cuatro temporizadores TIMER0-3. En el siguiente proyectoutilizamos el TIMER2 que es básicamente un contador de 8 bits (TMR2) con un divisor de pre-escaladoy uno de pos-escalado. En la �gura 27 se muestra el esquema del TIMER2.

Figura 27: Temporizador 2

El contador TMR2 incrementa desde cero hasta que es igual al valor del registro PR2. Este incre-mento depende del valor del divisor del reloj o pre-escalado (PRESCALER), el cual puede ser 1, 4, o16. Para �jar el periodo del temporizador (PR2) se puede utilizar la ecuación 2

T = (PR2 + 1) ∗ 4 ∗ 1

Fosc∗ PRESCALER ∗ POSTSCALER (2)

donde:Fosc es la la frecuencia del oscilador.PRESCALER es el valor del divisor del oscilador a la entrada del temporizador.POSTCALER es el valor del divisor de la señal de salida del temporizador.T es el periodo de la señal a generar.PR2 es el registro del periodo.

El valor del contador TMR2 se compara con el valor del registro PR2 en cada ciclo de reloj y cuandoel contador TMR2 es igual al registro PR2 el comparador produce una señal que va al contador depos-escalado y pone en cero el contador TMR2. Dependiendo del valor pre�jado de pos-escalado seactiva la bandera de interrupción TMR2IF que se encuentra en el registro PIR1. En este proyectocomo el pos-escalado es igual a 1, la interrupción se genera cuando el valor de TMR2 es igual al valorde PR2. Para habilitar la interrupción del temporizador 2 se utiliza el bit TMR2IE del registro PIE1.Los valores de pre-escalado y pos-escalado se con�guran en el registro T2CON tal como se muestra enla �gura 28.

PROF. ALEXIS CABELLO PÁGINA: 25

Page 29: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 28: Registro T2CON

7.2. Programa proyecto7.c

En los listados 10 y 11 se muestra el programa proyecto7.c. El periodo de la señal a generar (8.33ms)se divide entre 512 y se utiliza el temporizador 2 para generar una interrupción cada 16.275us. Paragenerar la señal cuadrada con 50% de ciclo de trabajo lo primero que se hace es incrementar uncontador por cada interrupción y cuando alcanza el valor medio de 256 se pone en bajo la señal ycuando alcanza el valor máximo de 512 se pone en cero el contador y se pone la señal en alto.

Listado 10 proyecto7.c

#include <p18cxxx.h>#include <delays.h>#include <stdlib.h>#include "lcd.h"#pragma config PLLDIV = 5 // (20 MHz crystal)#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2#pragma config FOSC = HSPLL_HS //HSPLL_HS#pragma config WDT = OFF

unsigned int count=0;

void initTimer (void);void InterruptHandlerHigh (void);

PROF. ALEXIS CABELLO PÁGINA: 26

Page 30: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 11 continuación de proyecto7.c

// High priority interrupt vector#pragma code InterruptVectorHigh = 0x08void InterruptVectorHigh (void){

_asmgoto InterruptHandlerHigh //jump to interrupt routine

_endasm}// High priority interrupt routine#pragma code#pragma interrupt InterruptHandlerHighvoid InterruptHandlerHigh (){if (PIR1bits.TMR2IF == 1)

{PIR1bits.TMR2IF = 0;count++;if(count==256) PORTD=0;if(count==512){

PORTD=0xFF;count=0;

}}

}void main() {

TRISA=TRISB=TRISC=TRISD = 0x00; // set direction to be outputPORTD=0x0;ADCON1 = 0x0F;INTCONbits.GIE = 1; //enable global interruptsINTCONbits.PEIE = 1; //enable peripherical interrupts

initTimer();while(1);

}void initTimer (void){

PR2 = 194; // T = (PR2+1) * 4 *(1/Fosc)*PRESCALER// 16.25us= (PR2+1)* 4*(1/Fosc)*PRESCALER : Fosc=48Mhz : PRESCALER=1T2CON=0;T2CONbits.T2CKPS1 = 0;T2CONbits.T2CKPS0 = 0; // 1:1 - prescaler

IPR1bits.TMR2IP = 1; // high priorityPIR1bits.TMR2IF = 0;PIE1bits.TMR2IE = 1; //1=enable InterruptT2CONbits.TMR2ON = 1;

}

PROF. ALEXIS CABELLO PÁGINA: 27

Page 31: ProgramacionPIC18enC.pdf

UNEXPO-LCM

7.3. Diseño en PROTEUS

En la Figura 29 se muestra el diseño en proteus del proyecto 7, solamente se ha agregado elosciloscopio para observar la señal cuadrada. Se conecta la salida RD0 del puerto D del PIC al canalA del osciloscopio. En la Figura 30 se muestra la pantalla del osciloscopio, en la cual se puede apreciarel periodo de la señal.

50%

RV1

10k

VDD

AN0

AN0

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

RB4RB5RB6RB7

RE0

RE2RE1

RB1RB2RB3

R1210k

R14

10k R13

10k

RB0

A

B

C

D

L0

Figura 29: Diseño del proyecto 7

Figura 30: Simulación del proyecto 7

PROF. ALEXIS CABELLO PÁGINA: 28

Page 32: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 31: Diagrama del módulo PWM

8. Proyecto 8

En el proyecto 8 se utiliza el módulo CCP1 del microcontrolador. Se con�gura el módulo CCP1 enmodo PWM estándar para generar una señal cuadrada de 4KHz con 50% de ciclo de trabajo pero ala cual se le puede modi�car el ancho del pulso.

8.1. Módulo CCP (Captura, Comparador y PWM)

El microcontrolador PIC 18F4550 tiene dos módulos CCP. En este proyecto se utiliza el móduloCCP1 en su modo de funcionamiento de PWM (modulador de ancho de pulso). En la �gura 31 semuestra un diagrama del módulo PWM. El módulo permite generar una señal PWM con 10 bits deresolución. El módulo CCP genera los 10 bits de resolución del PWM uniendo los 8 bits del contadorTMR2 con 2 bits del divisor de pre-escalado, tal como se observa en la Nota 1 de la �gura 31. Estos10 bits se comparan con los 10 bit del ciclo de trabajo para generar la señal PWM. En la �gura 32se muestra una señal de salida PWM. La señal PWM tiene una base de tiempo �jo o período y untiempo variable en que se encuentra en alto o ciclo de trabajo (ancho del pulso). Tal como se puedeapreciar en la �gura 31, el módulo utiliza el TIMER2 como contador para generar la señal PWM. Elperíodo de la señal se �ja escribiendo el registro PR2 según la ecuación 2. El ciclo de trabajo puedetener hasta 10 bits de resolución y se establece escribiendo en los registros CCPRxL y CCPxCON, talcomo se muestra en la �gura 33. Para con�gurar el módulo CCP en modo PWM se escribe �1� en losbits CCPxM2-3 del registro CCPxCON tal como se muestra en la �gura 34.

PROF. ALEXIS CABELLO PÁGINA: 29

Page 33: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Ciclo de trabajo

PERIODO

TMR2=PR2TMR2=PR2

TMR2=Ciclo de trabajo

Figura 32: Señal de salida del módulo PWM

Ciclo de trabajo

CCPxL

Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7Bit 8Bit 9

CCPxL

Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7Bit 8Bit 9

CCPxL: Byte mas significativo de los 10Bit del ciclo de trabajo.

CPxB0-CPxB1: 2 bits menos significativos de los 10Bits del ciclo de trabajo

CCPxCON

Bit 0Bit 1

CCPxCON

Bit 0Bit 1

Figura 33: Ciclo de trabajo del PWM

Registro CCPxCON

CCPxM0CCPxM1CCPxM2CCPxM3DCxB0DCxB1----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7CCPxM0CCPxM1CCPxM2CCPxM3DCxB0DCxB1----

Bit 0Bit 1Bit 2Bit 3Bit 4Bit 5Bit 6Bit 7

CCPxM0-M3: Selección del modo de operación0000= Capture/compare/ PWM deshabilitado0001= reservado0010= comparador: Cambia la salida cuando sea igual0011= reservado0100= modo de captura: cada flanco de caida0101= modo de captura: cada flanco de subida0110= modo de captura: cada 4 flanco de subida0111= modo de captura: cada 16 flanco de subida1000= comparador: Cambia la salida cuando sea igual1001= comparador: Cambia la salida cuando sea igual1010= comparador: Genera interrupción cuando sea igual1011= comparador: dispara un evento especial,

comienza la conversión ADC11xx= modo PWM

DCxB0-DCxB1: Bit0 y Bit1 para el Ciclo de trabajo del PWM

Figura 34: Registro CCPxCON

PROF. ALEXIS CABELLO PÁGINA: 30

Page 34: ProgramacionPIC18enC.pdf

UNEXPO-LCM

8.2. Programa proyecto8.c

En el listado 12 se muestra el programa proyecto8.c. Para utilizar el módulo CCP1 en modo PWMestándar se con�gura el registro CCP1CON, escribiendo los bits CCP1M3-CCP1M2 con �1� . El periodode la señal PWM lo determina el periodo del temporizador 2 y se con�gura escribiendo el registro PR2.El periodo se calcula a través de la ecuación 2.

El módulo CCP permite producir una señal PWM hasta con 10bits de resolución. Para con�gurarel ciclo de trabajo de trabajo se escribe en el registro CCPR1L los 8 bits mas signi�cativos y los otrosdos bits se escriben en los bit DC1B1-DC1B0 del registro CCP1CON. La salida de la señal PWMse produce por el pin RC2 del puerto C, por lo que esta señal debe ser habilitada como salida paraobtener la señal PWM.

8.3. Diseño en PROTEUS

En la Figura 35 se muestra el diseño en proteus del proyecto 8, El diseño es básicamente el mismoque el anterior, solo que se conecta la salida RC2 del puerto C al osciloscopio para poder observar laseñal PWM generada. La pantalla del osciloscopio donde se observa la señal PWM generada por elprograma se muestra en la Figura 36.

50%

RV1

10k

VDD

AN0

AN0

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD2LM016L

D4R4

470

D3R3

470

D2R2

470

D1R1

470

OSC1

VDD

R20

4.7k

R8

470

D7R7

470

D6R6

470

D5R5

470

RA0/AN02

RA1/AN13

RA2/AN2/VREF-/CVREF4

RA3/AN3/VREF+5

RA4/T0CKI/C1OUT/RCV6

RA5/AN4/SS/LVDIN/C2OUT7

RA6/OSC2/CLKO14

OSC1/CLKI13

RB0/AN12/INT0/FLT0/SDI/SDA33

RB1/AN10/INT1/SCK/SCL34

RB2/AN8/INT2/VMO35

RB3/AN9/CCP2/VPO36

RB4/AN11/KBI0/CSSPP37

RB5/KBI1/PGM38

RB6/KBI2/PGC39

RB7/KBI3/PGD40

RC0/T1OSO/T1CKI 15

RC1/T1OSI/CCP2/UOE 16

RC2/CCP1/P1A 17

VUSB18

RC4/D-/VM 23

RC5/D+/VP 24

RC6/TX/CK 25

RC7/RX/DT/SDO 26

RD0/SPP0 19

RD1/SPP1 20

RD2/SPP2 21

RD3/SPP3 22

RD4/SPP4 27

RD5/SPP5/P1B 28

RD6/SPP6/P1C 29

RD7/SPP7/P1D 30

RE0/AN5/CK1SPP 8

RE1/AN6/CK2SPP 9

RE2/AN7/OESPP 10

RE3/MCLR/VPP 1

U1

PIC18F4550

OSC2

D8

L7L6L5L4L3

L1L2

L0

L0

L1

L2

L3

L4

L5

L6

L7

RB4RB5RB6RB7

RE0

RE2RE1

RB1RB2RB3

R1210k

R14

10k R13

10k

RB0

A

B

C

D

RC2

RC2

Figura 35: Diseño del proyecto 8

PROF. ALEXIS CABELLO PÁGINA: 31

Page 35: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 12 proyecto8.c

#include <p18cxxx.h>#include <delays.h>#include <stdlib.h>

#pragma config PLLDIV = 5 // (20 MHz crystal)#pragma config CPUDIV = OSC1_PLL2#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2#pragma config FOSC = HSPLL_HS //HSPLL_HS#pragma config WDT = OFF

unsigned int count=0;

void initPWM (void);

void main() {

TRISA=TRISB=TRISC=TRISD = 0x00; // set direction to be outputPORTD=0x0;ADCON1 = 0x0F;

INTCONbits.GIE = 1; //enable global interruptsINTCONbits.PEIE = 1; //enable peripherical interrupts

initPWM();

while(1);}

void initPWM (void){

PR2 = 187; // T pwm = (PR2+1)*4*(1/FOSC)*PRESCALERCCPR1L = 94; // 50% duty cycle

T2CON=0;T2CONbits.T2CKPS1 = 1;T2CONbits.T2CKPS0 = 0; // 16 - prescaler

IPR1bits.TMR2IP = 0; // low priorityPIR1bits.TMR2IF = 0;PIE1bits.TMR2IE = 0; //disable InterruptT2CONbits.TMR2ON = 1;

CCP1CON = 0;CCP1CONbits.DC1B1=0;CCP1CONbits.DC1B0=0; //Duty cicleCCP1CONbits.CCP1M3=1;CCP1CONbits.CCP1M2=1; //PWM modeTRISCbits.TRISC2 = 0; //RC1 output

}

PROF. ALEXIS CABELLO PÁGINA: 32

Page 36: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Figura 36: Simulación del proyecto 8

PROF. ALEXIS CABELLO PÁGINA: 33

Page 37: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Anexo A

Manejo de la pantalla LCD

Las pantallas LCD son dispositivos que se utilizan para visualizar información. Los dispositivosLCD poseen internamente un microcontrolador especi�co que sirven para regular el funcionamiento delos mismos.

Las pantallas mas comunes están formados por una matriz de 5*7 pixels en una o en varías líneas,en el siguiente proyecto se trabajará con una pantalla LCD que permite trabajar dos líneas de 16caracteres cada una y, que posee un microcontrolador 44780. Esta pantalla que se muestra en la �gura37 posee 14 terminales que serán explicados con detalle a continuación.

RE

2

RB

4R

B5

RB

6R

B7

RE

0

VD

D

RE

1

D7

14D

613

D5

12D

411

D3

10D

29

D1

8D

07

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

Figura 37: LCD LM016L

Como se observan los 14 terminales son VSS, VDD, VEE, RS, RW, E, D0, D1, D2, D3, D4, D5, D6,y D7, estos terminales se dividen en tres categorías, los tres primeros son los terminales de alimentación,los siguientes tres terminales son los utilizados para control del LCD y los últimos 8 respectivamente,son utilizados para transferir los datos.

Terminales de Alimentación

1. VSS: Se aplica la tierra

2. VDD: Se aplica la alimentación de 5 voltios

3. VEE: Normalmente este terminal se conecta a un potenciómetro que permita variar un voltajeentre 0 a 5 voltios y así observar la diferencia de brillo y contraste que se puede tener en lapantalla LCD. Si se conecta a tierra, se indica el mayor contraste.

Terminales de Control

1. RS: Por este terminal, se indica a la pantalla LCD si se va escribir un comando o una data, seentiende por comandos todas aquellas instrucciones que sirven para inicializar la pantalla, borrarpantalla, posicionar el cursor entre otras, para todo esto, se debe colocar un �0� en este terminal;por el contrario si se conecta a �1� , lo que se envía es la data, generalmente el código ASCII delcarácter a mostrar.

PROF. ALEXIS CABELLO PÁGINA: 34

Page 38: ProgramacionPIC18enC.pdf

UNEXPO-LCM

2. RW: Este terminal corresponde a Read/Write, es decir, es el terminal que indica si vamos a leero a escribir de la pantalla LCD, siendo �1� para leer y �0� para escribir.

3. E: Enable, este terminal permite habilitar el proceso de escritura/lectura a la pantalla LCD. sino se activa este terminal, la información en D0-D7 no se lee o escribe.

Terminales para Data Estos 8 terminales reciben los caracteres ASCII a representar, así comociertos códigos de control que regulan los efectos de visualización o para obtener información sobre elestado interno del dispositivo.

El dispositivo LCD responde a una serie de comandos con los que se puede manipular sus distintasopciones de trabajo, para lo cual se hace referencia a la tabla 2.

Comando RS R/W E D7 D6 D5 D4 D3 D2 D1 D0Tiempo deEjecución

Clear Display 0 0 1 0 0 0 0 0 0 0 1 1.64 msHome 0 0 1 0 0 0 0 0 0 1 x 1.64 ms

Entry Mode Set 0 0 1 0 0 0 0 0 1 I/D S 40 usDisplay On/O� 0 0 1 0 0 0 0 1 D C B 40 us

Cursor Display Shift 0 0 1 0 0 0 1 S/C R/L x x 40 usFunction Set 0 0 1 0 0 1 DL N F x x 40 us

Set CGRAM Address 0 0 1 0 1 Dirección de la CGRAM 40 usSet DDRAM Address 0 0 1 1 Dirección de la DDRAM 40 us

Read Busy Flags Address 0 1 1 BF Dirección de la CGRAM o DDRAM 40 usWrite Data to CG o DD 1 0 1 Código ASCII para la RAM 40 usRead Data to CG o DD 1 1 1 Código Almacenado en RAM 40 us

Tabla 2: Códigos de los Comandos a los que responde el Dispositivo LCD

A continuación se explica con detalle todas las abreviaturas utilizadas en la tabla

S: Se re�ere a la visualización, si vale �1�, indica que cada vez que escribe un dato, la visualizaciónse desplaza automáticamente a la siguiente posición, por el contrario si vale �0�, funciona de formanormal.

I/D: Se re�ere al cursor, si vale �1�, el cursor se incrementa automáticamente de dirección luegode escribir, si vale �0�, éste se decrementa.

S/C: Si vale �1� se desplaza la visualización, si vale �0� se desplaza el cursor.

R/L: Si vale �1� el desplazamiento es a la derecha del LCD, si vale �0� es a la izquierda.

BF: si vale �1� el dispositivo LCD se encuentra en funcionamiento u ocupado, si se encuentra en�0�, indica que esta disponible.

DL: Si vale 1 trabaja con un bus de datos de 8 bits, si vale �0� trabaja con bus de solo 4 bits,que es el caso que se eligió en el proyecto.

N: Si vale �1� la presentación se hace en dos líneas, si vale �0� se hace en una sola línea.

F: Este indica el tamaño o la caja de los caracteres, si vale �1� es de 5x10 pixels, si vale �0�, esde 5x7.

PROF. ALEXIS CABELLO PÁGINA: 35

Page 39: ProgramacionPIC18enC.pdf

UNEXPO-LCM

B: Si vale �1�, parpadeo del cursor encendido y si es �0� , parpadeo del cursor apagado.

C: Si vale �1�, el cursor esta activado, si vale �0� el cursor esta desactivado.

D: Si vale �1�, la pantalla esta activada, si vale �0� la pantalla esta desactivada.

X: Indeterminado

A continuación se describen la función de los comandos que controlan el dispositivo LCD

Clear Display: Este comando borra la pantalla del dispositivo LCD y coloca el cursor en laprimera posición, que es la dirección 0, por defecto coloca el bit I/D en �1� para autoincrementode la posición del cursor.

Home: Pone el cursor en la dirección 0 y no varía el contenido de la memoria DDRAM que guardalos datos y que queda direccionada desde la posición 0.

Entry Mode Set: Establece la dirección del movimiento del cursor, si coloca el bit S en �1� desplazala visualización cada vez que se escribe un dato, si S vale �0� la visualización es normal.

Display On/O�: Activa o Desactiva al Display (D) y al cursos (C) y determina si éste es inter-mitente o no.

Cursor Display Shift: Mueve el cursor y desplaza la visualización sin cambiar el contenido de lamemoria DDRAM.

Function Set: Establece el número de líneas que se van a utilizar, con el bus de datos, siendonormalmente que sea de 8 bits, por lo que DL=1 y especí�ca el número de líneas de caracteres,que para que sean dos se debe colocar N=1 y el formato del carácter si F=0 entonces es de 5x7pixels.

Set CGRAM Adress: El dispositivo LCD tiene de�nidos los caracteres ASCII, sin embargo per-mite que el usuario pueda de�nir un máximo de nueve caracteres nuevos. Éstos se guardan enCGRRAM. Con este comando se indica la dirección de la CGRAM a partir de la cual se iránalmacenando los bytes que de�nen al nuevo carácter. Luego de ejecutar este comando todos losdatos que se lean o escriban posteriormente lo hacen desde esa posición de la CGRAM.

Set DDRAM Adress: Establece la dirección de la DDRAM, a partir de la cual todos los datos quese lean o escriban posteriormente lo harán desde esta posición. Es los 16 caracteres del primerrenglón ocupan las direcciones 80H- 8FH y los del segundo desde C0H- CFH.

Read Busy Flags Adress: Se trata de un comando para la lectura de las bandera BUSY, queindica si todavía se está ejecutando un comando previo en la pantalla, y además proporciona ladirección de la CGRAM y DDRAM que se haya utilizado por última vez.

Write Data to CG o DD: Se escribe en la DDRAM los caracteres ASCII, que se desea visualizar.También se escriben en la CGRAM los bytes de los nuevos caracteres creados por el usuario,en caso de existir los mismo. Se usa una memoria u otra según haya sido la instrucción dedireccionamiento anterior, que hará que se re�eje el contenido de la memoria DDRAM o CGRAM.

Read Data to CG o DD: Es muy parecido al comando anterior, pero en este caso es solo paralectura de los datos que se encuentren en las memorias DDRAM o CGRAM.

En el archivo de encabezado se declaran los prototipos de las funciones del LCD y se de�nen los códigosde los comandos principales mostrados en la tabla 2. El archivo de encabezado (lcd.h) se muestra enel listado 13:

PROF. ALEXIS CABELLO PÁGINA: 36

Page 40: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 13 Archivo de encabezado LCD.h

typedef void VOID;typedef int INT;typedef signed char INT8;typedef signed int INT16;typedef signed long INT32;typedef unsigned short WORD;typedef char CHAR;typedef unsigned char BYTE;typedef double FLOAT;typedef long LONG;typedef INT8 BOOL;

//Display Config.#define MAX_DISPLAY_CHAR 16

//LCD Registers addresses (PORT E)#define LCD_CMD_WR 0x00#define LCD_DATA_WR 0x01#define LCD_BUSY_RD 0x02#define LCD_DATA_RD 0x03

//LCD Commands#define LCD_CLS 0x01#define LCD_HOME 0x02#define LCD_SETMODE 0x04#define LCD_SETVISIBLE 0x08#define LCD_SHIFT 0x10#define LCD_SETFUNCTION 0x20#define LCD_SETCGADDR 0x40#define LCD_SETDDADDR 0x80

#define E_PIN_MASK 0x04

#define FALSE 0#define TRUE 1

/***************************************************************************** FUNCTION PROTOTYPES ***********************************/VOID lcd_display (CHAR y, CHAR x, CHAR *buf);VOID lcd_char (CHAR ch);VOID lcd_init(void);VOID lcd_wait(void);VOID wrcmd (CHAR data);VOID wrdata(CHAR data);VOID lcd_clear(void);VOID lcd_reset(void);VOID setpos(CHAR y, CHAR x);

PROF. ALEXIS CABELLO PÁGINA: 37

Page 41: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 14 lcdio.c

/********************************************************************** PIC18F Driver for LCD in 4-bit mode ***********************************************************************/#include "p18cxxx.h"#include <delays.h>#include "lcd.h"VOID wrcmd8 (CHAR cmdcode);VOID lcd_init ()// Initialise the LCD Display.{

PORTB = TRISB = 0x0F;PORTE = TRISE = 0;

Delay10KTCYx(25);wrcmd8(LCD_SETFUNCTION+0x10); // Software reset.wrcmd8(LCD_SETFUNCTION+0x10); //wrcmd8(LCD_SETFUNCTION+0x12); //

#ifdef BIT8wrcmd8(LCD_SETFUNCTION+0x18); // 8-bit mode - 2 line - 5x7 font.

#elsewrcmd8(LCD_SETFUNCTION+0x08); // 4-bit mode - 2 line - 5x7 font.wrcmd(LCD_SETFUNCTION+0x08); // 4-bit mode - 2 line - 5x7 font.

#endifwrcmd(LCD_SETVISIBLE+0x04); // Display, no cursor - no blink.wrcmd(LCD_SETMODE+0x02); // Automatic Increment - No Display shift.wrcmd(LCD_SETDDADDR+0x00); // Address DDRAM with 0 offset 80h.

}VOID lcd_display (CHAR y, CHAR x, CHAR *buf){ INT8 i;

setpos(y,x);for (i=0 ; buf[i] != 0; i++)

{ wrdata(buf[i]); }}

VOID lcd_char (CHAR ch){ INT8 i;

wrdata(ch);}

VOID lcd_clear()// Clear the LCD Screen and reset// initial position.{ wrcmd(LCD_CLS);

wrcmd(LCD_SETDDADDR+0x0);}

VOID setpos (CHAR y, CHAR x){

if(y==1)wrcmd(LCD_SETDDADDR+(x-1));

elsewrcmd(LCD_SETDDADDR+0x40+(x-1));

}

PROF. ALEXIS CABELLO PÁGINA: 38

Page 42: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 15 continuación lcdio.c

VOID wrcmd8 (CHAR cmdcode)// Write a command to the LCD display.{ TRISB = 0x0F;

PORTB = cmdcode;

// Write to PORTB to latch data into the display.// Toggle Pin ’E’ to send the command.PORTE = LCD_CMD_WR;PORTE |= E_PIN_MASK;_asmNOPNOP_endasm

PORTE &= ~E_PIN_MASK;

lcd_wait();}

/***** Utility Functions *****/VOID wrcmd (CHAR cmdcode)// Write a command to the LCD display.// In 4-bit mode we send the MSN first and then// the LSN. We then call the wait routine to hold// until the busy flag is cleared.{ TRISB = 0x0F;

#ifdef BIT8PORTB = (cmdcode);

#elsePORTB = (cmdcode & 0xF0); // Get the most significant nibble first.

#endifPORTE = LCD_CMD_WR; // Specify a command write operation.PORTE |= E_PIN_MASK; // Toggle the ’E’ pin to send the command._asmNOPNOP

_endasmPORTE &= ~E_PIN_MASK;

#ifdef BIT8lcd_wait(); // Call the wait routine.

#elseTRISB = 0x0F;PORTB = (cmdcode << 4); // Repeat for least significant nibble.PORTE = LCD_CMD_WR;PORTE |= E_PIN_MASK;_asmNOPNOP

_endasmPORTE &= ~E_PIN_MASK;lcd_wait(); // Call the wait routine.

#endif}

PROF. ALEXIS CABELLO PÁGINA: 39

Page 43: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 16 continuación lcdio.c

VOID wrdata (CHAR data)// Write a Character to the LCD Display.// In 4-bit mode we send the MSN first and then// the LSN. We then call the wait routine to hold// until the busy flag is cleared.{ TRISB = 0x0F;

#ifdef BIT8PORTB = data;

#elsePORTB = data & 0xF0; // Get the most significant nibble first.

#endifPORTE = LCD_DATA_WR; // Specify a data write operation.PORTE |= E_PIN_MASK; // Toggle the ’E’ pin to send the command._asmNOPNOP

_endasmPORTE &= ~E_PIN_MASK;

#ifdef BIT8lcd_wait(); // Call the wait routine.

#elseTRISB = 0x0F;PORTB = (data << 4); // Repeat for least significant nibble.PORTE = LCD_DATA_WR;PORTE |= E_PIN_MASK;_asmNOPNOP

_endasmPORTE &= ~E_PIN_MASK;lcd_wait(); // Call the wait routine.

#endif}

VOID lcd_wait (){

Delay1KTCYx(10);}

Rutina lcd_init() Esta rutina se utiliza para inicializar el LCD. Se puede inicializar para fun-cionar en modo de transferencia de 4 bits o de 8 bits dependiendo si se de�ne la variable BIT8 pormedio del comando del preprocesador del compilador (#de�ne BIT8). Si esta de�nida la variable serealizar la con�guración para 8 bits y en caso contrario se con�gura para 4 bits.

Rutina lcd_display(y, x, string) Esta rutina permite mostrar en la pantalla LCD una cadenade caracteres. Se debe pasar como parámetros las coordenadas de la pantalla (y, x) a partir de dondese empieza a mostrar la cadena de caracteres.

y: número de la �la o línea (1 o 2)x: numero de la columna (1 a 16)string: cadena de caracteres a mostrar.

PROF. ALEXIS CABELLO PÁGINA: 40

Page 44: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Rutina lcd_char(char) Esta rutina permite mostrar un carácter en la posición actual delcursor. El cursor se incrementa y queda en la siguiente posición de la pantalla.

char = carácter a mostrar.

Rutina lcd_clear() Esta rutina permite borrar toda la pantalla LCD y se posiciona el cursoren coordenadas de inicio (1,1).

Rutina setpos(y,x) Esta rutina permite mover el cursor. Se debe pasar como parámetros lascoordenadas de la pantalla (y, x).

y: número de la �la o línea (1 o 2).x: número de la columna (1 a 16).

Las rutinas que se describen a continuación son las rutinas de bajo nivel que son utilizadas paraenviar los comandos y los datos a la pantalla LCD. Estas rutinas son utilizadas por las rutinas descritasanteriormente por controlar las funciones de la pantalla LCD.

Rutina wrcmd8(comando) Esta rutina escribe el código de comando pasado como parámetroa la pantalla LCD a través del modo de transferencia de 8 bits y espera a que el LCD termine deejecutar la operación. Esta rutina se utiliza en la función lcd_init() ya que al encender la pantalla estaqueda inicializada en modo de transferencia de 8 bits.

Rutina wrcmd(comando) Esta rutina escribe el código de comando pasado como parámetroa la pantalla LCD a través del modo de transferencia con�gurado en la rutina lcd_init(), es decir en4 bits o en 8 bits. La rutina espera a que el LCD termine de ejecutar la operación.

Rutina wrdata(char) Esta rutina escribe el carácter (char) pasado como parámetro a la pantallaLCD.

Rutina lcd_wait() Esta rutina espera para que el LCD termine de procesar el comando enviado.

PROF. ALEXIS CABELLO PÁGINA: 41

Page 45: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Anexo B

Manejo del Teclado Matricial

Un teclado matricial es un dispositivo de entrada de datos donde las líneas necesarias para detectarla tecla pulsada se agrupan de forma matricial en �las y columnas con el �n de disminuir las líneasrequeridas. Para un teclado de 12 teclas solo se requieren de 7 líneas de entrada/salida del microcon-trolador para manejar el teclado. En la �gura 38 se muestra el esquema de un teclado matricial de 12teclas.

RB7

RB6

RB4

RB5

B2

2

B4

4

B5

5

B6

6

B8

8

B3

3

B9

9

B7

7

B1

1

B12

#

B11

0

B10

*

RB3 RB2 RB1

Figura 38: Teclado Matricial de 4x3

Las líneas RB1-RB3 en la �gura son leídas por el nible inferior del puerto B (RB1-RB3), por lo quese tienen que con�gurar como entradas, mientras que las del nible superior (RB4-RB7) se con�gurancomo salidas y es donde se aplican el patrón de estados lógicos para ser leídos por el nible inferior.El programa que se muestra en el listado 17 gestiona el manejo del teclado, en el mismo se sacasecuencialmente un nivel bajo por una de las 4 líneas de salida que se aplican a las �las (RB4-RB7),al mismo tiempo que se lee el nivel lógico que llega al nible inferior o columnas (RB1-RB3). Si al leereste nible, una de las líneas se encuentra en nivel bajo, se deduce que la tecla asociada a dicha �la ydicha columna se encuentra presionada. Cada tecla tiene un código asociado desde el 1 al 12. Luegoestos códigos pueden ser sustituidos por un código ASCII por medio del uso de un tabla.

PROF. ALEXIS CABELLO PÁGINA: 42

Page 46: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Listado 17 kdbio.c

#include <p18cxxx.h>#include <delays.h>

char keypadread(void);char scankey(void);

char keypadread()// Find a key, wait for it to be released and return.{ char key;

key = scankey();if (key)

while (scankey() != 0);return key;

}char scankey()// Scan the keypad for a keypress.// Return 0 for no press.{ char row,col,idx;

unsigned char wait,tmp;idx=0;TRISB=0x0F;

for (row=0; row < 4; row++){ // Drive appropriate row low and read columns:

LATB = ~(1 << (row+4));

for (wait=0; wait<200; ++wait);tmp = (PORTB & 0x0F);

// See if any column is active (low):for (col=1; col<4; col++){

if ((tmp & (1<<col)) == 0){

idx = (row*4) + col;break;

}}if(idx!=0) break;

}TRISB=0x00;return idx;

}

Rutina scankey() Esta rutina es la que realiza el barrido por las �las y columnas del tecladopara detectar si se ha presionado una tecla. La rutina realiza un solo barrido y si una tecla es presionadaretorna el código de la misma, por el contrario si ninguna tecla es presionada la rutina retorna cero.

PROF. ALEXIS CABELLO PÁGINA: 43

Page 47: ProgramacionPIC18enC.pdf

UNEXPO-LCM

Rutina keypadread() Esta rutina llama a la rutina scankey y si una tecla fue presionada larutina espera hasta que la tecla deje de estar presionada y luego retorna el código del tecla.

PROF. ALEXIS CABELLO PÁGINA: 44