ejemplos simples c18

27
2015 UNIVERSIDAD DE PIURA Programación C18 - FACULTAD DE INGENIERIA 1

Upload: jorge-d-moralez

Post on 25-Jan-2016

251 views

Category:

Documents


1 download

DESCRIPTION

C18

TRANSCRIPT

Page 1: Ejemplos Simples c18

20

15

UNIVERSIDAD DE PIURA

- 1

Page 2: Ejemplos Simples c18

- 2

Contenido

Control de un Display.............................................................................................................................................3

Conceptos Básicos:.............................................................................................................................................3

Descripción del Circuito:.................................................................................................................................4

Programación:......................................................................................................................................................5

Programación C18

Page 3: Ejemplos Simples c18

3

- 3

Control de un LED mediante un pulsador

Conceptos Básicos:

LED (Light-Emitting-Diode): un LED resulta no ser más que un diodo, la diferencia con un diodo común radica en que al estar polarizado directamente este libera energía en forma de fotones. Este efecto es llamado electroluminiscencia, el color de la luz se determina a través de la banda de energía del semiconductor.

Descripción del circuito:

Programación C18

Page 4: Ejemplos Simples c18

4

- 4

Elementos:o PIC 18f4550: Microcontroladoro RES: Resistencias de 330R y 1K o LED: LED de color rojo para nuestro ejemploo BUTTON: Botón pulsador

Explicación:o Se alimenta al microcontrolador mediante la fuente de poder

(POWER) conectada al pin 1, por defecto este entrega 5V, los necesarios para la alimentación del microcontrolador.

o Se conecta un pulsador, el cual uno de sus extremos se conecta a un POWER y el otro extremo se conecta al pin RA0 del microcontrolador. Cuando el BUTTON sea pulsado comunicara una señal de 5V o 1L al PIC, caso contrario la señal que recibe el PIC será de 0V o 0L.

o El ejercicio consiste en configurar el pin RA0 como entrada al microcontrolador, este deberá leer la entrada lógica que registra en este puerto y mostrarla en el pin RD0

Programación:

Control de un Display

Conceptos Básicos:

#include <p18f4550.h> //incluimos la libreria del uC#include <config.h> //inlcluimos la libreria que define los parametros de trabajo del uC

