mplab c18: c básico

43
Rev: 1.0 Omar Gurrola http://www.proprojects.wordpress.com 5/22/2012 MPLAB C18: C Básico

Upload: dragoon-micromar

Post on 26-Mar-2016

317 views

Category:

Documents


10 download

DESCRIPTION

Este tutorial tiene el objetivo de poner en práctica varios aspectos básicos del lenguaje C enfocado a microcontroladores, utilizando el compilador de Microchip llamado C18.

TRANSCRIPT

Page 1: MPLAB C18: C Básico

Rev: 1.0

Omar Gurrola

http://www.proprojects.wordpress.com

5/22/2012

MPLAB C18: C Básico

Page 2: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012]

CONTENIDO

LICENCIA ............................................................................................................................................1

AGRADECIMIENTOS ...........................................................................................................................2

INTRODUCCIÓN .................................................................................................................................2

OBJETIVO DE ESTE TUTORIAL..............................................................................................................2

1. SOFTWARE Y HARDWARE UTILIZADO ..........................................................................................2

2. VARIABLES Y DATOS ...................................................................................................................3

2.1. TIPOS DE VARIABLES Y TAMAÑOS ................................................................................................ 3

2.2. CONSTANTES NUMÉRICAS ............................................................................................................ 4

2.3. CONVERSIÓN DE TIPO (TYPECASTING) ......................................................................................... 5

2.4. ÁMBITO DE VALIDEZ (SCOPE) ....................................................................................................... 5

2.5. REDEFINICIÓN DE VARIABLES (TYPEDEF) ...................................................................................... 6

2.6. ENUMERACIONES ......................................................................................................................... 7

2.7. ESTRUCTURAS ............................................................................................................................... 8

2.8. UNIONES ....................................................................................................................................... 9

2.9. ARREGLOS ................................................................................................................................... 11

2.10. CADENAS DE CARACTERES ...................................................................................................... 12

2.11. PUNTEROS ............................................................................................................................... 13

2.12. TAMAÑO (SIZEOF()) ................................................................................................................ 14

3. MODIFICADORES DE VARIABLES ............................................................................................... 15

3.1. AUTO ........................................................................................................................................... 15

3.2. STATIC ......................................................................................................................................... 15

3.3. EXTERN ........................................................................................................................................ 16

3.4. VOLATILE ..................................................................................................................................... 17

3.5. REGISTER ..................................................................................................................................... 17

3.6. CONST ......................................................................................................................................... 17

3.7. OVERLAY (C18) ............................................................................................................................ 18

3.8. RAM (C18) ................................................................................................................................... 18

3.9. ROM (C18) ................................................................................................................................... 19

4. OPERADORES ........................................................................................................................... 20

4.1. OPERADORES ARITMÉTICOS ....................................................................................................... 20

Page 3: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012]

4.2. OPERADORES DE COMPARACIÓN ............................................................................................... 20

4.3. OPERADORES LÓGICOS ............................................................................................................... 21

4.4. OPERADORES DE BITS ................................................................................................................. 22

4.5. PROCEDENCIA Y ORDEN DE EVALUACIÓN .................................................................................. 23

5. ESTRUCTURAS DE CONTROL ...................................................................................................... 23

5.1. IF-ELSE ......................................................................................................................................... 23

5.2. ELSE-IF ......................................................................................................................................... 24

5.3. SWITCH ........................................................................................................................................ 24

5.4. WHILE .......................................................................................................................................... 24

5.5. DO-WHILE.................................................................................................................................... 25

5.6. FOR .............................................................................................................................................. 25

5.7. CONTINUE ................................................................................................................................... 25

5.8. BREAK .......................................................................................................................................... 26

5.9. GOTO ........................................................................................................................................... 26

6. FUNCIONES .............................................................................................................................. 26

6.1. DECLARACIÓN Y DEFINICIÓN ...................................................................................................... 26

6.2. PARÁMETROS .............................................................................................................................. 27

7. DIRECTIVAS DEL PREPROCESADOR ............................................................................................ 28

7.1. #INCLUDE .................................................................................................................................... 28

7.2. #DEFINE, #IFDEF, #IFNDEF, #UNDEF, #IF, #ELIF, #ELSE, #ENDIF, #ERROR .................................. 28

7.3. #PRAGMA (C18) .......................................................................................................................... 29

7.4. SECCIONES DE MEMORIA (C18) .................................................................................................. 31

7.5. ENSAMBLADOR EN LÍNEA ........................................................................................................... 33

8. LIBRERÍAS ................................................................................................................................. 34

8.1. QUE ES UNA LIBRERÍA Y COMO USARLA ..................................................................................... 34

8.2. COMO CREAR TU LIBRERÍA DE DEMORAS .................................................................................. 35

8.3. COMO CREAR TU LIBRERÍA DE TIPOS DE VARIABLES .................................................................. 37

9. REFERENCIAS ............................................................................................................................ 39

Page 4: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 1

LICENCIA

MPLAB C18: C Básico por Omar Gurrola – http://www.proprojects.wordpress.com se encuentra bajo una Licencia

Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.

Page 5: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 2

AGRADECIMIENTOS

Gracias a mi esposa Tomiko, por ser mí apoyo y darme fortaleza.

También quiero agradecer a Alejandro Casanova “infopic.comlu.com” por su excelente tutorial de MPLAB C18.

A todas las personas que han dedicado tiempo y esfuerzo a realizar tutoriales y/o guías para que personas como yo

aprendan de forma fácil y rápida.

INTRODUCCIÓN

El lenguaje C a pesar de tener mucho tiempo que se inventó (1972), sigue siendo muy utilizado en varios ámbitos,

principalmente en los que se requiere programación de más bajo nivel como es el caso de microcontroladores,

drivers, etc.

Por lo que si te quieres especializar a desarrollar firmware para microcontroladores como yo, es indispensable que

domines este lenguaje.

Algunos microcontroladores ya se pueden programar en C++ lo que facilita mucho estructurar programas más

grandes y complejos, pero por el momento los microcontroladores que estaré utilizando se programan en C.

OBJETIVO DE ESTE TUTORIAL

Este tutorial tiene el objetivo de poner en práctica varios aspectos básicos del lenguaje C enfocado a

microcontroladores, utilizando el compilador de Microchip llamado C18.

1. SOFTWARE Y HARDWARE UTILIZADO

Todas las prácticas fueron desarrolladas y probadas con:

Software:

Windows 7 SP1 x64

Microchip MPLAB IDE v8.84

Microchip C18 3.4

Hardware:

AMD Phenom II 9600B Quad-Core 2.3 GHz

4GB DDR2

Page 6: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 3

2. VARIABLES Y DATOS

2.1. TIPOS DE VARIABLES Y TAMAÑOS

En C existen diferentes tipos de variables que se utilizan para almacenar datos e información durante la ejecución

del programa. Son los siguientes para C18:

Tipo: Tamaño (bits): Mínimo: Máximo:

char 8 -128 127 unsigned char 8 0 255

int 16 -32768 32767 unsigned int 16 0 65535

short 16 -32768 32767 unsigned short 16 0 65535

short long 24 -8388608 8388607 unsigned short long 24 0 16777215

long 32 -2174483648 2147486647 unsigned long 32 0 4294967295

float 32 exp(-126) exp(128) double 32 exp(-126) exp(128)

2.1.1. Ejemplo.

main.c

