Está en la página 1de 47

Repblica Bolivariana de Venezuela Universidad Nacional Experimental Politcnica Antonio Jos de Sucre Vicerrectorado Lus Caballero Mejas

Programacin de proyectos bsicos en microcontroladores PIC18 usando lenguaje C

Prof. Alexis Cabello

Caracas, Marzo 2013

NDICE GENERAL

Compilador MPLAB C para PIC18 1. Proyecto 1


1.1. 1.2. 1.3. Programa Proyecto1.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diseo en el PROTEUS

1 7
7 8 10

Simulacin en PROTEUS

2. Proyecto 2
2.1. 2.2. Programa Proyecto2.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diseo en el PROTEUS

11
11 11

3. Proyecto 3
3.1. 3.2. Programa Proyecto3.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diseo en el PROTEUS

12
12 13

4. Proyecto 4
4.1. 4.2. Programa Proyecto4.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diseo en el PROTEUS

14
14 15

5. Proyecto 5
5.1. 5.2. 5.3. Convertidor analgico a digital Programa Proyecto5.c Diseo en el PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
15 19 19

6. Proyecto 6
6.1. 6.2. Programa proyecto6.c Diseo en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21
22 22

7. Proyecto 7
7.1. 7.2. 7.3. Temporizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programa proyecto7.c Diseo en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25
25 26 28

8. Proyecto 8
8.1. 8.2. 8.3. Mdulo CCP (Captura, Comparador y PWM) Programa proyecto8.c Diseo en PROTEUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29
29 31 31

Anexo A. Manejo de la pantalla LCD Anexo B. Manejo del teclado matricial

34 42

UNEXPO-LCM
ndice de algoritmos
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. proyecto1.c proyecto2.c proyecto3.c proyecto4.c proyecto5.c proyecto6.c proyecto7.c proyecto8.c lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 8 11 13 14 20 21 23 24 26 27 32 37 38 39 40 43

continuacin de proyecto1.c

continuacin proyecto5.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . continuacin de proyecto6.c continuacin de proyecto7.c

Archivo de encabezado LCD.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . continuacin lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . continuacin lcdio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . kdbio.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

PROF. ALEXIS CABELLO

PGINA: 3

UNEXPO-LCM
Compilador MPLAB C para PIC18
Los proyectos mostrados a continuacin son desarrollados en lenguaje C y se utiliza el programa MPLAB C18 de Microchip como compilador. Se utiliza la versin MPLAB C for PIC18 in LITE mode, la cual puede descargarse de la pagina web de Microchip en la siguiente direccin:

http://www.

microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName= en536656
A continuacin 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 opcin 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

PGINA: 1

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

PGINA: 2

UNEXPO-LCM

Figura 4: Directorio de Archivos

4. Se deben aadir los archivos existentes y que deseemos agregar al proyecto, sin embargo en este momento no se tienen archivos existentes, por lo que este paso se puede obviar, y se termina con la creacin del Workspace. 5. Crear un archivo nuevo, para lo cual se ingresa a File y se selecciona la opcin New, all se obtiene una ventana en blanco donde se escribe el programa y luego se guarda con extensin .C. Figura 5

PROF. ALEXIS CABELLO

PGINA: 3

UNEXPO-LCM

Figura 5: Nuevo Documento

6. Una vez nalizado el programa se debe aadir el archivo al Workspace creado, para lo cual se ingresa en el men Project y se selecciona la opcin Add Files to Project; Figura 6, donde se debe seleccionar el directorio donde se estn guardando los archivos, Figura 7

Figura 6: Aadir nuevo Documento al Workspace

PROF. ALEXIS CABELLO

PGINA: 4

UNEXPO-LCM

Figura 7: Seleccin 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 compilacin podemos observar los posibles errores de sintaxis en las lineas de programacin y si todo esta correcto se obtiene un mensaje de compilacin exitosa como se muestra en Figura 9

PROF. ALEXIS CABELLO

PGINA: 5

UNEXPO-LCM

Figura 8: Compilacin del Proyecto

Figura 9: Compilacin Exitosa

PROF. ALEXIS CABELLO

PGINA: 6

UNEXPO-LCM
Una vez compilado de forma exitosa, se generan dos tipos de archivos .COF y .HEX. El primero contiene informacin que permite realizar una simulacin a nivel de cdigo fuente. El .HEX slo contiene el cdigo de mquina que se descarga al microcontrolador para su ejecucin.

1.

Proyecto 1
El proyecto uno se basa en aprender a manejar la conguracin de los puertos para encender 8 LED

de forma simultanea e intermitente por un tiempo indenido. 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 diseo del proyecto en el entorno de simulacin ISIS de PROTEUS, se utilizar ste programa para probar a nivel de simulacin 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 conguracin mediante la instruccin

pragma. Esto se muestra en el listado 1. Mediante los bits de conguracin

se programan ciertas funciones del PIC, como son el Watchdog, el reloj que utilizar el CPU, proteccin del cdigo, 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 congura PLLDIV con 5. El PLL multiplica esta frecuencia por 24 para obtener 96Mz, los cuales se dividen entre 2 para generar en denitiva el reloj del CPU y del modulo USB. Esto se indica en las lineas 4 y 5 congurando CPUDIV y USBDIV respectivamente. Luego se indica la fuente de entrada del oscilador congurando FOSC con HSPLL_HS y por ultimo se deshabilita el uso del watchdog (WDT) y la programacin 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 conguran 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 librera de retardo Delay10KTCYx (n). esta librera de retardo es suministrada por el compilador MPLAB C18, y permite generar un retardo total de 10.000 ciclos de instruccin por el numero suministrado como parmetro (n < 256).

PROF. ALEXIS CABELLO

PGINA: 7

UNEXPO-LCM
De esta forma y con las especicaciones dadas, se elabora el programa que ser grabado en nuestro dispositivo como se observa en el listado 2

Listado 2

continuacin de proyecto1.c