void main (void){

ADCON1=0x0F; //Todas son definidas como entradas/salidas digitalesTRISAbits.TRISA0=1; //Pin RA0 es definido como entrada (input)TRISDbits.TRISD0=0; //Pin RD0 es definido como salida (output)LATDbits.LATD0=0; //La salida RD0 se establece en 0 lógico

while(1){LATDbits.LATD0=PORTAbits.RA0; //La salida del Pin RD0 toma el valor lógico de la entrada RA0}

}

Page 5: Ejemplos Simples c18

5

- 5

1. Como primer paso en la programación se incluye las librerías del microcontrolador al igual que la librería que define los parámetros de trabajo del microcontrolador.

2. Al ingresar al programa principal o main lo primero es realizar la configuración de los pines de trabajo en el microcontrolador. A continuación se detalla la configuración empleada

a. ADCON1: comando que permite configurar los pines de trabajo como entradas/salidas digitales, es decir, en cada pin solo se podrá leer 0L o 1L.

b. TRIS: comando que permite configurar los pines de trabajo como entradas o salidas, escribiendo 1 ó 0 respectivamente. La sintaxis tiene dos formas: configurar todo el puerto o hacer una configuración por bit.

i. TRISA = 1; con esta sintaxis configuro TODOS los bits del Puerto A como entradas.

ii. TRISAbits.RA0 = 1; con esta sintaxis configuro el bit RA0 del Puerto A como entradas.

c. LAT: comando que me permite escribir valores lógicos 0L o 1L en los pines configurados como salidas. Su sintaxis es parecida a la del TRIS, por lo tanto se puede configurar todo el puerto o solo los pines deseados.

3. Ingresa al bucle infinito, que me permitirá repetir infinitas veces las líneas de programación en el incluidas. Para nuestro ejercicio recogerá infinitas veces el valor lógico que posea el pin RA0, pin donde está conectado el pulsador, y lo escribirá en el pin RD0, pin donde está conectado el LED. De esta forma se encenderá el LED cada vez que presionemos el pulsador.

Page 6: Ejemplos Simples c18

6

- 6

LED secuenciales empleando Delays

Conceptos Básicos:

Para el siguiente ejemplo se utilizara los 8 pines del Puerto D, de tal manera que se utilizara como una variable de 8 bits, en la cual se escribirá el valor binario de una variable, por ejemplo al copiar el valor de una variable i que sea igual a 19 en el Puerto D se escribirá 00010011 siendo RD0 el bit menos significativo.

NúmeroPUERTO D

RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD01 0 0 0 0 0 0 0 12 0 0 0 0 0 0 1 04 0 0 0 0 0 1 0 08 0 0 0 0 1 0 0 0

16 0 0 0 1 0 0 0 032 0 0 1 0 0 0 0 064 0 1 0 0 0 0 0 0

128 1 0 0 0 0 0 0 0

Descripción del Circuito:

Page 7: Ejemplos Simples c18

7

- 7

Elementos:o PIC 18f4550: Microcontroladoro RES16DIPIS: Barra de 9 resistenciaso LED-BARGRAPH: Barra de 10 LED de color verde o RES: Resistencia de 1K

Explicación:o Se alimenta al microcontrolador mediante la fuente de poder

(POWER) conectada al pin 1, por defecto este entrega 5V, los necesarios para la alimentación del microcontrolador.

o El ejercicio consiste en configurar el puerto D como salida, y copiar el valor de una variable i en este puerto, para que sus valores lógicos enciendan uno a uno los segmentos de la barra de LED de tal forma que se aprecie un desplazamiento secuencial descendente.

o La función de la barra de resistencias es generar una caída de tensión en el voltaje que está llegando a los pines de la barra de LED, para protegerlos.

Programación:

#include <p18f4550.h> //incluimos la libreria del uC#include <delays.h> //inlcuimos la libreria de los delays para poder llamarlos a través de funciones#include <config.h> //incluimos los parametros de configuracion del uC

int i=1; //definimos una variable a utilizar

void main (void){

ADCON1=0x0F; //Definimos que las entradas y salidas serán digitalesTRISD=0x00; //Definimos todo el puerto D del PIC como salida (digital)LATD=0; //Establecemos que el valor inicial del puerto D sea 0.while (1){while(i<255) //Establecemos como condicion de funcionamiento que el unico bit en 1L

//este como maximo en la posicion 8 del puerto{LATD=i; //El puerto D asume el valor de la variable iDelay10KTCYx(250); //Introducimos un retardo de 10*10e3 usegundosi=i<<1; //Desplazamos el único bit en 1L de la variable hacia la izquierda.}i=1; //Superado el valor de 255, establecemos el valor de la variable en 1 nuevamente}

}

Page 8: Ejemplos Simples c18

8

- 8

1. Como primer paso en la programación se incluye las librerías del microcontrolador al igual que la librería que define los parámetros de trabajo del microcontrolador, para este ejercicio en particular se debe utilizar retrasos o delays por lo que incluiremos también estas librerías.

2. Como segundo paso definiremos la variable i que almacenara los valores mostrados en la tabla al inicio del ejercicio. El objetivo de almacenar estos valores en una variable es mostrarlos en el Puerto D y la condición en común que poseen es que todos ellos tienen uno de sus 8 bit con valor de 1L y los demás con valor de 0L, los cuales ordenados secuencialmente darán el efecto de un desplazamiento secuencial del LED encendido. A continuación algunas consideraciones para esta variable:

a. Estamos definiendo la variable ‘i’ como una variable tipo int con lo cual estamos asignando un espacio de 16 bits para esta variable, esto quiere decir que con ella podemos abarcar desde 0 hasta 65535, en nuestro caso al copiarlo en el Puerto D solo recogerá los 8 bits menos significativos.

b. Además debemos generar una protección para limitar el valor de i, esto lo explicaremos más adelante.

3. Entramos al programa principal o main, lo primero que debemos hacer aquí es establecer la configurar todos los pines de trabajo, para este ejemplo al igual que el anterior utilizaremos los comandos ADCON1, TRIS, LAT.

4. Ingresamos al bucle infinito, dentro de él nos encontramos con dos alternativas referidas a la variable i, esto es parte de la protección que mencionamos antes , tenemos:

a. Cuando el valor de i es menor que 255, haciendo uso del comando LAT copiamos el valor de i en el Puerto D, a continuación introducimos un retraso de 10ms, luego haciendo uso del operacional ‘<< ‘desplazamos el único bit de la variable i que se encuentra en 1L y se reescribe sobre la variable i, dando el efecto de desplazamiento en la barra de LED, todo esto se repite mientras se cumpla la condición. Aquí un diagrama de lo que pasa:

Page 9: Ejemplos Simples c18

9

- 9

b. Cuando el valor de i no cumple la condición escrita, en este momento sale del bucle comentado en el apartado a y pasa a la siguiente instrucción que es: hacer la variable i igual a 1, como es evidente esto hará que en la siguiente iteración se cumpla la primera condición y el programa volverá a realizar la secuencia antes graficada.

NOTA: es importante entender el porqué de esta protección. Recordemos que la variable i es una variable tipo int, por lo tanto maneja 16 bits, entonces una vez que el valor de 1L de la variable se encuentre en el bit RD7, al desplazarse un bit más a la izquierda la variable i asumirá el valor que le corresponde, pero en nuestra representación observaríamos toda la barra de LED apagada, pues los 8 bits que estamos representando están en 0L.

Page 10: Ejemplos Simples c18

10

- 10

LED secuenciales empleando timers

Conceptos Básicos:

Interrupciones: ‘una interrupción es un evento que requiere que el CPU detenga su programa normal en ejecución y desarrolle algún servicio relacionado con el evento’1. Una interrupción puede ser generada externamente, por ejemplo cuando bit capacitado para generar una interrupción cambia de estado lógico, o internamente, por ejemplo por desbordamiento de un timer. Aquí una analogía del funcionamiento de una interrupción:

o Como actuarias cuando estas sentado en tu escritorio leyendo un libro y el teléfono empieza a sonar. Probablemente actuarias así:

Recordarías la página que estabas leyendo o ubicarías alguna referencia, luego cerrarías el libro y lo colocarías aparte.

Contestarías el teléfono y dirías “Hola, … ”. Esperarías a reconocer la voz del que está hablando y si es

familiar responderías de inmediato. Hablarías con esta persona. Colgarías el teléfono cuando terminas de hablar con esta

persona. Abrirías el libro y regresarías a la página que estabas

leyendo.

De manera similar funcionan las interrupciones dentro de un microcontrolador, termina la instrucción que está realizando, guarda la dirección de la siguiente instrucción, realiza la rutina de interrupción y una vez terminada regresa a la dirección guardada.

1 Fuente: pic microcontroller - an introduction to software and hardware interfacing Cap. 6 Pag. 244

Page 11: Ejemplos Simples c18

11

- 11

Descripción del Circuito:

Elementos:o PIC 18f4550: Microcontroladoro RES16DIPIS: Barra de 9 resistenciaso LED-BARGRAPH: Barra de 10 LED de color verde o RES: Resistencia de 1K

Explicación:o Se alimenta al microcontrolador mediante la fuente de poder

(POWER) conectada al pin 1, por defecto este entrega 5V, los necesarios para la alimentación del microcontrolador.

o El ejercicio consiste en configurar el puerto D como salida, y copiar el valor de una variable i en este puerto, para que sus valores lógicos enciendan uno a uno los segmentos de la barra de LED de tal forma que se aprecie un desplazamiento secuencial descendente.

o La función de la barra de resistencias es generar una caída de tensión en el voltaje que está llegando a los pines de la barra de LED, para protegerlos.

Page 12: Ejemplos Simples c18

12

- 12

Programación: #include <p18f4550.h>#include <config.h>#include <timers.h>

int i=1; //Definimos una variable tipo int llamada i cuyo valor inicial es 1int second_counter = 900; //Definimos una variable tipo int llamada ‘second_counter’ cuyo valor inicial es 900void Interruption_Timer0();//Definimos una subrutina llamada ‘Interruption_Timer0’

#pragma code Interrupcion = 0X0008 // Creamos una nueva sección de código a partir de la dirección 0x08void VectorInterrupcion(void){

Interruption_Timer0(); // enlazamos al vector interrupción}#pragma code // Cerramos sección.-

#pragma interrupt Interruption_Timer0 //configuramos ‘Interruption_Timer0’ como subrutina por interrupciónvoid Interruption_Timer0(void){

if(INTCONbits.TMR0IF==1) //Nos aseguramos que la interrupción sea por desbordamiento del TIMER0 {INTCONbits.TMR0IF=0; //Regresamos el bit de bandera a 0 WriteTimer0(60); //Empezamos el contador en 60second_counter++; //Aumentamos en 1 el valor de la variable second_counterif(second_counter==965) //Esperamos que la variable second_counter sea igual a 965{

second_counter=0; //Regresamos a 0 la cuenta de la variable second_counterLATD=i; //El puerto D asume el valor de la variable iif(i<255)//Establecemos como condición de funcionamiento que el unico bit en 1L{ //este como máximo en la posición 8 del puertoi=i<<1; //Desplazamos el único bit en 1L de la variable hacia la izquierda.}else{i=1; //Superado el valor de 255, establecemos el valor de la variable en 1 nuevamente}}

}}