void main(void) { // Variables locales char c_variable; // 8b -128 -> 127 char c_variable2; unsigned char uc_variable; // 8b 0 -> 255 int i_variable; // 16b -32,768 -> 32,767 int i_variable2; unsigned int ui_variable; // 16b 0 -> 65,535 short s_variable; // 16b -32,768 -> 32,767 short s_variable2; unsigned short us_variable; // 16b 0 -> 65,535 short long sl_variable; // 24b -8,388,608 -> 8,388,607 short long sl_variable2; unsigned short long usl_variable; // 24b 0 -> 16,777,215 long l_variable; // 32b -2,147,483,648 -> 2,147,483,647 long l_variable2; unsigned long ul_variable; // 32b 0 -> 4,294,967,295 float f_variable; // 32b exp(-126) -> exp(128) double d_variable; // 32b exp(-126) -> exp(128) c_variable = -128; c_variable2 = 127; uc_variable = 255; i_variable=-32768; i_variable2=32767; ui_variable=65535; s_variable = -32768; s_variable2 = 32767; us_variable = 65535; sl_variable=-8388608; sl_variable2=8388607;

Page 7: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 4

usl_variable=16777215; l_variable=-2141483648; l_variable2=2141483647; ul_variable=4294967295; f_variable=-5.321; d_variable=6.999; }

2.2. CONSTANTES NUMÉRICAS

Nos ayuda a definir valores en diferentes bases numéricas directamente.

Base: Prefijo: Ejemplo:

Decimal Ninguno 250 Hexadecimal 0x 0xAA

Binario 0b 0b11110000 Octal 0 077

2.2.1. Ejemplo.

main.c