void main() { TRISA=TRISB=TRISC=TRISD = 0x00; // set direction to be output ADCON1 |= 0x0F;//A/D port as Digital do { PORTD = 0x00; // Turn OFF LEDs on PORTD Delay10KTCYx (250); // delay PORTD = 0xFF; // Turn ON LEDs on PORTD Delay10KTCYx (250); // delay } while(1); }

En el listado anterior se puede observar que se genera una salida de uno lgico por cada bit del puerto D (PORTD), por un tiempo determinado para encender los diodos LED y posteriormente se genera una salida con ceros lgicos para poder apagar los diodos LED.

1.2.

Diseo en el PROTEUS

Para la realizacin del diseo 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 pulsacin sobre el botn P de la ventana de componentes que se muestra en la gura 11

Figura 10: Modo Componentes

Figura 11: Seleccin de Botn P

Luego de activar el botn P se abre la ventana para la seleccin y edicin del componente y comprobar sus caractersticas; el dispositivo que se quiere utilizar, en nuestro caso el PIC18F4550, al localizar el componente deseado se realiza una doble pulsacin en l de tal forma que aparezca en la ventana de componentes y libreras como se muestra en la gura 12

PROF. ALEXIS CABELLO

PGINA: 8

UNEXPO-LCM

Figura 12: Seleccin del Componente

Para situar el componente en el esquema de trabajo solo debemos seleccionarlo de la lista, y hacer una pulsacin 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 congurados 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

PGINA: 9

UNEXPO-LCM
R1 U1
2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470

D1 D2 D3 D4 D5 D6 D7 D8

R2
L1 470

R3
L2 470

OSC2 OSC1

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7

R4
L3 470

R5
L4 470 VDD L5

R6
470

18

R20
4.7k L6

VUSB PIC18F4550

R7
470

R8
L7 470

Figura 14: Diseo Final

1.3.

Simulacin en PROTEUS

Una vez terminado el diseo 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 permitirn poder correr el programa, si presionamos Play se observa el funcionamiento del programa tal como se muestra en la gura 15

R1 U1
2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470

D1 D2 D3 D4 D5 D6 D7 D8

R2
L1 470

R3
L2 470

OSC2 OSC1

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7

R4
L3 470

R5
L4 470 VDD L5

R6
470

18

R20
4.7k L6

VUSB PIC18F4550

R7
470

R8
L7 470

Figura 15: Funcionamiento del Proyecto 1

PROF. ALEXIS CABELLO

PGINA: 10

UNEXPO-LCM
2. Proyecto 2
El proyecto dos consiste bsicamente en la misma lgica y en el mismo diseo del proyecto uno, la diferencia se encuentra en que en este proyecto no se encendern 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 diseo en el PROTEUS.

2.1.

Programa Proyecto2.c

Para comenzar se debe incluir los archivos de encabezado (.h) y se programan los bits de conguracin mediante la instruccin 1. Para inicializar el programa se conguran 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 librera de retardo Delay10KTCYx (n); esta librera de retardo es suministrada por el compilador MPLAB C18, y permite generar un retardo total de 10.000 ciclos de instruccin por el numero suministrado como parmetro (n < 256). De esta forma y con las especicaciones dadas, se elabora el programa, quedando como se muestra en el listado 3

pragma, como se explic en el proyecto 1 y se muestran en el listado

Listado 3

proyecto2.c

void main() { unsigned char led=0; TRISD = 0x00; // set direction to be output ADCON1 |= 0x0F;//A/D port as digital do { PORTD=(1 << led); led++; if(led==8) led=0; Delay10KTCYx(100); // delay PORTD=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 nmero 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 grcamente 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 condicin y la inicializamos en 0 nuevamente.

2.2.

Diseo en el PROTEUS

El diseo de este proyecto es bsicamente el mismo utilizado en el proyecto 1, donde se conectan

PROF. ALEXIS CABELLO

PGINA: 11

UNEXPO-LCM
Bit7 0 Bit 6 0 Bit 5 0 Bit 4 0 Bit 3 0 Bit 2 0 Bit 1 0 Bit 0 1

Nmero antes de rotar. Bit 7 0 Bit 6 0 Bit 5 0 Bit 4 0 Bit 3 1 Bit 2 0 Bit 1 0 Bit 0 0

Nmero despus 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 congurados 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 simulacin, se observa cmo con el mismo diseo, 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.

R1 U1
2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470

D1 D2 D3 D4 D5 D6 D7 D8

R2
L1 470

R3
L2 470

OSC2 OSC1

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7

R4
L3 470

R5
L4 470 VDD L5

R6
470

18

R20
4.7k L6

VUSB PIC18F4550

R7
470

R8
L7 470

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 mediante

la programacin del PIC 18F4550 para mostrar cadenas de caracteres en las diferentes lneas de la pantalla.

3.1.

Programa Proyecto3.c

Para comenzar a realizar el programa en C, esta vez se necesitan una serie de funciones adicionales o subrutinas, para poder trabajar con la pantalla LCD. Estas rutinas se describen en el Anexo A. Primero se debe incluir los archivos de encabezado (.h) y se programan los bits de conguracin mediante la instruccin

pragma, como se explic en el proyecto 1 y se muestran en el listado 1. En este proyecto PGINA: 12

PROF. ALEXIS CABELLO

UNEXPO-LCM
se debe agregar el archivo de encabezado (lcd.h) para poder hacer uso de las funciones de manejo del LCD.

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 digital PORTC = TRISC = 0x00; PORTB = TRISB = 0x00; lcd_init(); lcd_clear(); lcd_display(1,1,buffer1); lcd_display(2,3,buffer2); for(;;); }

3.2.

Diseo en el PROTEUS

En el diseo de proteus se agrega la pantalla LCD (LM016L9) y se conectan los terminales de datos al puerto B, los terminales de control al puerto E, los terminales de alimentacin de VDD a 5V, VSS y VEE a GND para obtener el mayor contraste. El diseo nal y la simulacin del proyecto se muestra en la gura 17.
R1 U1
2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470

D1 D2 D3 D4 D5 D6 D7 D8

R2
L1 470

R3
L2 470

OSC2 OSC1

RB4 RB5 RB6 RB7

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2

R4
L3 470

R5
L4 470 VDD L5 470

R6 R7
L6 470

18

VUSB

LCD2 PIC18F4550 LM016L

R20
4.7k

R8
L7 470

VSS VDD VEE

RS RW E RE0 RE1 RE2 4 5 6

VDD

Figura 17: Diseo del Proyecto 3

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

1 2 3

D0 D1 D2 D3 D4 D5 D6 D7

PGINA: 13

UNEXPO-LCM
4. Proyecto 4
El proyecto 4 se enfoca en el uso de las funciones de manejo de un teclado matricial de 4x3 mediante la programacin del PIC 18F4550. Se realiza un programa de prueba que muestra en una pantalla LCD la tecla presionada.

4.1.

Programa Proyecto4.c

Para comenzar a realizar el programa en C, esta vez se necesitan una serie de funciones adicionales o subrutinas, para poder trabajar con el Teclado. Estas rutinas se describen en el Anexo B. En este proyecto 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 B lcd_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 variable Delay10KTCYx(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

PGINA: 14

UNEXPO-LCM
Como se muestra en el listado 5, se utiliza la funcin el cdigo de la tecla presionada (1 a 12). Este cdigo se utiliza como el indice de la tabla mostrarlo en la pantalla LCD.

la cual guarda el carcter ASCII de la tecla presionada. Luego se utiliza ese carcter ASCII para

keypadread para leer una tecla, la cual retorna keycodes,

4.2.

Diseo en el PROTEUS

En el diseo de proteus se agrega la pantalla LCD (LM016L9) y un teclado matricial (KEYPAD). A las lneas de entrada al microcontrolador (RB1-RB3) se agregan resistencias de 10k conectadas al VCC (Pull-ups ), esto con el n de detectar niveles alto cuando ninguna tecla sea presionada. Esto slo se requiere a nivel de simulacin en proteus, puesto que cuando se implementa fsicamente con el microcontrolador se pueden utilizar las resistencias pull-up internas del microcontrolador a travs de la instruccin (INTCON2 &= ~0x80). El simulador no procesa correctamente esta instruccin. En la gura 18 se muestra el diseo nal y una simulacin del proyecto.
R1 U1
2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470 L1 470 L2 470 L3 19 20 21 22 27 28 29 30 8 9 10 1 470 L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2 L4 470 L5 470 VDD L6 470 L7 470 RB3 RB2 RB1

D1 D2 D3 D4 D5 D6 D7 D8

R2 R3 R4 R5 R6 R7 R8

R9 R10 R12OSC2
10k 10k 10k OSC1

RB1 RB2 RB3 RB4 RB5 RB6 RB7

18

VUSB

LCD2 PIC18F4550 LM016L

R20
4.7k

VSS VDD VEE

RS RW E

7 8 9 10 11 12 13 14

1 2 3

4 5 6

D0 D1 D2 D3 D4 D5 D6 D7

RB7

1 4 7

2 5 8 0

3 6 9 #

RB6

VDD

RB5 RE0 RE1 RE2 RB4 RB5 RB6 RB7

RB4

Figura 18: Diseo del proyecto 4

5.

Proyecto 5
En el proyecto 5 se utiliza el convertidor analgico a digital (ADC) del PIC 18F4550 para leer el

valor de tensin de una seal analgica y mostrar ese valor expresado en milivoltios por la pantalla LCD. Se emplea un potencimetro para generar una seal analgica que puede variar entre 0 y 5V, la cual se conecta al canal cero (AN0) del Convertidor ADC.

5.1.

Convertidor analgico a digital

En la gura 19 se muestra un esquema del convertidor analgico a digital (ADC) del PIC 18F4550. Este mdulo permite la conversin de una seal analgica 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 los bits CHS3-CHS0 del registro ADCON0 tal como se muestra en la gura 20.

PROF. ALEXIS CABELLO

PGINA: 15

UNEXPO-LCM

Figura 19: Convertidor Analgico a Digital

Registro ADCON0
Bit 7 -Bit 6 -Bit 5 CHS3 Bit 4 CHS2 Bit 3 CHS1 Bit 2 CHS0 Bit 1
Go/Done

Bit 0 ADON

ADON: ADC On bit 0= Convertidor deshabilitado 1: Convertidor habilitado Go/Done: Bit de estatus de la conversin 0=Conversin lista 1= conversin en progreso CHS0-CHS3: Bits de seleccin del canal 0000= 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

PGINA: 16

UNEXPO-LCM

Registro ADCON1
Bit 7 -Bit 6 -Bit 5
VCFG1

Bit 4
VCFG0

Bit 3
PCFG3

Bit 2
PCFG2

Bit 1
PCFG1

Bit 0
PCFG0

PCFG3-0: Bits de configuracin de los puertos analgicos. VCFG0: Bit de configuracin del voltaje de referencia negativo VREF0=VSS 1=AN2 VCFG1: Bit de configuracin del voltaje de referencia positivo VREF+ 0=VDD 1=AN3
PFCG3-PCFG0 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 AN12 A A A D D D D D D D D D D D D D AN11 A A A A D D D D D D D D D D D D AN10 A A A A A D D D D D D D D D D D AN9 A A A A A A D D D D D D D D D D AN8 A A A A A A A D D D D D D D D D AN7 A A A A A A A A D D D D D D D D AN6 A A A A A A A A A D D D D D D D AN5 A A A A A A A A A A D D D D D D AN4 A A A A A A A A A A A D D D D D AN3 A A A A A A A A A A A A D D D D AN2 A A A A A A A A A A A A A D D D AN1 A A A A A A A A A A A A A A D D AN0 A A A A A A A A A A A A A A A D

Figura 21: Registro ADCON1

Adquisicin
TACQ

Conversin

D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
TAD

Go TAD= 1 (Fosc/n) n=2,4,8,16,32,64

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


Figura 22: Tiempo de adquisicin-conversin

PROF. ALEXIS CABELLO

PGINA: 17

UNEXPO-LCM

Registro ADCON2
Bit 7
ADFM

Bit 6
--

Bit 5

Bit 4

Bit 3

Bit 2

Bit 1

Bit 0

ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0

ADCS2-ADCS0: Reloj de Conversin del ADC 000= Fosc/2 001= Fosc/8 010= Fosc/32 011= FRC (Oscilador RC Interno) 100= Fosc/4 101= Fosc/16 110= Fosc/64 111= FRC (Oscilador RC Interno) ADFM: Formato del Resultado del ADC 0 = Justificado a la Izquierda 1 = Justificado a la derecha

ACQT2-ACQT0: Tiempo de adquisicin del ADC 000= 0 Tad 001= 2 Tad 010= 4 Tad 011= 6 Tad 100= 8 Tad 101= 12 Tad 110= 16 Tad 111= 20 Tad

Figura 23: Registro ADCON2

ADRESH: Byte alto del resultado de la conversin ADRESL: Byte bajo del resultado de la conversin
ADRESH Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 ADRESL Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Figura 24: Resultado justicado a la derecha

PROF. ALEXIS CABELLO

PGINA: 18

UNEXPO-LCM
En las guras 21 y 23 se muestran el resto de los registros donde se congura el funcionamiento del ADC. En el registro ADCON1 se congura el voltaje de referencia positivo a VDD y el negativo a GND, as como se denen los terminales analgicos y digitales, en ste proyecto se conguran los terminales AN0-AN3 como analgicos y el resto digitales. En el registro ADCON2 se congura el tiempo de la conversin segn se muestra en la gura 22. El tiempo de conversin de cada bit (TAD) mnimo debe ser 0.8us y el tiempo de adquisicin (T utiliza el divisor de 64 y 4 TAD para el T

ACQ)

mnimo debe ser de 1.4us segn la hoja de especicaciones. Como se utiliza una Fosc de 48MHz, se

ACQ para

satisfacer los requerimientos. El resultado de la

conversin se obtiene en los registros ADRESH y ADRESL, la cual puede ser ajustado a la derecha o a la izquierda. En la gura 24 se muestra el resultado justicado a la derecha, la cual es la utilizada en este proyecto. Los valores de los registros se pueden apreciar en el listado 7 donde se congura la rutina de conversin 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 el valor de la conversin. A esta ltima se debe pasar como parmetro el canal del ADC que se quiere leer, en este proyecto se lee la seal analgica conectada al canal cero (AN0). Para mostrar el valor correspondiente en milivoltios con dos dgitos decimales por el LCD, se realiza la conversin mostrada en la ecuacin 1:

volts =
donde:

n 5000 mV 100 1024

(1)

es el valor del ADC (0-1023) que corresponde a (0-5v). Se multiplica por 100 para tomar

dos decimales de precisin. Luego se toma la parte entera diviendo los voltios entre 100 y se toma el resto de la divisin como la parte decimal, y nalmente se convierten estos valores en un cadena de caracteres ASCII para su visualizacin en la pantalla LCD.

5.3.

Diseo en el PROTEUS

En la gura 25 se muestra el diseo en proteus del proyecto 5. Se utiliza el proyecto 4 como base y se agrega un potencimetro para generar la seal analgica. El cursor del potencimetro se conecta al terminal AN0 del PIC. La gura muestra el cursor del potencimetro en 50 %, lo que corresponde a un valor de 2493.68 mV, el cual se observa en la pantalla LCD. Al variar el cursor del potencimetro se puede apreciar como se actualiza el valor medido en la pantalla LCD, funcionando el sistema como un voltmetro digital.

PROF. ALEXIS CABELLO

PGINA: 19

UNEXPO-LCM
Listado 6
proyecto5.c

#include <p18cxxx.h> #include <delays.h> #include <stdlib.h> #include "lcd.h" #pragma config PLLDIV #pragma config CPUDIV #pragma config USBDIV #pragma config FOSC #pragma config WDT #pragma config MCLRE #pragma config LVP

= = = = = = =

5 // (20 MHz crystal) OSC1_PLL2 2 // Clock source from 96MHz PLL/2 HSPLL_HS //HSPLL_HS OFF ON 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; //AN0 for(;;) // 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 result Vdec = volts / 100; // Decimal part Vfrac = volts % 100; // Fractional part itoa(Vdec,lcd); // Convert Vdec to string in "lcd" // Display result on LCD // lcd_display(1,6,lcd); // Output to LCD lcd_char(.); // Display "." ch1 = Vfrac / 10; // Calculate fractional part ch2 = Vfrac % 10; // Calculate fractional part lcd_char(48+ch1); // Display fractional part lcd_char(48+ch2); // Display fractional part Delay10KTCYx(250); // delay Delay10KTCYx(250); // delay } }

PROF. ALEXIS CABELLO

PGINA: 20

UNEXPO-LCM
Listado 7
continuacin 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 Off return result; }

U1
AN0 2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26

R9 R10 R12OSC2
10k 10k 10k OSC1

RB1 RB2 RB3 RB4 RB5 RB6 RB7

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2

VDD

18 VDD

VUSB

LCD2 PIC18F4550 LM016L RV1

R20
4.7k

50%

VSS VDD VEE

RS RW E 4 5 6 RE0 RE1 RE2

1 2 3

10k

VDD

Figura 25: Diseo del proyecto 5

6.

Proyecto 6
En el proyecto 6 se utilizan las interrupciones para realizar un reloj digital a partir de una fuente

de alimentacin de corriente alterna de 60Hz. La fuente alterna alimenta un circuito que genera un pulso por cada cruce por cero de la seal (detector de cruce por cero) y esta seal se utiliza como una fuente de interrupcin externa para el conteo del tiempo.

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

D0 D1 D2 D3 D4 D5 D6 D7

AN0

PGINA: 21

UNEXPO-LCM
U1
AN0 2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26

R12
10k 10k RB1 RB2 RB3

R14
10k OSC2 OSC1 RB0

R13

RB4 RB5 RB6 RB7

19 20 21 22 27 28 29 30 8 9 10 1

L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2

VDD

18 VDD VDD

VUSB

LCD2 PIC18F4550 LM016L RV1


VSS VDD VEE

R20
4.7k

BR1 V1
VSINE VO=0 VA=20 FREQ=60

RS RW E 4 5 6 RE0 RE1 RE2

2W08G

1 2 3

10k

2 K 4N25 K E

4 VDD

Figura 26: Diseo 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 declaracin de las interrupciones en el compilador MPLAB C18. En los microcontroladores 18F existen dos vectores de interrupcin, uno de alta prioridad y otro de baja prioridad. El vector de alta prioridad se encuentra en la direccin 0x08h y el de baja prioridad en el la direccin 0x18h. El bit IPEN del registro RCON habilita las prioridades de las interrupciones. Si el bit IPEN=0 como es por defecto no se utilizan las prioridades de las interrupciones y todas utilizan el vector de interrupcin de alta prioridad (0x08h). En este proyecto no se utilizan las prioridades y se emplea la directiva el vector de interrupcin de alta prioridad el salto a la rutina de interrupcin y se utiliza la directiva

#pragma code para escribir en

#pragma interrupt para indicar cual es la rutina de interrupcin.

Como la frecuencia de la fuente de alimentacin es de 60Hz, el circuito detector de cruce por cero

genera 120 pulsos en un segundo. Por esto, en la rutina de interrupcin se acumula cada vez que se genera una interrupcin y cuando se alcanza 120 se pone en cero y se empienza a incrementar los segundos. Igualmente se procede con los segundos, cuando se alcanzan los 60 se pone en cero y se empiezan a incrementar los minutos hasta alcanzar los 60 minutos donde se pone en cero y empieza de nuevo el reloj. En la rutina principal del programa se habilita la interrupcin INT0 y luego en un bucle innito se convierten constantemente los minutos y segundos a ASCII y se muestra en la pantalla LCD el tiempo.

6.2.

Diseo en PROTEUS

En la Figura 26 se muestra el diseo en proteus. Para la simulacin se emplea una fuente alterna de 13Vac y el circuito detector de cruce por cero aislado del microcontrolador por medio de un optoacoplador 4N25, la seal de salida del detector (RB0) se conecta al terminal de interrupcin externa (INT0). En la simulacin se muestra el reloj indicando que ha transcurrido 1 minuto y 06 segundos.

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

B C

6 5

RB0

D0 D1 D2 D3 D4 D5 D6 D7

R11 U2 240

R10
10k
50%

AN0

PGINA: 22

UNEXPO-LCM
Listado 8
proyecto6.c

#include <p18cxxx.h> #include <delays.h> #include <stdlib.h> #include "lcd.h" #pragma config PLLDIV #pragma config CPUDIV #pragma config USBDIV #pragma config FOSC #pragma config WDT #pragma config LVP

= = = = = =

5 // (20 MHz crystal) OSC1_PLL2 2 // Clock source from 96MHz PLL/2 HSPLL_HS //HSPLL_HS OFF 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 = 0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh //jump to interrupt routine _endasm } //---------------------------------------------------------------------------// High priority interrupt routine #pragma code #pragma interrupt InterruptHandlerHigh void 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

PGINA: 23

UNEXPO-LCM

Listado 9

continuacin de proyecto6.c

void main() { TRISA=TRISB=TRISC=TRISD = 0x00; PORTD=0x0; ADCON1 = 0x0F; lcd_init(); TRISBbits.RB0=1; INTCONbits.GIE = 1; INTCONbits.PEIE = 1;

// set direction to be output

//enable global interrupts //enable peripherical interrupts

INTCONbits.INT0IE =1; //enable INT0 Interrupt lcd_clear(); lcd_display(1,1,msg); do{ setpos(1,7); ch1 = min / 10; // digit1 ch2 = min % 10; // digit2 lcd_char(48+ch1); // Display digit1 lcd_char(48+ch2); // Display digit2 lcd_char(:); ch1 = seg / 10; // digit1 ch2 = seg % 10; // digit2 lcd_char(48+ch1); // Display digit1 lcd_char(48+ch2); // Display digit2 }while(1); }

PROF. ALEXIS CABELLO

PGINA: 24

UNEXPO-LCM
7. Proyecto 7
En el proyecto 7 se muestra el uso del temporizador del microcontrolador para tener un control exacto del tiempo y as generar una seal cuadrada de 120Hz. El ciclo de trabajo de la seal cuadrada generada es de 50 % pero cambiando el valor en una variable se puede cambiar el ancho de pulso o ciclo de trabajo.

7.1.

Temporizador

El microcontrolador PIC 18F4550 tiene cuatro temporizadores TIMER0-3. En el siguiente proyecto utilizamos el TIMER2 que es bsicamente un contador de 8 bits (TMR2) con un divisor de pre-escalado y 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 incremento depende del valor del divisor del reloj o pre-escalado (PRESCALER), el cual puede ser 1, 4, o 16. Para jar el periodo del temporizador (PR2) se puede utilizar la ecuacin 2

T = (P R2 + 1) 4
donde:

1 P RESCALER Fosc

(2)

Fosc es la la frecuencia del oscilador P RESCALER es el valor del divisor T es el periodo de la seal a generar P R2 es el valor del registro

del oscilador para el temporizador

El valor del contador TMR2 se compara con el valor del registro PR2 en cada ciclo de reloj y cuando el contador TMR2 es igual al registro PR2 el comparador produce una seal que va al contador de pos-escalado y pone en cero el contador TMR2. Dependiendo del valor prejado de pos-escalado se activa la bandera de interrupcin TMR2IF que se encuentra en el registro PIR1. En este proyecto como el pos-escalado es igual a 1, la interrupcin se genera cuando el valor de TMR2 es igual al valor de PR2. Para habilitar la interrupcin del temporizador 2 se utiliza el bit TMR2IE del registro PIE1. Los valores de pre-escalado y pos-escalado se conguran en el registro T2CON tal como se muestra en la gura 28.

PROF. ALEXIS CABELLO

PGINA: 25

UNEXPO-LCM
Registro T2CON
Bit 7
--

Bit 6
T2OUTPS3

Bit 5
T2OUTPS0

Bit 4
T2OUTPS1

Bit 3
T2OUTPS0

Bit 2
TMR2ON

Bit 1
T2CKPS1

Bit 0
T2CKPS0

T2CKPS1-0: Pre-escalar del reloj del Timer 2 00= 1:1 01= 1:4 1x= 1:16 TMR2ON: Activacin del Timer2 1=Activado (ON) 0= Desactivado (OFF) T2OUTPS3-0: Post-escalar de la salida del Timer 2 0000= 1:1 0001= 1:2 . . 1111= 1:16

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 seal a generar (8.33ms) se divide entre 512 y se utiliza el temporizador 2 para generar una interrupcin cada 16.275us. Para generar la seal cuadrada con 50 % de ciclo de trabajo lo primero que se hace es incrementar un contador por cada interrupcin y cuando alcanza el valor medio de 256 se pone en bajo la seal y cuando alcanza el valor mximo de 512 se pone en cero el contador y se pone la seal en alto.

Listado 10

proyecto7.c

#include <p18cxxx.h> #include <delays.h> #include <stdlib.h> #include "lcd.h" #pragma config PLLDIV #pragma config CPUDIV #pragma config USBDIV #pragma config FOSC #pragma config WDT unsigned int count=0;

= = = = =

5 // (20 MHz crystal) OSC1_PLL2 2 // Clock source from 96MHz PLL/2 HSPLL_HS //HSPLL_HS OFF

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

PROF. ALEXIS CABELLO

PGINA: 26

UNEXPO-LCM
Listado 11
continuacin de proyecto7.c

// High priority interrupt vector #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh //jump to interrupt routine _endasm } // High priority interrupt routine #pragma code #pragma interrupt InterruptHandlerHigh void 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 output PORTD=0x0; ADCON1 = 0x0F; INTCONbits.GIE = 1; //enable global interrupts INTCONbits.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=1 T2CON=0; T2CONbits.T2CKPS1 = 0; T2CONbits.T2CKPS0 = 0; // 1:1 - prescaler IPR1bits.TMR2IP = 1; PIR1bits.TMR2IF = 0; PIE1bits.TMR2IE = 1; T2CONbits.TMR2ON = 1; } // high priority //1=enable Interrupt

PROF. ALEXIS CABELLO

PGINA: 27

UNEXPO-LCM
7.3. Diseo en PROTEUS

En la Figura 29 se muestra el diseo en proteus del proyecto 7, solamente se ha agregado el osciloscopio para observar la seal cuadrada. Se conecta la salida RD0 del puerto D del PIC al canal A del osciloscopio. En la Figura 30 se muestra la pantalla del osciloscopio, en la cual se puede apreciar el periodo de la seal.

R1 U1
AN0 2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 L0 470 L1 470 L2 470 L3 19 20 21 22 27 28 29 30 8 9 10 1 470 L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2 L4 470 L5 470 VDD L6 470 L7 470

D1 D2 D3 D4 D5 D6 D7 D8

R2 R3 R4 R5 R6 R7 R8

R12
10k 10k RB1 RB2 RB3

R14
10k OSC2 OSC1 RB0

R13

RB4 RB5 RB6 RB7

18 VDD

VUSB

LCD2 PIC18F4550 LM016L RV1

R20
4.7k

L0

A B

50%

VSS VDD VEE

RS RW E

D0 D1 D2 D3 D4 D5 D6 D7

AN0

C D

10k

VDD

RE0 RE1 RE2

Figura 29: Diseo del proyecto 7

Figura 30: Simulacin del proyecto 7

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

1 2 3

4 5 6

PGINA: 28

UNEXPO-LCM

Figura 31: Diagrama del mdulo PWM

8.

Proyecto 8
En el proyecto 8 se utiliza el mdulo CCP1 del microcontrolador. Se congura el mdulo CCP1 en

modo PWM estndar para generar una seal cuadrada de 4KHz con 50 % de ciclo de trabajo pero a la cual se le puede modicar el ancho del pulso.

8.1.

Mdulo CCP (Captura, Comparador y PWM)

El microcontrolador PIC 18F4550 tiene dos mdulos CCP. En este proyecto se utiliza el mdulo CCP1 en su modo de funcionamiento de PWM (modulador de ancho de pulso). En la gura 31 se muestra un diagrama del mdulo PWM. El mdulo permite generar una seal PWM con 10 bits de resolucin. El mdulo CCP genera los 10 bits de resolucin del PWM uniendo los 8 bits del contador TMR2 con 2 bits del divisor de pre-escalado, tal como se observa en la Nota 1 de la gura 31. Estos 10 bits se comparan con los 10 bit del ciclo de trabajo para generar la seal PWM. En la gura 32 se muestra una seal de salida PWM. La seal PWM tiene una base de tiempo jo o perodo y un tiempo variable en que se encuentra en alto o ciclo de trabajo (ancho del pulso). Tal como se puede apreciar en la gura 31, el mdulo utiliza el TIMER2 como contador para generar la seal PWM. El perodo de la seal se ja escribiendo el registro PR2 segn la ecuacin 2. El ciclo de trabajo puede tener hasta 10 bits de resolucin y se establece escribiendo en los registros CCPRxL y CCPxCON, tal como se muestra en la gura 33. Para congurar el mdulo CCP en modo PWM se escribe 1 en los bits CCPxM2-3 del registro CCPxCON tal como se muestra en la gura 34.

PROF. ALEXIS CABELLO

PGINA: 29

UNEXPO-LCM

Ciclo de trabajo PERIODO TMR2=PR2 TMR2=Ciclo de trabajo TMR2=PR2

Figura 32: Seal de salida del mdulo PWM

Ciclo de trabajo
CCPxL: Byte mas significativo de los 10Bit del ciclo de trabajo. CPxB0-CPxB1: 2 bits menos significativos de los 10Bits del ciclo de trabajo
CCPxL Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 CCPxCON Bit 0

Figura 33: Ciclo de trabajo del PWM

Registro CCPxCON
Bit 7
--

Bit 6
--

Bit 5
DCxB1

Bit 4
DCxB0

Bit 3
CCPxM3

Bit 2
CCPxM2

Bit 1
CCPxM1

Bit 0
CCPxM0

CCPxM0-M3: Seleccin del modo de operacin 0000= Capture/compare/ PWM deshabilitado 0001= reservado 0010= comparador: Cambia la salida cuando sea igual 0011= reservado 0100= modo de captura: cada flanco de caida 0101= modo de captura: cada flanco de subida 0110= modo de captura: cada 4 flanco de subida 0111= modo de captura: cada 16 flanco de subida 1000= comparador: Cambia la salida cuando sea igual 1001= comparador: Cambia la salida cuando sea igual 1010= comparador: Genera interrupcin cuando sea igual 1011= comparador: dispara un evento especial, comienza la conversin ADC 11xx= modo PWM DCxB0-DCxB1: Bit0 y Bit1 para el Ciclo de trabajo del PWM

Figura 34: Registro CCPxCON

PROF. ALEXIS CABELLO

PGINA: 30

UNEXPO-LCM
8.2. Programa proyecto8.c

En el listado 12 se muestra el programa proyecto8.c. Para utilizar el mdulo CCP1 en modo PWM estndar se congura el registro CCP1CON, escribiendo los bits CCP1M3-CCP1M2 con 1 . El periodo de la seal PWM lo determina el periodo del temporizador 2 y se congura escribiendo el registro PR2. El periodo se calcula a travs de la ecuacin 2. El mdulo CCP permite producir una seal PWM hasta con 10bits de resolucin. Para congurar el ciclo de trabajo de trabajo se escribe en el registro CCPR1L los 8 bits mas signicativos y los otros dos bits se escriben en los bit DC1B1-DC1B0 del registro CCP1CON. La salida de la seal PWM se produce por el pin RC2 del puerto C, por lo que esta seal debe ser habilitada como salida para obtener la seal PWM.

8.3.

Diseo en PROTEUS

En la Figura 35 se muestra el diseo en proteus del proyecto 8, El diseo es bsicamente el mismo que el anterior, solo que se conecta la salida RC2 del puerto C al osciloscopio para poder observar la seal PWM generada. La pantalla del osciloscopio donde se observa la seal PWM generada por el programa se muestra en la Figura 36.

R1 U1
AN0 2 3 4 5 6 7 14 13 33 34 35 36 37 38 39 40 RA0/AN0 RC0/T1OSO/T1CKI RA1/AN1 RC1/T1OSI/CCP2/UOE RA2/AN2/VREF-/CVREF RC2/CCP1/P1A RA3/AN3/VREF+ RC4/D-/VM RA4/T0CKI/C1OUT/RCV RC5/D+/VP RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK RA6/OSC2/CLKO RC7/RX/DT/SDO OSC1/CLKI RB0/AN12/INT0/FLT0/SDI/SDA RB1/AN10/INT1/SCK/SCL RB2/AN8/INT2/VMO RB3/AN9/CCP2/VPO RB4/AN11/KBI0/CSSPP RB5/KBI1/PGM RB6/KBI2/PGC RB7/KBI3/PGD RD0/SPP0 RD1/SPP1 RD2/SPP2 RD3/SPP3 RD4/SPP4 RD5/SPP5/P1B RD6/SPP6/P1C RD7/SPP7/P1D RE0/AN5/CK1SPP RE1/AN6/CK2SPP RE2/AN7/OESPP RE3/MCLR/VPP 15 16 17 23 24 25 26 RC2 L2 470 L3 19 20 21 22 27 28 29 30 8 9 10 1 470 L0 L1 L2 L3 L4 L5 L6 L7 RE0 RE1 RE2 L4 470 L5 470 VDD L6 470 L7 470 L0 470 L1 470

D1 D2 D3 D4 D5 D6 D7 D8

R2 R3 R4 R5 R6 R7 R8

R12
10k 10k RB1 RB2 RB3

R14
10k OSC2 OSC1 RB0

R13

RB4 RB5 RB6 RB7

18 VDD

VUSB

LCD2 PIC18F4550 LM016L RV1

R20
4.7k

RC2

A B

50%

VSS VDD VEE

RS RW E

D0 D1 D2 D3 D4 D5 D6 D7

AN0

C D

10k

VDD

RE0 RE1 RE2

Figura 35: Diseo del proyecto 8

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

1 2 3

4 5 6

PGINA: 31

UNEXPO-LCM
Listado 12
proyecto8.c

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

unsigned int count=0; void initPWM (void); void main() { TRISA=TRISB=TRISC=TRISD = 0x00; PORTD=0x0; ADCON1 = 0x0F; INTCONbits.GIE = 1; INTCONbits.PEIE = 1; initPWM(); while(1); } void initPWM (void) { PR2 = 187; // T pwm = (PR2+1)*4*(1/FOSC)*PRESCALER CCPR1L = 94; // 50 % duty cycle T2CON=0; T2CONbits.T2CKPS1 = 1; T2CONbits.T2CKPS0 = 0; IPR1bits.TMR2IP = 0; PIR1bits.TMR2IF = 0; PIE1bits.TMR2IE = 0; T2CONbits.TMR2ON = 1; CCP1CON = 0; CCP1CONbits.DC1B1=0; CCP1CONbits.DC1B0=0; CCP1CONbits.CCP1M3=1; CCP1CONbits.CCP1M2=1; TRISCbits.TRISC2 = 0; } // set direction to be output

//enable global interrupts //enable peripherical interrupts

// 16 - prescaler // low priority //disable Interrupt

//Duty cicle //PWM mode //RC1 output

PROF. ALEXIS CABELLO

PGINA: 32

UNEXPO-LCM

Figura 36: Simulacin del proyecto 8

PROF. ALEXIS CABELLO

PGINA: 33

UNEXPO-LCM

Anexo A
Manejo de la pantalla LCD
Las pantallas LCD son dispositivos que se utilizan para visualizar informacin. Los dispositivos LCD poseen internamente un microcontrolador especico que sirven para regular el funcionamiento de los mismos. Las pantallas mas comunes estn formados por una matriz de 5*7 pixels en una o en varas lneas, en el siguiente proyecto se trabajar con una pantalla LCD que permite trabajar dos lneas de 16 caracteres cada una y, que posee un microcontrolador 44780. Esta pantalla que se muestra en la gura 37 posee 14 terminales que sern explicados con detalle a continuacin.

VSS VDD VEE

RS RW E 4 5 6 RE0 RE1 RE2

1 2 3

VDD

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 categoras, los tres primeros son los terminales de alimentacin, los siguientes tres terminales son los utilizados para control del LCD y los ltimos 8 respectivamente, son utilizados para transferir los datos.

Terminales de Alimentacin
1. VSS: Se aplica la tierra 2. VDD: Se aplica la alimentacin de 5 voltios 3. VEE: Normalmente este terminal se conecta a un potencimetro que permita variar un voltaje entre 0 a 5 voltios y as observar la diferencia de brillo y contraste que se puede tener en la pantalla 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, se entiende por comandos todas aquellas instrucciones que sirven para inicializar la pantalla, borrar pantalla, 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 enva es la data, generalmente el cdigo ASCII del carcter a mostrar.

PROF. ALEXIS CABELLO

RB4 RB5 RB6 RB7

7 8 9 10 11 12 13 14

D0 D1 D2 D3 D4 D5 D6 D7

PGINA: 34

UNEXPO-LCM
2. RW: Este terminal corresponde a Read/Write, es decir, es el terminal que indica si vamos a leer o 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. si no se activa este terminal, la informacin en D0-D7 no se lee o escribe.

Terminales para Data

Estos 8 terminales reciben los caracteres ASCII a representar, as como

ciertos cdigos de control que regulan los efectos de visualizacin o para obtener informacin sobre el estado interno del dispositivo. El dispositivo LCD responde a una serie de comandos con los que se puede manipular sus distintas opciones de trabajo, para lo cual se hace referencia a la tabla 2.

Comando Clear Display Home Entry Mode Set Display On/O Cursor Display Shift Function Set Set CGRAM Address Set DDRAM Address Read Busy Flags Address Write Data to CG o DD Read Data to CG o DD

RS 0 0 0 0 0 0 0 0 0 1 1

R/W 0 0 0 0 0 0 0 0 1 0 1

E 1 1 1 1 1 1 1 1 1 1 1

D7 0 0 0 0 0 0 0 1 BF

D6 0 0 0 0 0 0 1

D5 0 0 0 0 0 1

D4 0 0 0 0 1 DL

D3 0 0 0 1 S/C N

D2 0 0 1 D R/L F

D1 0 1 I/D C x x

D0 1 x S B x x

Tiempo de Ejecucin 1.64 ms 1.64 ms 40 us 40 us 40 us 40 us 40 us 40 us 40 us 40 us 40 us

Direccin de la CGRAM Direccin de la DDRAM Direccin de la CGRAM o DDRAM Cdigo ASCII para la RAM Cdigo Almacenado en RAM

Tabla 2: Cdigos de los Comandos a los que responde el Dispositivo LCD

A continuacin se explica con detalle todas las abreviaturas utilizadas en la tabla S: Se reere a la visualizacin, si vale 1, indica que cada vez que escribe un dato, la visualizacin se desplaza automticamente a la siguiente posicin, por el contrario si vale 0, funciona de forma normal. I/D: Se reere al cursor, si vale 1, el cursor se incrementa automticamente de direccin luego de escribir, si vale 0, ste se decrementa. S/C: Si vale 1 se desplaza la visualizacin, 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 presentacin se hace en dos lneas, si vale 0 se hace en una sola lnea. F: Este indica el tamao o la caja de los caracteres, si vale 1 es de 5x10 pixels, si vale 0, es de 5x7.

PROF. ALEXIS CABELLO

PGINA: 35

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 continuacin se describen la funcin de los comandos que controlan el dispositivo LCD Clear Display: Este comando borra la pantalla del dispositivo LCD y coloca el cursor en la primera posicin, que es la direccin 0, por defecto coloca el bit I/D en 1 para autoincremento de la posicin del cursor. Home: Pone el cursor en la direccin 0 y no vara el contenido de la memoria DDRAM que guarda los datos y que queda direccionada desde la posicin 0. Entry Mode Set: Establece la direccin del movimiento del cursor, si coloca el bit S en 1 desplaza la visualizacin cada vez que se escribe un dato, si S vale 0 la visualizacin es normal. Display On/O: Activa o Desactiva al Display (D) y al cursos (C) y determina si ste es intermitente o no. Cursor Display Shift: Mueve el cursor y desplaza la visualizacin sin cambiar el contenido de la memoria DDRAM. Function Set: Establece el nmero de lneas que se van a utilizar, con el bus de datos, siendo normalmente que sea de 8 bits, por lo que DL=1 y especca el nmero de lneas de caracteres, que para que sean dos se debe colocar N=1 y el formato del carcter si F=0 entonces es de 5x7 pixels. Set CGRAM Adress: El dispositivo LCD tiene denidos los caracteres ASCII, sin embargo permite que el usuario pueda denir un mximo de nueve caracteres nuevos. stos se guardan en CGRRAM. Con este comando se indica la direccin de la CGRAM a partir de la cual se irn almacenando los bytes que denen al nuevo carcter. Luego de ejecutar este comando todos los datos que se lean o escriban posteriormente lo hacen desde esa posicin de la CGRAM. Set DDRAM Adress: Establece la direccin de la DDRAM, a partir de la cual todos los datos que se lean o escriban posteriormente lo harn desde esta posicin. Es los 16 caracteres del primer rengln 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, que indica si todava se est ejecutando un comando previo en la pantalla, y adems proporciona la direccin 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. Tambin 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 segn haya sido la instruccin de direccionamiento anterior, que har que se reeje 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 para lectura 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 denen los cdigos de los comandos principales mostrados en la tabla 2. El archivo de encabezado (lcd.h) se muestra en el listado 13:

PROF. ALEXIS CABELLO

PGINA: 36

UNEXPO-LCM
Listado 13
Archivo de encabezado LCD.h

typedef typedef typedef typedef typedef typedef typedef typedef typedef typedef typedef

void VOID; int INT; signed char INT8; signed int INT16; signed long INT32; unsigned short WORD; char CHAR; unsigned char BYTE; double FLOAT; long LONG; 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 #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); 0x04

PROF. ALEXIS CABELLO

PGINA: 37

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); // wrcmd8(LCD_SETFUNCTION+0x10); // wrcmd8(LCD_SETFUNCTION+0x12); // #ifdef BIT8 wrcmd8(LCD_SETFUNCTION+0x18); // #else wrcmd8(LCD_SETFUNCTION+0x08); // wrcmd(LCD_SETFUNCTION+0x08); // #endif wrcmd(LCD_SETVISIBLE+0x04); // wrcmd(LCD_SETMODE+0x02); // wrcmd(LCD_SETDDADDR+0x00); // } 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)); else wrcmd(LCD_SETDDADDR+0x40+(x-1)); }

Software reset.

8-bit mode - 2 line - 5x7 font. 4-bit mode - 2 line - 5x7 font. 4-bit mode - 2 line - 5x7 font. Display, no cursor - no blink. Automatic Increment - No Display shift. Address DDRAM with 0 offset 80h.

PROF. ALEXIS CABELLO

PGINA: 38

UNEXPO-LCM
Listado 15
continuacin 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; _asm NOP NOP _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 BIT8 PORTB = (cmdcode); #else PORTB = (cmdcode & 0xF0); // Get the most significant nibble first. #endif PORTE = LCD_CMD_WR; // Specify a command write operation. PORTE |= E_PIN_MASK; // Toggle the E pin to send the command. _asm NOP NOP _endasm PORTE &= ~E_PIN_MASK; #ifdef BIT8 lcd_wait(); // Call the wait routine. #else TRISB = 0x0F; PORTB = (cmdcode << 4); // Repeat for least significant nibble. PORTE = LCD_CMD_WR; PORTE |= E_PIN_MASK; _asm NOP NOP _endasm PORTE &= ~E_PIN_MASK; lcd_wait(); // Call the wait routine. #endif }

PROF. ALEXIS CABELLO

PGINA: 39

UNEXPO-LCM
Listado 16
continuacin 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 BIT8 PORTB = data; #else PORTB = data & 0xF0; // Get the most significant nibble first. #endif PORTE = LCD_DATA_WR; // Specify a data write operation. PORTE |= E_PIN_MASK; // Toggle the E pin to send the command. _asm NOP NOP _endasm PORTE &= ~E_PIN_MASK; #ifdef BIT8 lcd_wait(); // Call the wait routine. #else TRISB = 0x0F; PORTB = (data << 4); // Repeat for least significant nibble. PORTE = LCD_DATA_WR; PORTE |= E_PIN_MASK; _asm NOP NOP _endasm PORTE &= ~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 dene la variable BIT8 por medio del comando del preprocesador del compilador (#dene BIT8). Si esta denida la variable se realizar la conguracin para 8 bits y en caso contrario se congura para 4 bits.

Rutina lcd_display(y, x, string)

Esta rutina permite mostrar en la pantalla LCD una cadena

de caracteres. Se debe pasar como parmetros las coordenadas de la pantalla (y, x) a partir de donde se empieza a mostrar la cadena de caracteres. y: nmero de la la o lnea (1 o 2) x: numero de la columna (1 a 16) string: cadena de caracteres a mostrar.

PROF. ALEXIS CABELLO

PGINA: 40

UNEXPO-LCM
Rutina lcd_char(char)
char = carcter a mostrar. Esta rutina permite mostrar un carcter en la posicin actual del cursor. El cursor se incrementa y queda en la siguiente posicin de la pantalla.

Rutina lcd_clear()

Esta rutina permite borrar toda la pantalla LCD y se posiciona el cursor

en coordenadas de inicio (1,1).

Rutina setpos(y,x)

Esta rutina permite mover el cursor. Se debe pasar como parmetros las

coordenadas de la pantalla (y, x). y: nmero de la la o lnea (1 o 2). x: nmero de la columna (1 a 16). Las rutinas que se describen a continuacin son las rutinas de bajo nivel que son utilizadas para enviar los comandos y los datos a la pantalla LCD. Estas rutinas son utilizadas por las rutinas descritas anteriormente por controlar las funciones de la pantalla LCD.

Rutina wrcmd8(comando)

Esta rutina escribe el cdigo de comando pasado como parmetro

a la pantalla LCD a travs del modo de transferencia de 8 bits y espera a que el LCD termine de ejecutar la operacin. Esta rutina se utiliza en la funcin lcd_init() ya que al encender la pantalla esta queda inicializada en modo de transferencia de 8 bits.

Rutina wrcmd(comando)

Esta rutina escribe el cdigo de comando pasado como parmetro

a la pantalla LCD a travs del modo de transferencia congurado en la rutina lcd_init(), es decir en 4 bits o en 8 bits. La rutina espera a que el LCD termine de ejecutar la operacin.

Rutina wrdata(char)
LCD.

Esta rutina escribe el carcter (char) pasado como parmetro a la pantalla

Rutina lcd_wait()

Esta rutina espera para que el LCD termine de procesar el comando enviado.

PROF. ALEXIS CABELLO

PGINA: 41

UNEXPO-LCM

Anexo B
Manejo del Teclado Matricial
Un teclado matricial es un dispositivo de entrada de datos donde las lneas necesarias para detectar la tecla pulsada se agrupan de forma matricial en las y columnas con el n de disminuir las lneas requeridas. Para un teclado de 12 teclas solo se requieren de 7 lneas de entrada/salida del microcontrolador para manejar el teclado. En la gura 38 se muestra el esquema de un teclado matricial de 12 teclas.

RB3

RB2

RB1

B1
RB7 4

B2
5

B3
6

B4
RB6 7

B5
8

B6
9

RB5

B7
*

B8
0

B9
#

RB4

B10

B11

B12

Figura 38: Teclado Matricial de 4x3

Las lneas RB1-RB3 en la gura son ledas por el nible inferior del puerto B (RB1-RB3), por lo que se tienen que congurar como entradas, mientras que las del nible superior (RB4-RB7) se conguran como salidas y es donde se aplican el patrn de estados lgicos para ser ledos por el nible inferior. El programa que se muestra en el listado 17 gestiona el manejo del teclado, en el mismo se saca secuencialmente un nivel bajo por una de las 4 lneas de salida que se aplican a las las (RB4-RB7), al mismo tiempo que se lee el nivel lgico que llega al nible inferior o columnas (RB1-RB3). Si al leer este nible, una de las lneas se encuentra en nivel bajo, se deduce que la tecla asociada a dicha la y dicha columna se encuentra presionada. Cada tecla tiene un cdigo asociado desde el 1 al 12. Luego estos cdigos pueden ser sustituidos por un cdigo ASCII por medio del uso de un tabla.

PROF. ALEXIS CABELLO

PGINA: 42

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 teclado

para detectar si se ha presionado una tecla. La rutina realiza un solo barrido y si una tecla es presionada retorna el cdigo de la misma, por el contrario si ninguna tecla es presionada la rutina retorna cero.

PROF. ALEXIS CABELLO

PGINA: 43

UNEXPO-LCM
Rutina keypadread()
Esta rutina llama a la rutina scankey y si una tecla fue presionada la rutina espera hasta que la tecla deje de estar presionada y luego retorna el cdigo del tecla.

PROF. ALEXIS CABELLO

PGINA: 44

También podría gustarte