void main (void){

ADCON1=0x0F; //Definimos que las entradas y salidas serán digitalesTRISD=0x00; //Definimos todo el puerto D del PIC como salida (digital)LATD=0; //Establecemos que el valor inicial del puerto D sea 0.INTCONbits.GIE=1; //Global Interruption EnableRCONbits.IPEN=0; //no hay prioridad de interrupcionesINTCONbits.T0IE=1; // TIMER0 Interruption EnableINTCONbits.PEIE=1; // PEripherical Interruption Enable

//Configuramos el OpenTimer0OpenTimer0(TIMER_INT_ON&T0_8BIT&T0_SOURCE_INT&T0_EDGE_FALL&T0_PS_1_256);WriteTimer0(60); //Empezamos el contador en 60while (1) // Esperamos el desbordamiento del TIMER0{}

}

Page 13: Ejemplos Simples c18

13

- 13

1. Como primer paso en la programación se incluye las librerías del microcontrolador al igual que la librería que define los parámetros de trabajo del microcontrolador, a diferencia del ejemplo anterior esta vez se utilizara contadores internos o timers por lo que incluiremos también estas librerías.

2. Complementando al ejemplo anterior además de definir la variable i, esta vez también definiremos la variable second_counter tipo int, debido a que el PIC no permite trabajar con retrasos de tiempo muy grandes una alternativa de solución es acumular los tiempos de espera, en este caso acumulados en la variable secon_counter.