void main(void) { unsigned char a,b,c,d; a = 250; // Decimal b = 0xAA; // Hexadecimal c = 077; // Octal d = 0b11110000; // Binario }

Page 8: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 5

2.3. CONVERSIÓN DE TIPO (TYPECASTING)

Permite que una variable actué como de otro tipo, pero la variable original nunca es modificada. Este tipo de

conversión nos ayuda a realizar operaciones y que el resultado no se vea afectado por el tipo de variable en ciertos

casos. Se utiliza poniendo el tipo al que queremos convertirlo entre paréntesis antes de la variable a convertir.

2.3.1. Ejemplo.

main.c

void main(void) { unsigned char uc_a,uc_b,uc_c; unsigned int ui_x,ui_y; uc_a = 100; uc_b = 200; uc_c = uc_a + uc_b; // ERROR: El resultado no estará correcto por que el resultado requiere mas de 8 bits ui_x = uc_a + uc_b; // ERROR: El resultado tampoco estará correcto por que la operación se realizó con 8 bits ui_y = (unsigned int)uc_a + (unsigned int)uc_b; // OK y = 300 }

2.4. ÁMBITO DE VALIDEZ (SCOPE)

El ámbito de validez de un identificador (función, variable, etc.) es la parte del código donde el identificador puede

ser utilizado.

Existen cuatro ámbitos:

Ámbito de aplicación (Global)

Este ámbito permite que el identificador sea visto por todo el programa.

Ámbito de archivo

Este ámbito solo se limita para archivos adicionales a main.c, como archivo1.c, etc.

Ámbito de función (Local)

Los identificadores solo son reconocidos dentro de la función donde se definieron.

Ámbito de bloque (En C18 no funcionan)

Los identificadores solo son reconocidos dentro del bloque, ejemplo bloque for, while, etc.

2.4.1. Ejemplo.

main.c

// Ámbito de aplicación unsigned char uc_global = 25; void funcion(unsigned char); void main(void) { // Ámbito de función (Local) unsigned char uc_localmain = 50; unsigned char r;

Page 9: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 6

r = uc_global; // Accedemos a la variable global r = uc_localmain; // Accedemos a la variable local de main funcion(r); } void funcion(unsigned char uc_localparam){ // Ámbito de funcion (Local) unsigned char uc_localfuncion = 100; unsigned char s; s = uc_localfuncion; // Accedemos a la variable local de función s = uc_localparam; // Accedemos al parámetro local de función s = uc_global; // Accedemos a la variable global }

archivo1.c

// Ámbito de archivo unsigned char x=23; unsigned char getx(){ return x; }

2.5. REDEFINICIÓN DE VARIABLES (TYPEDEF)

Se utiliza para redefinir tipos de variables y otros tipos de datos que se verán más delante. Ayudan a que los

nombres sean más significativos y cortos.

typedef unsigned char BYTE; typedef unsigned int UINT;

2.5.1. Ejemplo.

main.c

// 8b signed [-128 -> 127] typedef char INT8, s8; // 8b unsigned [0 -> 255] typedef unsigned char UCHAR, UINT8, u8, BYTE; // 16b signed [-32,768 -> 32,767] typedef int INT16, s16; // 16b unsigned [0 -> 65,535] typedef unsigned int UINT, UINT16, u16, WORD; // 24b signed [-8,388,608 -> 8,388,607] typedef short long INT24, s24; // 24b unsigned [0 -> 16,777,215] typedef unsigned short long UINT24, u24; // 32b signed [-2,147,483,648 -> 2,147,483,647] typedef long INT32, s32; // 32b unsigned [0 -> 4,294,967,295] typedef unsigned long ULONG, UINT32, u32, DWORD; // 32b decimal point [exp(-126) -> exp(128)] typedef float FLOAT; typedef double DOUBLE; void main(void) { INT8 var1 = -128; INT16 var2 = -32768; INT24 var3 = -8388608; INT32 var4 = -2147483648; UINT8 var5 = 255; UINT16 var6 = 65535; UINT24 var7 = 16777215; UINT32 var8 = 4294967295;

Page 10: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 7

BYTE var9 = 255; WORD var10 = 65535; DWORD var11 = 4294967295; FLOAT var12 = 5.7; DOUBLE var13 = 8.99; }

2.6. ENUMERACIONES

Permite realizar una lista de constantes con nombres que pueden ser fácilmente utilizados en el programa.

enum {cero,uno,dos,tres}; enum nombres {omar=5,carlos,juan}; typedef enum nombres {omar=5,carlos=7,juan} NOM;

2.6.1. Ejemplo.

main.c

enum {cero,uno,dos,tres}; // 0,1,2,3 typedef enum nombres {omar=5,carlos=7,juan} NOM; // 5,6,7 void main(void) { unsigned char n0,n1,n2; enum nombres minombre; // Creamos una variable para alojar nombre NOM minombre2, minombre3; // Creamos otra variable para alojar nombre usando la redefinición n0 = cero; // n0 = 0 n1 = uno; // n1 = 1 n2 = dos; // n2 = 2 minombre = omar; // minombre = 5 minombre2 = carlos; // minombre2 = 7 minombre3 = juan; // minombre3 = 8 }

Page 11: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 8

2.7. ESTRUCTURAS

Es una colección de variables que pueden contener diferentes tipos de datos que ayudan a organizar y manejar los

datos de forma agrupada y fácil.

Comúnmente diferentes variables sin agrupar se definían así:

unsigned char Hora, Minutos, Segundos, Actualizar, Alarma1, Alarma2, Alarma3;

Con una estructura se definen así:

Struct Reloj{ unsigned char Hora; unsigned char Minuto; unsigned char Segundos; unsigned Actualizar:1; unsigned Alarma1:1; unsigned Alarma2:1; unsigned Alarma3:1;

} Reloj1; Se utiliza de la siguiente manera:

Reloj1.Minutos=15; if(Reloj1.Actualizar==1){ }

2.7.1. Ejemplo.

main.c

struct Reloj{ unsigned char Hora; unsigned char Minuto; unsigned char Segundos; unsigned Actualizar : 1; unsigned Alarma1 : 1; unsigned Alarma2 : 1; unsigned Alarma3 : 1; }; typedef struct Calendario{ unsigned int Anio; unsigned char Mes; unsigned char Dia; } CAL; void main(void) { struct Reloj RelojTest; struct Calendario Calendario1; CAL Calendario2; RelojTest.Hora = 10; RelojTest.Minuto = 40; RelojTest.Segundos = 0; RelojTest.Actualizar = 1; Calendario1.Anio = 2011; Calendario1.Mes = 5; Calendario1.Dia = 9; Calendario2.Anio = 2012; Calendario2.Mes = 5; Calendario2.Dia = 9; }

Page 12: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 9

2.8. UNIONES

Son similares a las estructuras, la única diferencia es que los campos se sobreponen y se utilizan para llamar de

distintas formas a la misma área de memoria.

En este ejemplo se reservan 16 bits para un unsigned int que también puede ser accedido por dos unsigned char:

union{ unsigned int Valor; struct{

unsigned LSB:8; unsigned MSB:8;

}; } Variable;

Y se utiliza de la siguiente manera:

Variable.Valor = 0xAB; Variable.LSB = 0xD; Variable.MSB = 0xC;

2.8.1. Ejemplo.

main.c

typedef union UUINT16{ unsigned int Valor; struct{ unsigned LB:8; unsigned HB:8; }; struct{ unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; unsigned b5:1; unsigned b6:1; unsigned b7:1; unsigned b8:1; unsigned b9:1; unsigned b10:1; unsigned b11:1; unsigned b12:1; unsigned b13:1;

Page 13: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 10

unsigned b14:1; unsigned b15:1; }; } UINT16_VAL; void main(void) { union UUINT16 Variable1; UINT16_VAL Variable2; Variable1.HB = 0xAB; Variable1.LB = 0xCD; Variable2.Valor = 0; Variable2.b0 = 1; Variable2.b1 = 1; Variable2.b2 = 1; Variable2.b3 = 1; }

Page 14: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 11

2.9. ARREGLOS

Permiten trabajar con un conjunto de variables del mismo tipo y acceder a cada elemento utilizando un índice que

va de 0 hasta N-1, donde N es el número de elementos del arreglo.

Para declarar un arreglo se hace de la siguiente forma:

unsigned char Arreglo[N]; unsigned char Arreglo2[N][M]; unsigned char Arreglo3[]={1,2,3,4,5} unsigned char Arreglo4[2][3]={1,2,3,4,5,6};

2.9.1. Ejemplo.

main.c

void main(void) { unsigned char Variable; // Arreglo sin inicializar unsigned char Numeros[3]; unsigned char Numeros2[2][2]; // Arreglo inicializados unsigned char Numeros3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; unsigned char Numeros4[2][2] = {0, 1, 2, 3}; Numeros[0] = 0; Numeros[1] = 1; Numeros[2] = 2; Numeros2[0][0] = 0; Numeros2[0][1] = 1; Numeros2[1][0] = 2; Numeros2[1][1] = 3; Variable = Numeros3[0]; // Variable = 0 Variable = Numeros3[5]; // Variable = 5 Variable = Numeros3[9]; // Variable = 9 Variable = Numeros4[0][0]; // Variable = 0 Variable = Numeros4[0][1]; // Variable = 1 Variable = Numeros4[1][0]; // Variable = 2 Variable = Numeros4[1][1]; // Variable = 3 }

Page 15: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 12

2.10. CADENAS DE CARACTERES

Es un arreglo de caracteres, donde el último carácter es nulo para definir el fin de la cadena.

2.10.1. Ejemplo.

main.c

void main(void) { char caracter1 = 'H'; // Carácter H char caracter2 = 0x48; // Carácter H en hexadecimal char mensaje1[] = "Hola mundo!"; // Cadena de caracteres char mensaje2[] = "\"Hola\""; // Cadena de caracteres con comillas }

Page 16: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 13

2.11. PUNTEROS

Un puntero es una variable de 16 bits o 24 bits (Puntero a FAR ROM) que contiene una dirección de memoria.

Para declarar un puntero se realiza de la siguiente manera:

unsigned char *ptr;

Para asignar la dirección se realiza de la siguiente manera:

ptr = &variable; ptr = &Arreglo[0];

Para cambiar o leer el valor de la dirección a la que apunta es de la siguiente manera:

*ptr = 0x78; var2 = *ptr;

2.11.1. Ejemplo.

main.c

void main(void) { unsigned char aVarRAM[3] = {0xAA,0xBB,0xCC}; unsigned char VarRAM = 20; static near rom unsigned char ConROMNear = 30; static far rom unsigned char ConROMFar = 40; unsigned char *pVarRAM; // Puntero a ram de 16b near rom unsigned char *pConROMNear; // Puntero a rom de 16b far rom unsigned char *pConROMFar; // Puntero a rom de 24b unsigned char a,b,c,d,e,f; pVarRAM = &VarRAM; // pVarRAM apunta a VarRAM; pConROMNear = &ConROMNear; // pConROMNear apunta a pConROMNear pConROMFar = &ConROMFar; // pConROMFar apunta a pConROMFar a = *pVarRAM; // 20 b = *pConROMNear; // 30 c = *pConROMFar; // 40 pVarRAM = &aVarRAM[0]; // pVarRAM apunta a aVarRAM[0] d = *pVarRAM; // 0xAA e = *(pVarRAM+1); // 0xBB f = *(pVarRAM+2); // 0xCC }

Page 17: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 14

2.12. TAMAÑO (SIZEOF())

Nos da el tamaño de una variable (normal, arreglo, puntero, estructura, unión o tipo) en bytes.

2.12.1. Ejemplo.

main.c

void main(void) { unsigned char r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19; unsigned char *pVarRAM; // Puntero a ram de 16b static near rom unsigned char *pConROMNear; // Puntero a rom de 16b static far rom unsigned char *pConROMFar; // Puntero a rom de 24b unsigned int Arreglo[2][2] = {1,2,3,4}; // Arreglo 2x2 char ArregloCaracteres[] = "Hola mundo!"; // Arreglo de caracteres struct { // Estructura unsigned int Anio; unsigned char Mes; unsigned char Dia; } Estructura1; union{ // Union unsigned int Valor; struct{ unsigned LSB:8; unsigned MSB:8; }; } Union1; r1 = sizeof(char); // 1 (8b) r2 = sizeof(unsigned char); // 1 (8b) r3 = sizeof(int); // 2 (16b) r4 = sizeof(unsigned int); // 2 (16b) r5 = sizeof(short); // 2 (16b) r6 = sizeof(unsigned short); // 2 (16b) r7 = sizeof(short long); // 3 (24b) r8 = sizeof(unsigned short long); // 3 (24b) r9 = sizeof(long); // 4 (32b) r10 = sizeof(unsigned long); // 4 (32b) r11 = sizeof(float); // 4 (32b) r12 = sizeof(double); // 4 (32b) r13 = sizeof(pVarRAM); // 2 (16b) r14 = sizeof(pConROMNear); // 2 (16b) r15 = sizeof(pConROMFar); // 3 (24b) r16 = sizeof(Arreglo); // 8 (64b) r17 = sizeof(ArregloCaracteres); // 12 (96b) r18 = sizeof(Estructura1); // 4 (32b) r19 = sizeof(Union1); // 2 (16b) }

Page 18: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 15

3. MODIFICADORES DE VARIABLES

3.1. AUTO

Es el modificador por default de una variable y no es necesario ponerlo explícitamente.

3.1.1. Ejemplo.s

main.c

void main(void) { unsigned char Variable; // Variable auto auto unsigned char Variable2; // Variable auto explícitamente (no es necesario poner auto) Variable = 100; Variable2 = 200; }

3.2. STATIC

Se define dentro de una función y no son destruidas al terminar, manteniendo su valor en cada llamada a la

función. Si diferentes funciones tiene la misma variable static cada una tiene una copia con su propio valor.

3.2.1. Ejemplo.

main.c

unsigned char funcion1(unsigned char, unsigned char); unsigned char funcion2(unsigned char, unsigned char); void main(void) { unsigned char a,b,c,d,e,f,g,h; a = funcion1(0,1); // static x = 0, a = 0 b = funcion1(20,0); // b = x + 20 = 20 c = funcion1(30,0); // c = x + 30 = 50 d = funcion2(0,1); // static x = 0, d = 0

Page 19: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 16

e = funcion2(40,0); // e = x + 20 = 40 f = funcion2(40,0); // f = x + 30 = 80 g = funcion1(0,0); // g = 50 h = funcion2(0,0); // h = 80 } unsigned char funcion1(unsigned char w, unsigned char s){ static unsigned char x; if(s) x = 0; x = x + w; return x; } unsigned char funcion2(unsigned char w, unsigned char s){ static unsigned char x; if(s) x = 0; x = x + w; return x; }

3.3. EXTERN

Se utiliza cuando la variable o función se encuentra definida en otro modulo y no se requiere reservar memoria

nuevamente.

3.3.1. Ejemplo.

main.c

extern unsigned char Suma(unsigned char, unsigned char); // función declarada suma.c void main(void) { extern unsigned char Variable; // Declarada en suma.c unsigned char r, r2; r = Suma(50,30); r2 = Variable; }

suma.c

unsigned char Variable = 100; unsigned char Suma(unsigned char a, unsigned char b){ return (a + b); }

Page 20: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 17

3.4. VOLATILE

El contenido de la variable puede cambiar sin previo aviso, se utiliza para puertos I/O, memoria mapeada,

variables modificadas en interrupciones, etc.

Básicamente le dice al optimizador que no modifique el código donde se utilicen este tipo de variables. Si no se

utiliza volatile donde se requiere puede que el programa no funcione bien cuando se utilice el optimizador o

interrupciones.

3.4.1. Ejemplo.

main.c

void main(void) { volatile unsigned char vol = 0; // Si se utiliza el optimizador y vol no se declarada como volatile // esta línea podría ser cambiada por while (TRUE) y nunca terminaría while (vol != 255) { ; // continue; } }

3.5. REGISTER

Son variables que se guardan en el registro del CPU, son mucho más rápidas que las variables de memoria pero son

muy limitadas.

3.5.1. Ejemplo.

main.c

void main(void) { register unsigned char reg = 0; reg = reg + 10; }

3.6. CONST

El contenido es constante y no se puede modificar.

3.6.1. Ejemplo.

main.c

void main(void) { unsigned char r; const unsigned char const_var = 20; r = const_var; //const_var = 20; // No se puede cambiar el valor por ser const }

Page 21: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 18

3.7. OVERLAY (C18)

Solo se puede utilizar para variables tipo local (no globales ni parámetros). Las variables de este tipo ocupan el

mismo lugar de memoria con lo que se puede reducir el uso de la misma y también se reducen la cantidad de

instrucciones necesarias para accederlas.

Se utilizan para variables en funciones que no pueden activarse al mismo tiempo.

3.7.1. Ejemplo.

main.c

void Inicializa(unsigned char ); unsigned char Suma(unsigned char); void main(void) { unsigned char r, r2; Inicializa(0); // var = 0 r = Suma(5); // var = 5 Inicializa(10); // var = 10 r2 = Suma(90); // var = 100 } void Inicializa(unsigned char i) { overlay unsigned char var; // variable overlay var = i; } unsigned char Suma(unsigned char a) { overlay unsigned char var; // variable overlay var = var + a; return var; }

3.8. RAM (C18)

Variables de este tipo residen en la memoria de datos, pueden ser near o far.

Near (16b, <= 64KB): Se alojan en las primeras posiciones de memoria, generando menos código y

accediendo más rápido.

Far (24b, <= 2MB): Pueden alojarse en cualquier posición de memoria dentro de los 2MB.

3.8.1. Ejemplo.

main.c

void main(void) { near ram unsigned char varnear; // variable near ram <= 64KB far ram unsigned char varfar; // variable far ram <= 2MB varnear = 0x55; varfar = 0x77; }

Page 22: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 19

3.9. ROM (C18)

Constantes de este tipo residen en la memoria de programa y se utilizan normalmente para almacenar cadenas de

caracteres. Pueden ser near y far también.

3.9.1. Ejemplo.

main.c

void main(void) { static near rom const unsigned char nrc_var = 0xAA; static far rom const unsigned char frc_var = 0xBB; static rom const unsigned char rc_var = 0xCC; unsigned char a,b,c; a = nrc_var; b = frc_var; c = rc_var; }

Page 23: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 20

4. OPERADORES

4.1. OPERADORES ARITMÉTICOS

Sirven para realizar cálculos matemáticos básicos.

Operador: Función:

+ Suma - Resta * Multiplicación / División

++ Incremento -- Decremento

4.1.1. Ejemplo.

main.c

void main(void) { unsigned char a, b, c; unsigned int d, e, f; a = 10; b = 2; c = a + b; // c=12 c = a - b; // c=8 c = a*b; // c=20 c = a / b; // c=5 c = ++a; // c=11,a=11 c = a++; // c=11,a=12 c = --a; // c=11,a=11 c = a--; // c=11,a=10 // Con enteros e = 200; f = 100; d = e + f; // d=300 d = e - f; // d=100 d = e*f; // d=20,000 d = e / f; // d=2 d = ++e; // d=201,e=201 d = e++; // d=201,e=202 d = --e; // d=201,e=201 d = e--; // d=201,e=200 }

4.2. OPERADORES DE COMPARACIÓN

Son utilizados para comparar dos condiciones de una expresión, siendo el resultado verdadero (true 1) o falso

(false 0).

Operador: Función:

== Igual != Diferente < Menor que > Mayor que

<= Menor igual que >= Mayor igual que

Page 24: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 21

4.2.1. Ejemplo.

main.c

void main(void) { unsigned char r; // == Igual r = 1 == 0; // false 0 r = 1 == 1; // true 1 // != Diferente r = 2 != 3; // true 1 r = 2 != 2; // false 0 // < Menor que r = 3 < 5; // true 1 r = 5 < 3; // false 0 // < Mayor que r = 3 > 5; // false 0 r = 5 > 3; // true 1 // < Menor que r = 3 < 5; // true 1 r = 5 < 3; // false 0 // <= Menor igual que r = 5 <= 3; // false 0 r = 3 <= 5; // true 1 r = 5 <= 5; // true 1 // >= Mayor igual que r = 3 >= 5; // false 0 r = 5 >= 3; // true 1 r = 5 >= 5; // true 1 }

4.3. OPERADORES LÓGICOS

Son utilizados para realizar operaciones lógicas, siendo el resultado verdadero (true 1) o falso (false 0).

Operador: Función:

&& AND || OR ! NOT

4.3.1. Ejemplo.

main.c

void main(void) { unsigned char r; // && AND r = (5<3) && (3>1); // False 0 r = (5>3) && (3>1); // True 1 // || OR r = (5<3) || (3<1); // False 0 r = (5>3) || (3>1); // True 1 // ! NOT r = !(5<3); // False 0 r = !(5>3); // True 1 }

Page 25: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 22

4.4. OPERADORES DE BITS

Son utilizados para realizar operaciones lógicas con los bits de las variables. Comúnmente se utilizan para realizar

mascaras poniendo a uno o cero ciertos bits.

Operador: Función:

& And | Or ^ Xor ~ Not

<< Rotar izquierda >> Rotar derecha

4.4.1. Ejemplo.

main.c

void main(void) { unsigned char r; // & And (C=1 cuando A y B son uno) r = 0xA0 & 0x0B; // r=0x00 r = 0xCA & 0x0F; // r=0x0A // | Or (C=1 cuando A o B son uno) r = 0x0C | 0xC0; // r=0xCC r = 0xAB | 0x0F; // r=0xAF // ^ Xor (C=1 cuando A y B son diferentes) r = 0x0F ^ 0x00; // r=0x0F r = 0xAA ^ 0x55; // r=0xFF // ~ Complemento (C=1 cuando A=0 y viceversa) r = ~0x0F; // r=0xF0 r = ~0xAA; // r=0x55 // << Corrimiento izquierda r = 0x01 << 1; // r=0x02 r = 0x01 << 7; // r=0x80 r = 0x0F << 4; // r=0xF0 // >> Corrimiento derecha r = 0x08 >> 1; // r=0x04 r = 0x80 >> 7; // r=0x01 r = 0xF0 >> 4; // r=0x0F // Mascaras con And (Pone a ceros los bits específicos) r = 0xCD & 0x0F; // r=0x0D r = 0xCD & 0xF0; // r=0xC0 // Mascaras con Or (Pone a unos los bits específicos) r = 0xCD | 0x0F; // r=0xCF r = 0xCD | 0xF0; // r=0xFD // Mascaras con Xor (Invierte los bits específicos) r = 0xAA ^ 0x0F; // r=0xA5 r = 0xAA ^ 0xF0; // r=0x5A }

Page 26: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 23

4.5. PROCEDENCIA Y ORDEN DE EVALUACIÓN

Todas las operaciones se realizan de arriba hacia abajo en el siguiente orden:

Operador: Orden:

() [] -> . Izquierda a derecha ! ~ ++ -- + - * (type) sizeof Derecha a izquierda * / % Izquierda a derecha + - Izquierda a derecha << >> Izquierda a derecha < <= > >= Izquierda a derecha == != Izquierda a derecha & Izquierda a derecha ^ Izquierda a derecha | Izquierda a derecha && Izquierda a derecha || Izquierda a derecha ?: Derecha a izquierda = += -= *= /= %= &= ^= |= <<= >>= Derecha a izquierda , Izquierda a derecha

5. ESTRUCTURAS DE CONTROL

5.1. IF-ELSE

Se utiliza para ejecutar cierto código si la condición es verdadera o falsa según sea el caso.

5.1.1. Ejemplo.

main.c

void main(void) { unsigned char a, b, c; a = 5; b = 3; // if if (a > b) { // 5 > 3 = Verdadero c = 1; } // if-else if (a < b) { // 5 < 3 = FALSO c = 1; } else { // Se ejecuta el else c = 2; } }

Page 27: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 24

5.2. ELSE-IF

Se utiliza para evaluar una condición adicional si la primera resulto verdadero o falso según sea el caso.

5.2.1. Ejemplo.

main.c

void main(void) { unsigned char a,b,c; a = 5; b = 3; // if-else if (a < b) { // 5 < 3 = FALSO c = 1; } else if(a == b) { // Se ejecuta el else y se evalua el nuevo if c = 2; } else { c = 3; // Se ejecuta el else } }

5.3. SWITCH

Este tipo de estructuras permiten ejecutar un bloque de código dependiendo el valor de la variable.

5.3.1. Ejemplo.

main.c

void main(void) { unsigned char a,c; // switch a = 5; switch(a){ // Ejecuta el bloque correspondiente al case case 1: c = 1; break; case 2: c = 2; break; case 5: c = 5; break; default: c = 255; break; } }

5.4. WHILE

Ejecuta un grupo de instrucciones mientras la condición sea verdadera. Si la condición es falsa desde el principio el

bloque no se ejecuta.

5.4.1. Ejemplo.

main.c

void main(void) { unsigned char a; // while a = 0;

Page 28: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 25

while (a < 10) { // Se ejecutara mientras se cumpla la condición, puede no ejecutarse ni una vez a++; // a=1,2,3,4,5,6,7,8,9,10 } }

5.5. DO-WHILE

Esta estructura es similar a la anterior, con la diferencia de que se ejecutara al menos una vez el código aunque la

condición sea falsa.

5.5.1. Ejemplo.

main.c

void main(void) { unsigned char a; // do-while a = 0; do { a++; // a=1,2,3,4,5,6,7,8,9,10 } while (a < 10); // Se ejecutara mientras se cumpla la condición, se ejecuta por lo menos una vez }

5.6. FOR

Se utiliza para un número definido de ciclos, se le da el valor inicial, la condición y el incremento.

5.6.1. Ejemplo.

main.c

void main(void) { unsigned char a,c; // for for (a = 0; a < 10; a++) { // Se ejecutara diez veces c = 1; } }

5.7. CONTINUE

Sirve para pasar el control al final de la estructura y evitar que se ejecute el código siguiente, haciendo que se

revalúe la condición.

5.7.1. Ejemplo.

main.c

void main(void) { unsigned char a,b; b = 0; for(a = 0 ; a < 10 ; a++){ if(a == 5 || a == 8) continue; // Se brinca el resto del código si a = 5 o 8 b++; } }

Page 29: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 26

5.8. BREAK

Sirve para pasar el control fuera de la estructura, literalmente es para salirse de la estructura.

5.8.1. Ejemplo.

main.c

void main(void) { unsigned char a,b; b = 0; for(a = 0 ; a < 10 ; a++){ if(a == 5) break; // Se sale del for si a = 5 b++; // b = 5 } }

5.9. GOTO

Se utiliza para transferir el control a una etiqueta especificada.

5.9.1. Ejemplo.

main.c

void main(void) { unsigned char a,b; b = 0; for(a = 0 ; a < 10 ; a++){ if(a == 5) goto SAL; // Brinca a SAL si a = 5 b++; // b = 5 } SAL: b = 0; }

6. FUNCIONES

6.1. DECLARACIÓN Y DEFINICIÓN

Las funciones son subprogramas encargas de realizar ciertas tareas.

Antes de definir una función se debe declarar para que el compilador la conozca y se pueda utilizar. Esto puede

estar definido antes de main() o en otro archivo, a esto también se le conoce como prototipo.

La definición de una función se define normalmente al final del programa.

6.1.1. Ejemplo.

main.c

// Declaración de funciones (Prototipos de funciones) void Mostrar(void); unsigned int Suma(unsigned char, unsigned char); int Resta(unsigned char, unsigned char);

Page 30: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 27

unsigned int Multiplicacion(unsigned char a, unsigned char b) { unsigned int r = (unsigned int) a * (unsigned int) b; return r; } void main(void) { unsigned int a,b; int c; Mostrar(); // Llamamos a Mostrar a = Suma(100,200); // 300 b = Resta(210,110); // 100 c = Resta(150,250); // -100 } // Definición de la función Mostrar void Mostrar(void) { ; // Muestra algo... } // Definición de la función Suma unsigned int Suma(unsigned char a, unsigned char b) { unsigned int r = (unsigned int) a + (unsigned int) b; return r; } // Definición de la función Resta int Resta(unsigned char a, unsigned char b) { int r = (int) a - (int) b; return r; }

6.2. PARÁMETROS

Las funciones reciben y regresan variables que pueden ser de cualquier tipo: básicos, estructuras, uniones,

enumeraciones, punteros y arreglos. Cuando no reciben o regresan valor se pone “void”.

Las funciones pueden regresar un solo valor si así se requiere, pero se puede recibir más de uno regresando un

puntero o un arreglo.

6.2.1. Ejemplo.

main.c

// Declaración de funciones (Prototipos de funciones) void Mostrar(void); // No recibe parámetros ni regresa valor. unsigned int Suma(unsigned char, unsigned char); // Recibe dos parámetros unsigned char y regresa un unsigned int void Swap(unsigned char *, unsigned char *); // Recibe dos punteros para modificarlos void Reemplazar(char *, char, char); // Recibe un puntero y dos unsigned char void main(void) { unsigned int a,b; char Mensaje[] = "Hola!!!!"; Mostrar(); // Llamamos a Mostrar a = Suma(100,200); // 300 a = 100; b = 200; Swap(&a,&b); // Intercambiamos a y b dando sus direcciones Reemplazar(&Mensaje[0],'!','?'); // Remplaza !!!! por ???? } // Definición de la función Mostrar void Mostrar(void) { ; // Muestra algo... }

Page 31: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 28

// Definición de la función Suma unsigned int Suma(unsigned char a, unsigned char b) { unsigned int r = (unsigned int) a + (unsigned int) b; return r; } void Swap(unsigned char *a, unsigned char *b){ unsigned char t; t = *a; *a= *b; *b = t; } void Reemplazar(char * Texto, char Token, char Remplazo){ while(*Texto != '\0'){ if(*Texto == Token) *Texto = Remplazo; Texto++; } }

7. DIRECTIVAS DEL PREPROCESADOR

7.1. #INCLUDE

Se utiliza para añadir archivos de cabeceras.

#include <cabecera.h> La cabecera se encuentra en el directorio de librerías.

#include “cabecera2.h” La cabecera se encuentra en la misma carpeta que el proyecto.

7.1.1. Ejemplo.

main.c

#include<p18f14k50.h> void main(void) { PORTA = 0x00; // Declarada en la cabecera. }

7.2. #DEFINE, #IFDEF, #IFNDEF, #UNDEF, #IF, #ELIF, #ELSE, #ENDIF, #ERROR

Son utilizadas para realizar compilaciones condicionadas, permitiendo compilar cierto código para varias

arquitecturas, compiladores, etc.

7.2.1. Ejemplo.

main.c

#define MAX 100 // Definimos MAX = 100 #define P18F14K50 // Definimos P18F14K50 #ifdef P18F14K50 #include <p18f14k50.h> // Si se definió P18F14K50 incluimos esta cabecera #elif P18C #include <p18cxxx.h> // En otro caso si se definió P18C incluimos esta cabecera #endif // Cerramos el if void main(void) { unsigned char a,b,c; a = 100;

Page 32: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 29

b = 2; #ifndef RESTA c = a + b; // Si no esta definido RESTA, sumamos #else c = a - b; // En otro caso restamos #endif // Cerramos el if #if MAX == 200 // FALSO c = a * b; // Si MAX == 200 -> multiplicamos #else #undef MAX // Indefinimos MAX #endif #ifndef MAX #error No se definió MAX // MAX no esta definido muestra este mensaje de error #endif }

7.3. #PRAGMA (C18)

Se utiliza para definir directivas y su utilización depende del compilador. Para C18 se utiliza para definir los fusibles

del microcontrolador y para definir la sección de memoria donde se almacenaran ciertos datos, los cuales de ven

en la siguiente sección.

Para configurar los fusibles se define de la siguiente manera, la información se puede consultar en el archivo

“hlpPIC18ConfigSet.chm”:

#pragma config Fusible=estado

7.3.1. Ejemplo.

main.c #include <p18F14k50.h> #pragma config CPUDIV=NOCLKDIV // CPU System Clock Selection bit: // NOCLKDIV No CPU System Clock divide // CLKDIV2 CPU System Clock divided by 2 // CLKDIV3 CPU System Clock divided by 3 // CLKDIV4 CPU System Clock divided by 4 #pragma config USBDIV=OFF // USB Clock Selection bit: // OFF USB Clock comes directly from the OSC1/OSC2 oscillator block; no divide // ON USB clock comes from the OSC1/OSC2 divided by 2 #pragma config FOSC=HS // Oscillator Selection bits: // LP LP oscillator // XT XT oscillator // HS HS oscillator // ERCCLKOUT External RC oscillator, CLKOUT function on OSC2 // ECCLKOUTH EC, CLKOUT function on OSC2 (high) // ECH EC (high) // ERC External RC oscillator // IRC Internal RC oscillator // IRCCLKOUT Internal RC oscillator, CLKOUT function on OSC2 // ECCLKOUTM EC, CLKOUT function on OSC2 (medium) // ECM EC (medium) // ECCLKOUTL EC, CLKOUT function on OSC2 (low) // ECL EC (low) #pragma config PLLEN=ON // 4 X PLL Enable bit: // OFF PLL is under software control // ON Oscillator multiplied by 4 #pragma config PCLKEN=ON // Primary Clock Enable Bit: // OFF Primary clock is under software control // ON Primary clock enabled #pragma config FCMEN=OFF // Fail-Safe Clock Monitor Enable bit: // OFF Fail-Safe Clock Monitor disabled // ON Fail-Safe Clock Monitor enabled #pragma config IESO=OFF // Internal/External Oscillator Switchover bit: // OFF Oscillator Switchover mode disabled // ON Oscillator Switchover mode enabled #pragma config PWRTEN=OFF // Power-up Timer Enable bit: // ON PWRT enabled // OFF PWRT disabled #pragma config BOREN=ON // Brown-out Reset Enable bits: // OFF Brown-out Reset disabled in hardware and software

Page 33: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 30

// ON Brown-out Reset enabled and controlled by software (SBOREN is enabled) // NOSLP Brown-out Reset enabled in hardware only and disabled in Sleep mode (SBOREN is disabled) // SBORDIS Brown-out Reset enabled in hardware only (SBOREN is disabled) #pragma config BORV=30 // Brown Out Voltage: // 30 VBOR set to 3.0 V nominal // 27 VBOR set to 2.7 V nominal // 22 VBOR set to 2.2 V nominal // 19 VBOR set to 1.9 V nominal #pragma config WDTEN=OFF // Watchdog Timer Enable bit: // OFF WDT is controlled by SWDTEN bit of the WDTCON register // ON WDT is always enabled. SWDTEN bit has no effect. #pragma config WDTPS = 1 // Watchdog Timer Postscale Select bits: // 1 1:1 // 2 1:2 // 4 1:4 // 8 1:8 // 16 1:16 // 32 1:32 // 64 1:64 // 128 1:128 // 256 1:256 // 512 1:512 // 1024 1:1024 // 2048 1:2048 // 4096 1:4096 // 8192 1:8192 // 16384 1:16384 // 32768 1:32768 #pragma config MCLRE=OFF // MCLR Pin Enable bit: // OFF RE3 input pin enabled; MCLR disabled // ON MCLR pin enabled, RE3 input pin disabled #pragma config HFOFST=OFF // HFINTOSC Fast Start-up bit: // OFF The system clock is held off until the HFINTOSC is stable. // ON HFINTOSC starts clocking the CPU without waiting for the oscillator to stabilize. #pragma config STVREN=ON // Stack Full/Underflow Reset Enable bit: // OFF Stack full/underflow will not cause Reset // ON Stack full/underflow will cause Reset #pragma config LVP=ON // Single-Supply ICSP Enable bit: // OFF Single-Supply ICSP disabled // ON Single-Supply ICSP enabled #pragma config BBSIZ=OFF // Boot Block Size Select Bit: // OFF 1kW boot block size // ON 2kW boot block size #pragma config XINST=OFF // Extended Instruction Set Enable bit: // OFF Instruction set extension and Indexed Addressing mode disabled (Legacy mode) // ON Instruction set extension and Indexed Addressing mode enabled #pragma config CP0=OFF // Code Protection bit: // ON Block 0 code-protected // OFF Block 0 not code-protected #pragma config CP1=OFF // Code Protection bit: // ON Block 1 code-protected // OFF Block 1 not code-protected #pragma config CPB=OFF // Boot Block Code Protection bit: // ON Boot block code-protected // OFF Boot block not code-protected #pragma config CPD=OFF // Data EEPROM Code Protection bit: // ON Data EEPROM code-protected // OFF Data EEPROM not code-protected #pragma config WRT0=OFF // Write Protection bit: // ON Block 0 write-protected

// OFF Block 0 not write-protected #pragma config WRT1=OFF // Write Protection bit: // ON Block 1 write-protected // OFF Block 1 not write-protected #pragma config WRTB=OFF // Boot Block Write Protection bit: // ON Boot block write-protected // OFF Boot block not write-protected #pragma config WRTC=OFF // Configuration Register Write Protection bit: // ON Configuration registers write-protected // OFF Configuration registers not write-protected #pragma config WRTD=OFF // Data EEPROM Write Protection bit: // ON Data EEPROM write-protected // OFF Data EEPROM not write-protected #pragma config EBTR0=OFF // Table Read Protection bit: // ON Block 0 protected from table reads executed in other blocks // OFF Block 0 not protected from table reads executed in other blocks #pragma config EBTR1=OFF // Table Read Protection bit: // ON Block 1 protected from table reads executed in other blocks // OFF Block 1 not protected from table reads executed in other blocks #pragma config EBTRB=OFF // Boot Block Table Read Protection bit: // ON Boot block protected from table reads executed in other blocks // OFF Boot block not protected from table reads executed in other blocks void main(void) { ; }

Page 34: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 31

7.4. SECCIONES DE MEMORIA (C18)

Las secciones son diversas áreas de memoria del PIC18:

Memoria de programa (ROM)

Memoria de datos (RAM)

Memoria de datos de USB (USB-RAM)

Memoria EEPROM

Etc.

En el archivo *.lnk del PIC18 en específico se pueden observar las diferentes áreas y rangos de las memorias,

donde:

page: Memoria de programa (code y romdata)

gprX: Memoria de datos en grupos de 256B (idata y udata)

usbX: Memoria de datos para USB en grupos de 256B (Solo algunos uC)

PROTECTED: Áreas donde el compilador no colocara instrucciones o datos automáticamente, a menos

que se lo indiquemos con #pragma.

La sintaxis para definir cada área es la siguiente:

Contiene variables no inicializadas estáticas.

#pragma udata [attribute-list] [section-name [=address]]

Contiene variables inicializadas estáticas.

#pragma idata [attribute-list] [section-name [=address]]

Contiene constantes estáticas.

#pragma romdata [overlay] [section-name [=address]]

Contiene instrucciones.

#pragma code [overlay] [section-name [=address]]

El [attribute-list] pueden ser [access] y le indica al compilador que debe incluir la sección por el modo acceso a

datos access bank sin necesidad de modificar el banco actual de la RAM.

El modo [overlay] permite que otras secciones se sitúen en las mismas posiciones físicas, permitiendo conservar

memoria siempre que no se activen simultáneamente.

Para que el modo [overlay] sea válido se deben cumplir las dos siguientes condiciones:

1. Las dos secciones deben pertenecer a fichero distintos.

2. Deben tener el mismo nombre y dirección.

Page 35: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 32

7.4.1. Ejemplo.

main.c

// Prototipos void funcion1(unsigned char); void funcion2(unsigned char); void funcion3(unsigned char); extern void funcion10(void); // pertenecen a otro modulo extern void funcion14(void); extern void funcion12(void); extern void funcion16(void); // Variables globales #pragma udata seccion_uvar=0x200 unsigned char var1; char varchar; #pragma udata #pragma udata access seccion_uvar_access // Con modo access no se especifica la dirección near unsigned char var2; #pragma udata #pragma idata seccion_ivar=0x210 unsigned char var3 = 25; #pragma idata #pragma idata access seccion_ivar_access // Con modo access no se especifica la dirección near unsigned char var4 = 30; #pragma idata #pragma romdata const_table=0x3000 // constante a partir de la dirección de programa 0x3000 const rom unsigned char a_num[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; const rom char a_hola[] = "Hola"; #pragma romdata void main(void) { var1 = 100; // Dirección 0x200 var2 = 200; // Dirección 0x2 definida por el compilador sin utilizar bancos (access ram <= 0x5F) var3 = 150; // Dirección 0x210 var4 = 180; // Dirección 0x3 definida por el compilador sin utilizar bancos (access ram <= 0x5F) var1 = a_num[0]; // var1=0 leída de la memoria de programa var1 = a_num[3]; // var1=3 leída de la memoria de programa var1 = a_num[10]; // var1=10 leída de la memoria de programa varchar = a_hola[0]; // varchar='H' leída de la memoria de programa varchar = a_hola[1]; // varchar='o' leída de la memoria de programa varchar = a_hola[2]; // varchar='l' leída de la memoria de programa varchar = a_hola[3]; // varchar='a' leída de la memoria de programa funcion1(1); funcion2(2); // Llamada a la funcion2 que empieza en la dirección 0x100 específicamente funcion3(3); // Llamada a la funcion3 que continua de la dirección de la funcion2 funcion10(); // var10=0x10 dir=0x250, var11=0x11 dir=0x251 funcion14(); // var14=0x14 dir=0x260, var15=x015 dir=0x261 funcion12(); // var12=0x1212 dir=0x250 por estar en overlay sobrescribe var10 y var11 funcion16(); // var16=0x1616 dir=0x260 por estar en overlay sobrescribe var14 y var15 } // La dirección de este codigo la definirá el compilador void funcion1(unsigned char x) { x++; } // Este código se pondrá en la posición 0x100 específicamente #pragma code mi_codigo=0x100 void funcion2(unsigned char x) { x = 150; } // Este código continuara de la funcion2 void funcion3(unsigned char x) { x = 180; } #pragma code

Page 36: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 33

archivo1.c

#pragma udata overlay overlay_udat=0x250 unsigned char var10, var11; #pragma udata #pragma idata overlay overlay_idat=0x260 unsigned char var14=100, var15=200; #pragma idata void funcion10(void){ var10=0x10; var11=0x11; } void funcion14(void){ var14=0x14; var15=0x15; }

archivo2.c

#pragma udata overlay overlay_udat=0x250 unsigned int var12; #pragma udata #pragma idata overlay overlay_idat=0x260 unsigned int var16=0xFFFF; #pragma idata void funcion12(void){ var12=0x1212; } void funcion16(void){ var16=0x1616; }

7.5. ENSAMBLADOR EN LÍNEA

Nos ayuda a escribir código ensamblador directamente sobre C.

El código se escribe entre _asm _endasm.

7.5.1. Ejemplo.

main.c

#pragma udata access seccion_uvar_access unsigned char count; #pragma udata void main(void) { _asm MOVLW 10 // W = 10 MOVWF count,0 // count = W = 10 start: DECFSZ count,1,0 // count--, brinca si es igual a cero BRA start // goto start: GOTO done done: _endasm }

Page 37: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 34

8. LIBRERÍAS

8.1. QUE ES UNA LIBRERÍA Y COMO USARLA

Una librería es un conjunto de cabeceras, variables, funciones y definiciones agrupadas en un archivo para que

puedan ser utilizadas, normalmente este grupo se encarga de realizar ciertas tareas específicas para un dispositivo

o para cierto proceso.

Las librerías se diseñan con el objetivo de reutilizar el código y reducir el tiempo de programación.

Para usar una librería solamente utilizamos la directiva #define <cabecera.h> o #define “cabecera.h” al principio

de nuestro programa en main.c.

Para este ejemplo utilizaremos la librería <delays.h> que se encarga de generar retardos en el microcontrolador

utilizando las siguientes funciones:

Delay1TCY(); Nop(); = 1xTCY

Delay10TCYx(0-255); Múltiplos de 10xTCY, 0 = 2,560 ciclos

Delay100TCYx(0-255); Múltiplos de 100xTCY, 0 = 256,000 ciclos

Delay10KTCYx(0-255); Múltiplos de 10KxTCY, 0 = 2,560,000 ciclos

Donde un:

Para convertir el tiempo a ciclos se utiliza la siguiente formula:

Dónde:

TCY: Tiempo de un ciclo del microcontrolador (s).

FrecOsc: Frecuencia oscilador (MHz).

CR: Ciclos requeridos (TCY).

Tiempo: Tiempo (s)

Para el ejemplo la frecuencia del microcontrolador se establece a 48 MHz, por lo tanto TCY = 83.33 ns

Se busca generar retardos de 100ms, 250ms, 500ms y 1s. Por lo tanto utilizando la formula anterior calculamos los

TCY para cada tiempo.

100ms = 1.2M TCY

250ms = 3M TCY

300ms = 3.6M TCY

500ms = 6M TCY

1s = 12M TCY

Page 38: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 35

8.1.1. Ejemplo.

main.c

// Añadimos la librería de demoras #include <delays.h> void main(void) { // Estos ejemplos están calculados con un reloj de 48MHz // Usando la librería <delays.h> Delay1TCY(); // 1xTC = 83.33nS Delay10TCYx(0); // 2559xTC = 213.25uS Delay10TCYx(128); // 1280xTC = 106.666uS Delay10TCYx(255); // 2549xTC = 212.416uS Delay100TCYx(0); // 25599xTC = 2.133mS Delay100TCYx(128); // 12800xTC = 1.066mS Delay100TCYx(255); // 25499xTC = 2.124mS Delay10KTCYx(0); // 2559999xTC = 213.333mS Delay10KTCYx(128); // 1280000xTC = 106.666mS Delay10KTCYx(255); // 2550009xTC = 212.500mS Delay10KTCYx(120); // Para 100ms Delay10KTCYx(255); // Para 250ms Delay10KTCYx(45); Delay10KTCYx(255); // Para 300ms Delay10KTCYx(105); Delay10KTCYx(255); // Para 500ms Delay10KTCYx(255); Delay10KTCYx(90); Delay10KTCYx(255); // Para 1s Delay10KTCYx(255); Delay10KTCYx(255); Delay10KTCYx(255); Delay10KTCYx(180); }

8.2. COMO CREAR TU LIBRERÍA DE DEMORAS

Para crear nuestra propia librería de demoras predefinidas o funciones para generarlas hay que crear dos archivos:

El archivo de cabecera nombrelibreria.h con el siguiente formato:

nombrelibreria.h

#ifndef __NOMBRELIBRERIA_H #define __NOMBRELIBRERIA_H /** INCLUDES *******************************************************/ /** MACROS & TYPEDEF ***********************************************/ /** PROTOTYPES *****************************************************/ #endif // __NOMBRELIBRERIA_H

El archivo de definiciones nombrelibreria.c con el siguiente formato:

nombrelibreria.c

/** INCLUDES *******************************************************/ #include "nombrelibreria.h" /** DEFINITIONS ****************************************************/ void FuncionX(void){ ; }

Page 39: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 36

8.2.1. Ejemplo.

wait.h

#ifndef __WAIT_H #define __WAIT_H /** INCLUDES *******************************************************/ #include <delays.h> // Delays in instructions /** MACROS & TYPEDEF ***********************************************/ #define Wait1us() Delay10TCYx(1); Delay1TCY(); Delay1TCY() // INST: 12 * 83 = 0.996us #define Wait5us() Delay10TCYx(6) // INST: 60 * 83 = 4.999us #define Wait10us() Delay10TCYx(12) // INST: 122 * 83 = 10.126us #define Wait20us() Delay10TCYx(24) // INST: 242 * 83 = 20.086us #define Wait25us() Delay10TCYx(30) // INST: 303 * 83 = 25.149us #define Wait50us() Delay10TCYx(60) // INST: 602 * 83 = 49.966us #define Wait100us() Delay10TCYx(120) // INST: 1202 * 83 = 99.766us #define Wait200us() Delay10TCYx(240) // INST: 2402 * 83 = 199.366us #define Wait250us() Delay100TCYx(30) // INST: 3002 * 83 = 249.166us #define Wait500us() Delay100TCYx(60) // INST: 6002 * 83 = 498.166us /** PROTOTYPES *****************************************************/ /******************************************************************* * Function: void Waitmsx(unsigned int) * Input: 1-65535 ms (16b) * Output: None * Description: Wait 1 to 65535 ms *******************************************************************/ void Waitmsx(unsigned int); #endif // __WAIT_H wait.c

/** INCLUDES *******************************************************/ #include "wait.h" /** FUNCTIONS ******************************************************/ /******************************************************************* * Function: void WaitXms(unsigned int) * Input: 1-65535 ms (16b) * Output: None * Description: Wait 1 to 65535 ms * INST: 1 = 12062 * 83 = 1.001ms *******************************************************************/ void Waitmsx(unsigned int ms){ unsigned int c; for(c=0; c < ms; c++) Delay1KTCYx(12); } main.c

#include "wait.h" void main(void) { // Estos ejemplos están calculados con un reloj de 48MHz // Usando la librería “wait.h” Wait1us(); // 12 = 1us Wait5us(); // 60 = 5us Wait10us(); // 120 = 10us Wait20us(); // 240 = 20us Wait25us(); // 300 = 25us Wait50us(); // 600 = 50us Wait100us(); // 1200 = 100us Wait200us(); // 2400 = 200us Wait250us(); // 3000 = 250us Wait500us(); // 6000 = 500us Waitmsx(0); // 41 = 3.416us Waitmsx(1); // 12060 = 1.005ms Waitmsx(5); // 60136 = 5.011ms Waitmsx(100); // 1201941 = 100.161ms Waitmsx(500); // 6009544 = 500.795ms Waitmsx(1000); // 12019048 = 1.001s Waitmsx(5000); // 60095090 = 5.007s }

Page 40: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 37

8.3. COMO CREAR TU LIBRERÍA DE TIPOS DE VARIABLES

Para facilitar la declaración de variables vamos a crear una librería con varios typedef más significativos, por

ejemplo el unsigned char también es conocido como BYTE o u8 y es más corto, también declararemos un tipo bool

como true y false, entre otros más.

Esto también ayuda a que si portamos el código a otro compilador y la cantidad de bits se mueve o el tipo básico

no existe podemos solamente ajustarlo en esta cabecera y no en el código del programa.

8.3.1. Ejemplo.

variables.h

#ifndef __VARIABLES_H #define __VARIABLES_H /** MACROS & TYPEDEF ***********************************************/ // 8b signed [-128 -> 127] typedef char INT8, s8; // 8b unsigned [0 -> 255] typedef unsigned char UCHAR, UINT8, u8, BYTE; // 16b signed [-32,768 -> 32,767] typedef int INT16, s16; //typedef short SSHORT; // 16b unsigned [0 -> 65,535] typedef unsigned int UINT, UINT16, u16, WORD; //typedef unsigned short USHORT; // 24b signed [-8,388,608 -> 8,388,607] typedef short long INT24, s24; // 24b unsigned [0 -> 16,777,215] typedef unsigned short long UINT24, u24; // 32b signed [-2,147,483,648 -> 2,147,483,647] typedef long INT32, s32; // 32b unsigned [0 -> 4,294,967,295] typedef unsigned long ULONG, UINT32, u32, DWORD; // 32b decimal point [exp(-126) -> exp(128)] typedef float FLOAT; typedef double DOUBLE; // 8b Boolean typedef enum {false,true} boolean, bool; #endif // __VARIABLES_H

main.c

// Añadimos la libreria #include "variables.h" void main(void) { // 8b signed [-128 -> 127] INT8 a = -128; s8 b = 127; // 8b unsigned [0 -> 255] UCHAR c = 0; UINT8 d = 255; u8 e = 0; BYTE f = 255; // 16b signed [-32,768 -> 32,767] INT16 g = -32768; s16 h = 32767; // 16b unsigned [0 -> 65,535] UINT i = 0;

Page 41: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 38

UINT16 j = 65535; u16 k = 0; WORD l = 65535; // 24b signed [-8,388,608 -> 8,388,607] INT24 m = -8388608; s24 n = 8388607; // 24b unsigned [0 -> 16,777,215] UINT24 o = 0; u24 p = 16777215; // 32b signed [-2,147,483,648 -> 2,147,483,647] INT32 q = -2147483648; s32 r = 2147483647; // 32b unsigned [0 -> 4,294,967,295] ULONG s = 0; UINT32 t = 4294967295; u32 u = 0; DWORD v = 4294967295; // 32b decimal point [exp(-126) -> exp(128)] FLOAT x = -2.69; DOUBLE y = 2.69; // 8b Boolean boolean z1 = true; bool z2 = false; }

Page 42: MPLAB C18: C Básico

Omar Gurrola MPLAB C18: C Básico http://www.proprojects.wordpress.com

Revisión: 1.0 [05/2012] 39

9. REFERENCIAS

Casanova Alejandro, “Tutorial MPLAB C18”, 2010

http://issuu.com/suky_pdfs/docs/tutorial_c18_v2

Huss Eric, “The C Library Reference Guide”, 1997

http://www.acm.uiuc.edu/webmonkeys/book/c_guide/

Microchip, “MPLAB C18 C COMPILER GETTING STARTED”, 2005

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en0100

14

Page 43: MPLAB C18: C Básico

http://www.proprojects.wordpress.com