3. Definimos la subrutina que se ejecutara una vez que el TIMER0 haya terminado su cuenta. Este se enlaza con el vector interrupción Interruption_timer0 que es declarado como subrutina de interrupción mediante el comando interrupt configurado al inicio de esa sección.

4. Dentro de esta sección, preguntamos si la interrupción ha sido producto del desbordamiento del timer0, esto atendiendo al encendido del bit de bandera

TMR0IF(Timer 0 Interruption Flag).

5. Luego se hace el bit TMR0IF igual a 0 para evitar conflictos, escribimos el contador en 60 y almacenamos estos tiempos de espera en la variable second_counter hasta hacerla igual a 965.

6. Una vez que la variable second_counter ha llegado a ser 965, hacemos esta variable igual 0 y mostramos el valor de la variable i en el Puerto D igual que en el ejemplo anterior. Incluimos la protección ya comentada cuando el valor de i supera el valor de 128 debe regresar a ser 1, para que se encienda el LED en la primera ubicación.

7. La configuración del programa principal o main es similar a la anterior, cabe explicar algunas adiciones:

a. INTCONbits.GIE=1; este comando me permite activar las interrupciones globales, cuando es igual a 1, dentro de estas se encuentran las producidas por desbordamiento de TIMER.

b. RCONbits.IPEN=0; este comando me permite desactivar la prioridad en las interrupciones, cuando es igual a 0, es decir no hay un tipo de interrupción que prevalezca.

c. INTCONbits.T0IE=1; activamos las interrupciones que produce el desbordamiento del TIMER0, haciéndolo igual a 1.

Page 14: Ejemplos Simples c18

14

- 14

d. INTCONbits.PEIE=1; este commando nos permite activar las interrupciones perifericas, al hacerlo igual a 1.

8. Pasamos a la configuración del TIMER0:

a. TIMER_INT_ON: Activa las interrupciones producto del desbordamiento del TIMER0.

b. T0_8BIT: Define el espacio del TIMER0, en este caso es de 8 bits por lo tanto tiene la capacidad de contar de 0 a 255.

c. T0_SOURCE_INT: Indicamos que la fuente de reloj que utilizaremos es el reloj interno del PIC.

d. T0_EDGE_FALL: Configuramos el TIMER para reconocer el desbordamiento en el flanco de bajada del pulso.

e. T0_PS_1_256: configuramos el pre escalar que me ayudara en el cálculo del tiempo requerido.

Page 15: Ejemplos Simples c18

15

- 15

Page 16: Ejemplos Simples c18

16

- 16

Control de un Display

Conceptos Básicos:

Figura 1. Display Ánodo/Cátodo común.

El primer concepto que debe quedar claro antes de empezar a programar un display es la diferencia entre ánodo común y cátodo común, esta diferencia la explicaremos de una forma sencilla a continuación:

o Ánodo común: como se aprecia en la Figura 1, esta configuración nos presenta todos los pines positivos, de los LED que forman los segmentos del display, conectados en un punto común. Esto me indica que debo conectar el pin del display a negativo para lograr que se encienda.

o Cátodo común: como se aprecia en la Figura 1, esta configuración nos presenta todos los pines negativos, de los LED que forman los segmentos del display, conectados en un punto común. Esto me indica que debo conectar el pin del display a positivo para lograr que se encienda.

Page 17: Ejemplos Simples c18

17

- 17

Descripción del Circuito:

Elementos:o PIC 18f4550: Microcontroladoro RES16DIPIS: Barra de 8 resistenciaso 7SEG-MPX1-CC: Display de 7 segmentos con cátodo común

Explicación:

o Se alimenta al microcontrolador mediante la fuente de poder (POWER) conectada al pin 1, por defecto este entrega 5V, los necesarios para la alimentación del microcontrolador.

o El ejercicio consiste en configurar el puerto D como puerto de salida para los valores lógicos que influirán en el encendido de los segmentos del display, al ser un display de 7 segmentos con Cátodo Común necesitamos dar un valor de 1 lógico o 5V al pin correspondiente al segmento del display para encenderlo.

o La función de la barra de resistencias es generar una caída de tensión en el voltaje que está llegando a los pines del display, para protegerlo.

Page 18: Ejemplos Simples c18

18

- 18

Programación:

#include <p18f4550.h>#include <config.h>#include <delays.h>

char number=0; //Definimos una variable tipo char llamada "number" cuyo valor inicial es 0

void main(void){

ADCON1=15; //Configuramos entradas/salidas digitalesTRISD=0x00; //Configuramos el puerto D como salidaTRISA=0x00; //Configuramos el puerto A como salidaLATD=0; //Escribimos 0 en todos los pines del puerto DLATA=0xff; //Activamos los display a partir del Puerto Awhile(1){

if(number==10){ //protección para evitar que la variable ‘number’number=0; //supere el valor de 9}

switch(number){ //seleccionamos el caso dependiendo del valor de ‘number’

case 0:LATD=0b00111111; //mostramos 0 en el displaybreak;

case 1:LATD=0b00000110; //mostramos 1 en el displaybreak;

case 2:LATD=0b01011011; //mostramos 2 en el displaybreak;

case 3:LATD=0b01001111; //mostramos 3 en el displaybreak;

case 4:LATD=0b01100110; //mostramos 4 en el displaybreak;

case 5:LATD=0b01101101; //mostramos 5 en el displaybreak;

case 6:LATD=0b01111101; //mostramos 6 en el displaybreak;

case 7:LATD=0b00000111; //mostramos 7 en el displaybreak;

case 8:LATD=0b01111111; //mostramos 8 en el displaybreak;

case 9:LATD=0b01101111; //mostramos 9 en el displaybreak;

}number++; //incrementamos en uno el valor de la variable ‘number ’ Delay10KTCYx(255); //escribimos un retraso para apreciar el cambio en el display

Page 19: Ejemplos Simples c18

19

- 19

1. La primera parte de toda programación en C consiste en llamar todas las librerías necesarias, para nuestro ejercicio haremos uso de un retraso o delay, entonces llamaremos a esta librería.

2. Como segundo paso para este ejercicio definiremos la variable ‘number’, esta variable almacenara valores del 1 al 9 los mismos que serán mostrados en el display. En este paso debemos tener algunas consideraciones:

a. Estamos definiendo la variable ‘number’ como una variable tipo char con lo cual estamos asignando un espacio de 8 bits para esta variable, esto quiere decir que con ella podemos abarcar desde 0 hasta 255(desde 00000000 hasta 11111111 en binario).

b. Por condición del problema, debemos crear una protección para restringir los valores de esta variable. En el momento en que ‘number’ sea 10 el programa automáticamente deberá asignarle el valor de 0.

3. Entramos al programa principal o main, lo primero que debemos hacer aquí es configurar nuestros puertos de salida, en este caso es el Puerto D que recogerá los 8 bits de la variable ‘number’, y los almacenara en sus pines desde D0 hasta D7, para luego comunicarlos con los pines del display. Para empezar escribiremos cero en el Puerto D.

4. Ingresamos al bucle infinito que nos permitirá repetir el conteo de 0 a 9 innumerables veces.

5. Hacemos uso del condicional if para crear la protección antes mencionada. Con este condicional lo que se pretende es: preguntar para cada iteración ‘¿es ‘number’ igual a 10?’. Si esta condición se cumple reemplazaremos el valor de ‘number’ (igual a 10 en este momento) por 0, caso contrario omitimos esta línea y pasamos a la selección del caso en el que nos encontramos.

6. Como se menciono anteriormente las resistencias nos sirven solo como una protección, por ello no influirán demasiado en nuestra programación.

7. Una vez creada la protección se asegura que solo se podrá tener 10 casos, cada uno se programara mediante el comando switch. Básicamente la configuración de cada caso consiste en escribir en cada pin del Puerto D 1L o 0L de tal forma que enciendan en el display los segmentos necesarios para mostrar el valor que posee ‘number’. Esto se puede apreciar mejor en la siguiente tabla resumen:

Page 20: Ejemplos Simples c18

20

- 20

NúmeroRD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0Dot G f e d c b A

0 0 0 1 1 1 1 1 11 0 0 0 0 0 1 1 02 0 1 0 1 1 0 1 13 0 1 0 0 1 1 1 14 0 1 1 0 0 1 1 05 0 1 1 0 1 1 0 16 0 1 1 1 1 1 0 17 0 0 0 0 0 1 1 18 0 1 1 1 1 1 1 19 0 1 1 0 1 1 1 1

8. Antes de cerrar el bucle infinito incrementamos el valor de la variable ‘number’, este valor incrementado será mostrado en la siguiente iteración. Además escribimos un retraso para poder apreciar los cambios en el display, de no ser así ocurrirían demasiado rápido y observaríamos todos los segmentos encendidos siempre.

Page 21: Ejemplos Simples c18

21

- 21