Você está na página 1de 65

Programacin de los microcontroladores - Microcontroladores

PIC Programacin en C con ejemplos


TOC
Capitulo 1
Capitulo 2
Capitulo 3
Capitulo 4
Apndice A
Capitulo 2 - Programacin de los microcontroladores

Usted seguramente sabe que no es suficiente slo conectar el microcontrolador a los otros componentes y

encender una fuente de alimentacin para hacerlo funcionar, verdad? Hay que hacer algo ms. Se necesita

programar el microcontrolador. Si cree que esto es complicado, est equivocado. Todo el procedimiento es

muy simple. Basta con leer el texto para entender de lo que estamos hablando.
2.1 LENGUAJES DE PROGRAMACIN
2.2 CARACTERSTICAS PRINCIPALES DEL MIKROC
2.3 TIPOS DE DATOS EN MIKROC
2.4 VARIABLES Y CONSTANTES
2.5 OPERADORES
2.6 ESTRUCTURAS DE CONTROL
2.7 TIPOS DE DATOS AVANZADOS
2.8 FUNCIONES
2.9 CARACTERSTICAS PRINCIPALES DEL PREPROCESADOR
2.10 MIKROC PRO FOR PIC
2.11 PROGRAMAR LOS PIC UTILIZANDO MIKROC PRO FOR PIC
2.1 LENGUAJES DE PROGRAMACIN

El microcontrolador ejecuta el programa cargado en la memoria Flash. Esto se denomina el cdigo


ejecutable y est compuesto por una serie de ceros y unos, aparentemente sin significado.
Dependiendo de la arquitectura del microcontrolador, el cdigo binario est compuesto por
palabras de 12, 14 o 16 bits de anchura. Cada palabra se interpreta por la CPU como una
instruccin a ser ejecutada durante el funcionamiento del microcontrolador. Todas las instrucciones
que el microcontrolador puede reconocer y ejecutar se les denominan colectivamente Conjunto de
instrucciones. Como es ms fcil trabajar con el sistema de numeracin hexadecimal, el cdigo
ejecutable se representa con frecuencia como una serie de los nmeros hexadecimales
denominada cdigo Hex. En los microcontroladores PIC con las palabras de programa de 14 bits
de anchura, el conjunto de instrucciones tiene 35 instrucciones diferentes.

LENGUAJE ENSAMBLADOR

Como el proceso de escribir un cdigo ejecutable era considerablemente arduo, en consecuencia


fue creado el primer lenguaje de programacin denominado ensamblador (ASM). Siguiendo la
sintaxis bsica del ensamblador, era ms fcil escribir y comprender el cdigo. Las instrucciones en
ensamblador consisten en las abreviaturas con significado y a cada instruccin corresponde una
localidad de memoria. Un programa denominado ensamblador compila (traduce) las instrucciones
del lenguaje ensamblador a cdigo mquina (cdigo binario).

HEste programa compila instruccin a instruccin sin optimizacin. Como permite controlar en detalle todos

los procesos puestos en marcha dentro del chip, este lenguaje de programacin todava sigue siendo popular.

Ventajas de lenguajes de programacin de alto nivel

A pesar de todos los lados buenos, el lenguaje ensamblador tiene algunas desventajas:

Incluso una sola operacin en el programa escrito en ensamblador consiste en muchas


instrucciones, hacindolo muy largo y difcil de manejar.
Cada tipo de microcontrolador tiene su propio conjunto de instrucciones que un
programador tiene que conocer para escribir un programa
Un programador tiene que conocer el hardware del microcontrolador para escribir un
programa
Programa escrito en C (El mismo programa compilado al cdigo ensamblador):
Los lenguajes de programacin de alto nivel (Basic, Pascal, C etc.) fueron creados con el propsito de superar

las desventajas del ensamblador. En lenguajes de programacin de alto nivel varias instrucciones en

ensamblador se sustituyen por una sentencia. El programador ya no tiene que conocer el conjunto de

instrucciones o caractersticas del hardware del microcontrolador utilizado. Ya no es posible conocer

exactamente cmo se ejecuta cada sentencia, de todas formas ya no importa. Aunque siempre se puede

insertar en el programa una secuencia escrita en ensamblador.

Si alguna vez ha escrito un programa para un microcontrolador PIC en lenguaje ensamblador, probablemente

sepa que la arquitectura RISC carece de algunas instrucciones. Por ejemplo, no hay instruccin apropiada

para multiplicar dos nmeros. Por supuesto, para cada problema hay una solucin y ste no es una excepcin

gracias a la aritmtica que permite realizar las operaciones complejas al descomponerlas en un gran nmero

operaciones ms simples. En este caso, la multiplicacin se puede sustituir con facilidad por adicin sucesiva

(a x b = a + a + a + ... + a). Ya estamos en el comienzo de una historia muy larga... No hay que preocuparse al
utilizar uno de estos lenguajes de programacin de alto nivel como es C, porque el compilador encontrar

automticamente la solucin a ste problema y otros similares. Para multiplicar los nmeros a y b, basta con

escribir a*b.

Lenguaje C

El lenguaje C dispone de todas las ventajas de un lenguaje de programacin de alto nivel (anteriormente

descritas) y le permite realizar algunas operaciones tanto sobre los bytes como sobre los bits (operaciones

lgicas, desplazamiento etc.). Las caractersticas de C pueden ser muy tiles al programar los

microcontroladores. Adems, C est estandarizado (el estndar ANSI), es muy portable, as que el mismo

cdigo se puede utilizar muchas veces en diferentes proyectos. Lo que lo hace accesible para cualquiera que

conozca este lenguaje sin reparar en el propsito de uso del microcontrolador. C es un lenguaje compilado, lo

que significa que los archivos fuentes que contienen el cdigo C se traducen a lenguaje mquina por el

compilador. Todas estas caractersticas hicieron al C uno de los lenguajes de programacin ms populares.

La figura anterior es un ejemplo general de lo que sucede durante la compilacin de programa de un lenguaje

de programacin de alto nivel a bajo nivel.

2.2 CARACTERSTICAS PRINCIPALES DEL MIKROC

A continuacin vamos a presentar a los elementos principales del lenguaje mikroC desarrollado por

Mikroelektronika. Este lenguaje es muy similar al C estndar, no obstante en determinados aspectos difiere

del ANSI estndar en algunas caractersticas. Algunas de estas diferencias se refieren a las mejoras,

destinadas a facilitar la programacin de los microcontroladores PIC, mientras que las dems son la
consecuencia de la limitacin de la arquitectura del hardware de los PIC. Aqu vamos a presentar

caractersticas especficas del lenguaje mikroC en la programacin de los microcontroladores PIC. El trmino

C se utilizar para referirse a las caractersticas comunes de los lenguajes C y mikroC.

Este libro describe una aplicacin muy concreta del lenguaje de programacin C utilizado en el compilador

mikroC PRO for PIC. En este caso, el compilador se utiliza para la programacin de los microcontroladores

PIC.

FASES DE COMPILACIN

El proceso de compilacin consiste en varios pasos y se ejecuta automticamente por el compilador. Por con,

un conocimiento bsico del funcionamiento puede ser til para entender el concepto del lenguaje mikroC.

El archivo fuente contiene el cdigo en mikroC que usted escribe para programar el microcontrolador. El

preprocesador se utiliza automticamente por el compilador al iniciarse el proceso de la compilacin. El

compilador busca las directivas del preprocesador (que siempre empiezan por #) dentro del cdigo y modifica

el cdigo fuente de acuerdo con las directivas. En esta fase se llevan a cabo inclusin de archivos, definicin

de constantes y macros etc, lo que facilita el proceso. Ms tarde vamos a describir estas directivas en detalle.

El analizador sintctico (parser) elimina toda la informacin intil del cdigo (comentarios, espacios en

blanco). Luego, elcompilador traduce el cdigo a un archivo binario denominado archivo .mcl.

El enlazador (linker) recupera toda la informacin requerida para ejecutar el programa de los archivos

externos y la agrupa en un solo archivo (.dbg). Adems, un proyecto puede contener ms de un archivo fuente

y el programador puede utilizar funciones predefinidas y agrupadas dentro de los archivos denominados

libreras. Por ltimo, el generador .hex produce un archivo .hex. Es el archivo que se va a cargar en el

microcontrolador.
El proceso entero de la compilacin que incluye todos los pasos anteriormente descritos se le

denomina building.
ESTRUCTURA DE PROGRAMA

La idea principal de escribir un programa en C es de romper un problema mayor en varios trozos ms

pequeos. Supongamos que es necesario escribir un programa para el microcontrolador para medir la

temperatura y visualizar los resultados en un LCD. El proceso de medicin se realiza por un sensor que

convierte temperatura en voltaje. El microcontrolador utiliza el convertidor A/D para convertir este voltaje (valor

analgico) en un nmero (valor digital) que luego se enva al LCD por medio de varios conductores. En

consecuencia, el programa se divide en cuatro partes, de las que cada una corresponde a una accin

especfica:

1. Activar y configurar el convertidor A/D incorporado;


2. Medir el valor analgico;
3. Calcular temperatura; y
4. Enviar los datos en el formato apropiado al LCD;

Los lenguajes de programacin de alto nivel como es C le permiten solucionar este problema con
facilidad al escribir cuatro funciones que se ejecutarn cclicamente sin parar.

La idea general es de dividir el problema en varios trozos, de los que cada uno se puede escribir
como una sola funcin. Todos los programas escritos en mikroC contienen por lo menos una
funcin llamada main() que encierra entre llaves {} las sentencias a ser ejecutadas. Esto es la
primera funcin a ser ejecutada al iniciarse la ejecucin de programa. Las otras funciones se
pueden llamar dentro de la funcin main. En otras palabras, podemos decir que la funcin main()
es obligatoria, mientras que las dems son opcionales. Si todava no ha escrito un programa en C,
es probable que todo le resulte confuso. No se preocupe, acptelo tal como es por el momento y
ms tarde entender la sintaxis.
Y ahora, su primer programa real! La figura muestra la estructura de programa, sealando las partes en las

que consiste.

La manera de escribir el cdigo en C es muy importante. Por ejemplo, C difiere entre minsculas y

maysculas, as que la funcin main() no se puede escribir MAIN() o Main(). Adems, note que dos lneas del

cdigo dentro de la funcin terminan con un punto y coma. En C todas las sentencias deben terminar con un

punto y coma ;, as el compilador puede aislarlas y traducirlas a cdigo mquina.


COMENTARIOS

Los comentarios son las partes del programa utilizados para aclarar las instrucciones de programa o para

proporcionar ms informacin al respecto. El compilador no hace caso a los comentarios y no los compila al
cdigo ejecutable. Dicho de manera sencilla, el compilador es capaz de reconocer los caracteres especiales

utilizados para designar dnde los comentarios comienzan y terminan y no hace nada de caso al texto entre

ellos durante la compilacin. Hay dos tipos de tales caracteres. Unos designan los comentarios largos que

ocupan varias lneas de programa marcados por la secuencia especial /*...*/, mientras que otros designan los

comentarios cortos que caben en una sola lnea //. Aunque los comentarios no pueden afectar a la ejecucin

de programa, son tan importantes como cualquier otra parte de programa. Aqu est el porqu... Con

frecuencia es necesario mejorar, modificar, actualizar, simplificar un programa... No es posible interpretar

incluso los programas simples sin utilizar los comentarios.

2.3 TIPOS DE DATOS EN MIKROC

En el lenguaje C, los datos tienen un tipo, o sea, cada dato utilizado en el programa debe tener su tipo
especificado. Esto permite al compilador conocer el tamao de dato (nmero de bytes requerido en la

memoria) y su representacin. Hay varios tipos de datos que se pueden utilizar en el lenguaje de

programacin mikroC dependiendo del tamao de dato y del rango de valores. La tabla muestra el rango de

valores que los datos pueden tener cuando se utilizan en su forma bsica.

TIPO DE TA M A O ( N M E R O D E
DESCRIPCIN R A N G O D E VA L O R E
D AT O BITS)

char Texto (caracteres) 8 de 0 a 255

int Valores enteros 16 de -32768 a 32767

de 1.1754943508210-38
float Valores en punto flotante 32
6.805647744071038

Valores en punto flotante de doble de 1.1754943508210-38


double 32
precisin 6.805647744071038

*Debido a las limitaciones impuestas por el hardware del microcontrolador, es imposible alcanzar una mayor

precisin de datos que la del tipo float. Por eso, el tipo double en mikroC equivale al tipo float.

Al aadir un prefijo (calificador) a cualquier tipo de dato entero o carcter, el rango de sus posibles valores

cambia as como el nmero de los bytes de memoria necesarios. Por defecto, los datos de tipo int son con

signo, mientras que los de tipo char son sin signo. El calificador signed (con signo) indica que el dato puede

ser positivo o negativo. El prefijo unsigned indica que el dato puede ser slo positivo. Note que el prefijo es

opcional.

T I P O D E D AT O T I P O D E D AT O C O N P R E F I J O TA M A O ( N M E R O D E B I T S ) R A N G O D E VA L
char signed char 8 de -128 a 128

unsigned int 16 de 0 a 65535

short int 8 de 0 a 255

int signed short int 8 de -128 a 127

long int 32 de 0 a 4294967

signed long int 32 de -2147483648 a 214

Tipo entero (int)

Un entero es un nmero sin parte fraccionaria que puede estar expresado en los siguientes formatos:

Hexadecimal (base 16): el nmero empieza con 0x (o 0X). Los enteros hexadecimales
consisten en los dgitos (de 0 a 9) y/o las letras (A, B, C,D, E, F). Por ejemplo: 0x1A.
Decimal (base 10): el nmero consiste en los dgitos (de 0 a 9). El primer dgito no puede
ser 0. En este formato, se puede introducir el signo de nmero (+ o -). Por ejemplo: 569,
-25, +1500.
Octal (base 8): los nmeros se representan a base 8 utilizando slo 8 dgitos (de 0 a 7).
Los enteros octales empiezan con 0. Por ejemplo: 056.
Binario: cuando un entero empieza con 0b (o 0B) se representan como una serie de bits
(0 y 1). Por ejemplo: 0B10011111

0x11 // formato hexadecimal equivale a decimal 17


11 // formato decimal
-152 // formato decimal
011 // formato octal equivale a decimal 9
0b11 // formato binario equivale a decimal 3

Tipo punto flotante (float)

El tipo punto flotante (float) se utiliza para los nmeros reales con el punto decimal. Los datos de tipo float se

pueden representar de varias maneras. Un dato float es siempre consigno (signed).

0. // = 0.0
-1.23 // = -1.23
23.45e6 // = 23.45 * 10^6
2e-5 // = 2.0 * 10^-5
3E+10 // = 3.0 * 10^10
.09E34 // = 0.09 * 10^34

Tipo carcter (char)

El tipo char es considerado como un entero por el compilador. No obstante, se utiliza normalmente para los

datos de tipo carcter. Un dato de tipo carcter est encerrado entre comillas y codificado en un carcter

ASCII.
59 // entero
'p' // carcter ASCII 'p'

Una secuencia de caracteres es denominada cadena (string). Las cadenas estn encerradas entre comillas

dobles, por ejemplo:

"Presione el botn RA0"

2.4 VARIABLES Y CONSTANTES


Definiciones

Una variable es un objeto nombrado capaz de contener un dato que puede ser modificado durante la

ejecucin de programa. En C, las variables tienen tipo, que significa que es necesario especificar el tipo de

dato que se le asigna a una variable (int, float etc.). Las variables se almacenan en la memoria RAM y el

espacio de memoria que ocupan (en bytes) depende de su tipo.

/* dos lneas de programa consecutivas. En la primera lnea del programa


se define el tipo de variable */

int a = 1000; // Variable a es de tipo int y equivale a 1000


a = 15; // a equivale a 15

Una constante tiene las mismas caractersticas que una variable excepto el hecho de que su valor asignado

no puede ser cambiado durante la ejecucin de programa. A diferencia de las variables, las constantes se

almacenan en la memoria Flash del microcontrolador para guardar el mayor espacio posible de memoria

RAM. El compilador las reconoce por el nombre y el prefijo const. En mikroC, el compilador reconoce

automticamente el tipo de dato de una constante, as que no es necesario especificar el tipo adicionalmente.

/* dos lneas de programa consecutivas */

const A = 1000 // el valor de la constante A est definido


A = 15; // ERROR! no se puede modificar el valor de la constante

Cada variable o constante debe tener un identificador que lo distingue de otras variables y constantes.

Refirase a los ejemplos anteriores, a y A son identificadores.

Reglas para nombrar

En mikroC, los identificadores pueden ser tan largos como quiera. Sin embargo, hay varias restricciones:

Los identificadores pueden incluir cualquiera de los caracteres alfabticos A-Z (a-z), los
dgitos 0-9 y el carcter subrayado '_'. El compilador es sensible a la diferencia entre
minsculas y maysculas. Los nombres de funciones y variables se escriben con
frecuencia con minsculas, mientras que los nombres de constantes se escriben con
maysculas.
Los identificadores no pueden empezar con un dgito.
Los identificadores no pueden coincidir con las palabras clave del lenguaje mikroC, porque
son las palabras reservadas del compilador.
El compilador mikroC reconoce 33 palabras clave:

M I K R O C - PA L A B R A S C L AV E

absolute data if return typedef

asm default inline rx typeid

at delete int sfr typenam

auto do io short union

bit double long signed unsigned

bool else mutable sizeof using

break enum namespace static virtual

case explicit operator struct void

catch extern org switch volatile

char false pascal template while

class float private this

code for protected throw

const friend public true

continue goto register try

Ejemplos de los identificadores vlidos e invlidos:

temperatura_V1 // OK
Presin // OK
no_corresponder // OK
dat2string // OK
SuM3 // OK
_vtexto // OK
7temp // NO -- no puede empezar con un nmero
%ms_alto // NO -- no pueden contener caracteres especiales
if // NO -- no puede coincidir con una palabra reservada
j23.07.04 // NO -- no puede contener caracteres especiales
(punto)
nombre de variable // NO -- no puede contener espacio en blanco

Declaracin de variables

Cada variable debe ser declarada antes de ser utilizada en el programa. Como las variables se almacenan en

la memoria RAM, es necesario reservar el espacio para ellas (uno, dos o ms bytes). Al escribir un programa,

usted sabe qu tipo de datos quiere utilizar y qu tipo de datos espera como resultado de una operacin,

mientras que el compilador no lo sabe. No se olvide de que el programa maneja las variables con los nombres

asignados. El compilador las reconoce como nmeros en la memoria RAM sin conocer su tamao y formato.

Para mejorar la legibilidad de cdigo, las variables se declaran con frecuencia al principio de las funciones:

<tipo> variable;

Es posible declarar ms de una variable de una vez si tienen el mismo tipo.

<tipo> variable1, variable2, variable3;

Aparte del nombre y del tipo, a las variables se les asignan con frecuencia los valores iniciales justamente

enseguida de su declaracin. Esto no es un paso obligatorio, sino una cuestin de buenas costumbres. Se

parece a lo siguiente:

unsigned int peso; // Declarar una variable llamada peso


peso = 20; // Asignar el valor 20 a la variable peso

Un mtodo ms rpido se le denomina declaracin con inicializacin (asignacin de los valores iniciales):

unsigned int peso = 20; // peso est declarado y su valor es 20

Si hay varias variables con el mismo valor inicial asignado, el proceso se puede simplificar:

unsigned int peso1 = peso2 = peso3 = 20;


int valor_inicial = un_mnimo_de_petrleo = 0;

Tenga cuidado de no declarar la misma variable otra vez dentro de la misma funcin.
Puede modificar el contenido de una variable al asignarle un nuevo valor tantas veces que
quiera
Al declarar una variable, siempre piense en los valores que la variable tendr que contener
durante la ejecucin de programa. En el ejemplo anterior, peso1 no se puede representar
con un nmero con punto decimal o un nmero con valor negativo.
Declaracin de constantes

Similar a las variables, las constantes deben ser declaradas antes de ser utilizadas en el programa. En

mikroC, no es obligatorio especificar el tipo de constante al declararla. Por otra parte, las constantes deben

ser inicializadas a la vez que se declaran. El compilador reconoce las constantes por su prefijo const utilizado

en la declaracin. Dos siguientes declaraciones son equivalentes:

const int MINIMUM = -100; // Declarar constante MINIMUM


const MINIMUM = -100; // Declarar constante MINIMUM

Las constantes pueden ser de cualquier tipo, incluyendo cadenas:

const T_MAX = 3.260E1; // constante de punto


flotante T_MAX
const I_CLASS = 'A'; // constante carcter
I_CLASS
const Mensaje = "Presione el botn IZQUIERDA"; // constante de cadena
Mensaje

Las constantes de enumeracin son un tipo especial de constantes enteras que hace un programa ms

comprensible al asignar los nmeros ordinales a las constantes. Por defecto, el valor 0 se asigna

automticamente a la primera constante entre llaves, el valor 1 a la segunda, el valor 2 a la tercera etc.

enum surtidores {AGUA,GASLEO,CLORO}; // AGUA = 0; GASLEO = 1; CLORO =


2

Es posible introducir directamente el valor de una constante dentro de la lista de enumeraciones. El

incremento se detiene al asignar un valor a un elemento de matriz, despus se reinicia a partir del valor

asignado. Vea el siguiente ejemplo:

enum surtidores {AGUA,GASLEO=0,CLORO}; // AGUA = 0; GSOLEO = 0; CLORO


= 1

Las constantes de enumeracin se utilizan de la siguiente manera:

int Velocidad_de_ascensor
enum motor_de_ascensor {PARADA,INICIO,NORMAL,MXIMO};
Velocidad_de_ascensor = NORMAL; // Velocidad_de_ascensor = 2

Definir los nuevos tipos de datos


La palabra clave typedef le permite crear con facilidad los nuevos tipos de datos.

typedef unsigned int positivo; // positivo es un sinnimo para el tipo


sin signo int
positivo a,b; // Variables a y b son de tipo positivo
a = 10; // Variable a equivale a 10
b = 5; // Variable b equivale a 5

mbito de variables y constantes

Una variable o una constante es reconocida por el compilador en base de su identificador. Un identificador

tiene significado si el compilador lo puede reconocer. El mbito de una variable o una constante es el rango de

programa en el que su identificador tiene significado. El mbito es determinado por el lugar en el que se

declara una variable o una constante. Intentar acceder a una variable o una constante fuera de su mbito

resulta en un error. Una variable o una constante es invisible fuera de su mbito. Todas las variables y

constantes que pensamos utilizar en un programa deben ser declaradas anteriormente en el cdigo. Las

variables y constantes pueden ser globales o locales. Una variable global se declara en el cdigo fuente, fuera

de todas las funciones, mientras que una variable local se declara dentro del cuerpo de la funcin o dentro de

un bloque anidado en una funcin.

A las variables globales se les puede acceder de cualquiera parte en el cdigo, an dentro de las funciones

con tal de que sean declaradas. El mbito de una variable global est limitado por el fin del archivo fuente en

el que ha sido declarado.


El mbito de variables locales est limitado por el bloque encerrado entre llaves {} en el que han sido

declaradas. Por ejemplo, si estn declaradas en el principio del cuerpo de funcin (igual que en la

funcin main) su mbito est entre el punto de declaracin y el fin de esa funcin. Refirase al ejemplo

anterior. A las variables locales declaradas en main() no se les puede acceder desde la Funcin_1 y al revs.

Un bloque compuesto es un grupo de declaraciones y sentencias (que pueden ser bloques tambin)

encerradas entre llaves. Un bloque puede ser una funcin, una estructura de control etc. Una variable

declarada dentro de un bloque se considera local, o sea, existe slo dentro del bloque. Sin embargo, las

variables declaradas fuera del mbito todava son visibles.

Aunque las constantes no pueden ser modificadas en el programa, siguen las mismas reglas que las

variables. Esto significa que son visibles dentro de su bloque a excepcin de las constantes globales

(declaradas fuera de cualquier funcin). Las constantes se declaran normalmente en el inicio del cdigo fuera

de cualquier funcin (como variables globales).

Clases de almacenamiento

Las clases de almacenamiento se utilizan para definir el mbito y la vida de variables, constantes y funciones

dentro de un programa. En mikroC se pueden utilizar diferentes clases de almacenamiento:

auto es una clase de almacenamiento por defecto para las variables locales, as que se
utiliza raramente. Se utiliza para definir que una variable local tiene duracin local. La clase
de almacenamiento auto no se puede utilizar con variables globales.

static es una clase de almacenamiento por defecto para las variables globales. Especifica
que una variable es visible dentro del archivo. A las variables locales declaradas con el
prefijo static se les puede acceder dentro del archivo fuente (o sea se comportan como
variables globales).
extern: la palabra clave extern se utiliza cuando el programa est compuesto por
diferentes archivos fuente. Esto le permite utilizar una variable, una constante o una
funcin declarada en otro archivo. Por supuesto, para compilar y enlazar este archivo
correctamente, el mismo debe ser incluido en su proyecto. En los siguientes ejemplos, el
programa consiste en dos archivos: File_1 y File_2. El File_1 utiliza una variable y una
funcin declaradas en File_2.
File 1:

extern int cnt; // Variable cnt es visible en File_1


extern void hello(); // Funcin hello()se puede utilizar en File_1

void main(){
PORTA = cnt++; // Cualquier modificacin de cnt en File_1 ser
visible en File_2
hello(); // Funcin hello()se puede llamar desde aqu
}

File 2:

int cnt = 0;
void hello();

void hello(){ // Modificaciones que afectan a la


. // cnt en File_1 son visibles aqu
.
.
}

2.5 OPERADORES

Un operador es un smbolo que denota una operacin aritmtica, lgica u otra operacin particular. Dicho de

manera sencilla, varias operaciones aritmticas y lgicas se realizan por medio de los operadores. Hay ms

de 40 operaciones disponibles en el lenguaje C, pero se utiliza un mximo de 10-15 de ellas en prctica. Cada

operacin se realiza sobre uno o ms operandos que pueden ser variables o constantes. Adems, cada

operacin se caracteriza por la prioridad de ejecucin y por la asociatividad.

OPERADORES ARITMTICOS

Los operadores aritmticos se utilizan en las operaciones aritmticas y siempre devuelven resultados

numricos. Hay dos tipos de operadores, los unitarios y los binarios. A diferencia de las operaciones unitarias

que se realizan sobre un operando, las operaciones binarias se realizan sobre dos operandos. En otras

palabras, se requieren dos nmeros para ejecutar una operacin binaria. Por ejemplo: a+b o a/b.

OPERADOR OPERACIN

+ Adicin

- Resta

* Multiplicacin

/ Divisin

% Resto de la divisin

int a,b,c; // Declarar 3 enteros a, b, c


a = 5; // Inicializar a
b = 4; // Inicializar b
c = a + b; // c = 9
c = c%2; // c = 1. Esta operacin se utiliza con frecuencia
// para comprobar la paridad. En este caso, el
// resultado es 1 lo que significa que la variable
// es un nmero imparo

OPERADORES DE ASIGNACIN

Hay dos tipos de asignacin en el lenguaje C:

Los operadores simples asignan los valores a las variables utilizando el carcter comn '='.
Por ejemplo: a =8
Las asignaciones compuestas son especficas para el lenguaje C. Consisten en dos
caracteres como se muestra en la tabla a la derecha. Se utilizan para simplificar la sintaxis
y habilitar la ejecucin ms rpida.
EJEMPLO
OPERADOR
Expresin Equivalente

+= a += 8 a=a+8

-= a -= 8 a=a-8

*= a *= 8 a=a*8

/= a /= 8 a=a/8

%= a %= 8 a=a%8

int a = 5; // Declarar e inicializar la variable a


a += 10; // a = a + 10 = 15

OPERADORES DE INCREMENTO Y DECREMENTO

Las operaciones de incremento y decremento por 1 se denotan con "++" y "--". Estos caracteres pueden
preceder o seguir a una variable. En primer caso (++x), la variable x ser incrementada por 1 antes de ser

utilizada en la expresin. De lo contrario, la variable se utilizar en la expresin antes de ser aumentada por 1.

Lo mismo se aplica a la operacin de decremento.

OPERADOR EJEMPLO DESCRIPCIN

++a
++ Variable "a" es incrementada por 1
a++

--b
-- Variable "a" es decrementada por 1
b--
int a, b, c;
a = b = 5;
c = 1 + a++; // c = 6
b = ++c + a // b = 7 + 6 = 13

OPERADORES RELACIONALES

Los operadores relacionales se utilizan en comparaciones con el propsito de comparar dos valores. En

mikroC, si una expresin es evaluada como falsa (false), el operador devuelve 0, mientras que si una oracin

es evaluada como verdadera (true), devuelve 1. Esto se utiliza en expresiones tales como si la expresin es

evaluada como verdadera, entonces...

OPERADOR DESCRIPCIN EJEMPLO CONDICIN DE VERACIDAD

> mayor que b>a si b es mayor que a

>= mayor o igual que a >= 5 si a es mayor o igual que 5

< menor que a<b si a es menor que b

<= menor o igual que a <= b si a es menor o igual que b

== igual que a == 6 si a es igual que 6

!= desigual que a != b si a es desigual que b

int prop;
int var = 5;
prop = var < 10; // Expresin es evaluada como verdadera, prop = 1

OPERADORES LGICOS

Hay tres tipos de operaciones lgicas en el lenguaje C: Y (AND) lgico, O (OR) lgico y negacin - NO (NOT)

lgico. Los operadores lgicos devuelven verdadero (1 lgico) si la expresin evaluada es distinta de cero. En

caso contrario, devuelve falso (0 lgico) si la expresin evaluada equivale a cero. Esto es muy importante

porque las operaciones lgicas se realizan generalmente sobre las expresiones, y no sobre las variables

(nmeros) particulares en el programa. Por lo tanto, las operaciones lgicas se refieren a la veracidad de toda

la expresin.

Por ejemplo: 1 && 0 es igual a (expresin verdadera) && (expresin falsa)

El resultado 0, o sea - Falso en ambos casos.

OPERADOR FUNCIN
&& Y

|| O

! NO

OPERADORES DE MANEJO DE BITS

A diferencia de las operaciones lgicas que se realizan sobre los valores o expresiones, las operaciones de

manejo de bits se realizan sobre los bits de un operando. Se enumeran en la siguiente tabla:

OPERADOR DESCRIPCIN EJEMPLO R E S U LT A D O

~ Complemento a uno a = ~b b=5 a=

<< Desplazamiento a la izquierda a = b << 2 b = 11110011 a = 110

>> Desplazamiento a la derecha a = b >> 2 b = 11110011 a = 000

a = 11100011
& Y lgico para manejo de bits c=a&b c = 110
b = 11001100

a = 11100011
| O lgico para manejo de bits c=a|b c = 111
b = 11001100

a = 11100011
^ EXOR lgico para manejo de bits c=a^b c = 001
b = 11001100

Note que el resultado de la operacin de desplazamiento a la derecha depende del signo de la variable. En

caso de que el operando se aplique a una variable sin signo o positiva, se introducirn los ceros en el espacio

vaco creado por desplazamiento. Si se aplica a un entero con signo negativo, se introducir un 1 para

mantener el signo correcto de la variable.


CMO UTILIZAR LOS OPERADORES?

Aparte de los operadores de asignacin, dos operadores no deben estar escritos uno junto
al otro.

x*%12; // esta expresin generar un error

Cada operador tiene su prioridad y asociatividad como se muestra en la tabla:


Similar a las expresiones aritmticas, los operadores se agrupan juntos por medio de
parntesis. Primero se calculan las expresiones encerradas entre parntesis. Si es
necesario, se pueden utilizar los parntesis mltiples (anidados).
PRIORIDAD OPERADORES A S O C I AT I V I

Alta () [] -> . de izquierda a de


! ~ ++ -- +(unitario) -(unitario) *Puntero &Puntero de derecha a izq

* / % de izquierda a de

+ - de izquierda a de

< > de izquierda a de

< <= > >= de izquierda a de

== != de izquierda a de

& de izquierda a de

^ de izquierda a de

| de izquierda a de

&& de izquierda a de

|| de derecha a izq

?: de derecha a izq

Baja = += -= *= /= /= &= ^= |= <= >= de izquierda a de

int a, b, res;
a = 10;
b = 100;
res = a*(a + b); // resultado = 1100
res = a*a + b; // resultado = 200

CONVERSIN DE TIPOS DE DATOS

Algunas operaciones implican conversin de datos. Por ejemplo, si divide dos valores enteros, hay una alta

posibilidad de que el resultado no sea un entero. El mikroC realiza una conversin automtica cuando se

requiera.

Si dos operandos de tipo diferente se utilizan en una operacin aritmtica, el tipo de operando de la prioridad

ms baja se convierte automticamente en el tipo de operando de la prioridad ms alta. Los tipos de datos

principales se colocan segn el siguiente orden jerrquico:


La autoconversin se realiza asimismo en las operaciones de asignacin. El resultado de la expresin de la

derecha del operador de la asignacin siempre se convierte en el tipo de la variable de la izquierda del

operador. Si el resultado es de tipo de la prioridad ms alta, se descarta o se redondea para coincidir con el

tipo de la variable. Al convertir un dato real en un entero, siempre se descartan los nmeros que siguen al

punto decimal.

int x; // A la variable x se le asigna el tipo integer (un entero)


x = 3; // A la variable x se le asigna el valor 3
x+ = 3.14; // El valor 3.14 se agrega a la variable x al
// realizar la operacin de asignacin

/* El resultado de la adicin es 6 en vez de 6.14, como era de esperar.


Para obtener el resultado esperado sin descartar los nmeros que siguen
al
punto decimal, se debe declarar x como un punto flotante. */

Para realizar una conversin explcita, antes de escribir una expresin o una variable hay que especificar el

tipo de resultado de operacin entre parntesis.

double distancia, tiempo, velocidad;


distancia = 0.89;
tiempo = 0.1;
velocidad = (int)(a/b); // c = (int)8.9 = 8.0
velocidad = ((int)a)/b; // c = 0/0.1 = 0.0

2.6 ESTRUCTURAS DE CONTROL


ESTRUCTURAS CONDICIONALES

Las condiciones son ingredientes comunes de un programa. Las condiciones permiten ejecutar una o varias

sentencias dependiendo de validez de una expresin. En otras palabras, Si se cumple la condicin (...), se

debe hacer (...). De lo contrario, si la condicin no se cumple, se debe hacer (...). Los operandos

condicionales if-else y switch se utilizan en las operaciones condicionales. Una sentencia condicional puede

ser seguida por una sola sentencia o por un bloque de sentencias a ser ejecutadas.
OPERADOR CONDICIONAL if-else

El operador if se puede utilizar solo o asociado al operador else (if-else).

Ejemplo del operador if:


if(expresin) operacin;

Si el resultado de la expresin encerrada entre parntesis es verdadero (distinto de 0) la operacin se realiza

y el programa contina con la ejecucin. Si el resultado de la expresin es falso (0), la operacin no se realiza

y el programa contina inmediatamente con la ejecucin.

Como hemos mencionado, la otra forma combina tanto el operador if como el else:

if(expresin) operacin1 else operacin2;

Si el resultado de la expresin es verdadero (distinto de 0), se realiza operacin1, de lo contrario se realiza

la operacin2. Despus de realizar una de las operaciones, el programa contina con la ejecucin.

La sentencia if-else se parece a lo siguiente:

if(expresin)
operacin1
else
operacin2

Si operacin1 u operacin2 est compuesta, escriba una lista de sentencias encerradas entre llaves. Por

ejemplo:

if(expresin) {
... //
... // operacin1
...} //
else
operacin2

El operador if-else se puede sustituir por el operador condicional '?:':

(expresin1)? expresin2 : expresin3

Si el valor de la expresin1 es distinto de 0 (verdadero), el resultado de la expresin entera ser equivalente al

resultado obtenido de laexpresin2. De lo contrario, si la expresin1 es 0 (falso), el resultado de la expresin

entera ser equivalente al resultado obtenido de laexpresin3. Por ejemplo:

maximum = (a>b)? a : b // A la variable maximum se le asigna el


// valor de la variable mayor(a o b)

Operador Switch

A diferencia de la sentencia if-else que selecciona entre dos opciones en el programa, el

operador switch permite elegir entre varias opciones. La sintaxis de la sentencia switch es:
switch (selector) // Selector es de tipo char o int
{
case constante1:
operacin1 // El grupo de operadores que se ejecutan si
... // el selector y la constante1 son equivalentes

break;

case constante2:

operacin2 // El grupo de operadores se ejecuta si


... // el selector y la constante2 son equivalentes

break;
...
default:

operacin_esperada // El grupo de operadores que se ejecuta si


... // ninguna constante equivale al selector
break;
}

La operacin switch se ejecuta de la siguiente manera: primero se ejecuta el selector y se compara con la

constante1. Si coinciden, las sentencias que pertenecen a ese bloque se ejecutan hasta llegar a la palabra

clave break o hasta el final de la operacin switch. Si no coinciden, el selector se compara con la constante2.

Si coinciden, las sentencias que pertenecen a ese bloque se ejecutan hasta llegar a la palabra clave break

etc. Si el selector no coincide con ninguna constante, se ejecutarn las operaciones que siguen al operador

default.

Tambin es posible comparar una expresin con un grupo de constantes. Si coincide con alguna de ellas, se

ejecutarn las operaciones apropiadas:

switch (das) // La variable das representa un da de la semana.


{ // Es necesario determinar si es un da laborable o no lo es
case1:case2:case3:case4:case5: LCD_message = 'Da laborable'; break;
case6:case7: LCD_message = 'Fin de semana'; break;
default:LCD_message_1 = 'Elija un da de la semana'; break;
}

La palabra clave de C break se puede utilizar en cualquier tipo de bloques. Al utilizar break, es posible salir

de un bloque aunque la condicin para su final no se haya cumplido. Se puede utilizar para terminar un bucle

infinito, o para forzar un bucle a terminar antes de lo normal.


BUCLES

A menudo es necesario repetir una cierta operacin un par de veces en el programa. Un conjunto de

comandos que se repiten es denominado un bucle de programa. Cuntas veces se ejecutar, es decir cunto

tiempo el programa se quedar en el bucle, depende de las condiciones de salir del bucle.
Bucle While

El bucle while se parece a lo siguiente:

while(expresin){
comandos
...
}

Los comandos se ejecutan repetidamente (el programa se queda en el bucle) hasta que la expresin llegue a

ser falsa. Si la expresin es falsa en la entrada del bucle, entonces el bucle no se ejecutar y el programa

continuar desde el fin del bucle while.

Un tipo especial del bucle de programa es un bucle infinito. Se forma si la condicin sigue sin cambios dentro

del bucle. La ejecucin es simple en este caso ya que el resultado entre llaves es siempre verdadero
(1=verdadero), lo que significa que el programa se queda en el mismo bucle:

while(1){ // En vez de "while(1)", se puede escribir "while(true)"


... // Expresiones encerradas entre llaves se ejecutarn
... // repetidamente (bucle infinito)
}

Bucle For

El bucle for se parece a lo siguiente:

for(expresin_inicial; expresin_de_condicin; cambiar_expresin) {


operaciones
...
}

La ejecucin de esta secuencia de programa es similar al bucle while, salvo que en este caso el proceso de

especificar el valor inicial (inicializacin) se realice en la declaracin. La expresin_ inicial especifica la

variable inicial del bucle, que ms tarde se compara con la expresin_ de_condicin antes de entrar al bucle.

Las operaciones dentro del bucle se ejecutan repetidamente y despus de cada iteracin el valor de la

expresin_inicial se incrementa de acuerdo con la regla cambiar_expresin. La iteracin contina hasta que la

expresin_de_condicin llegue a ser falsa.

for(k=0; k<5; k++) // La variable k se incrementa 5 veces (de 1 a 4) y


operacin // cada vez se repite la expresin operacin
...

La operacin se ejecutar cinco veces. Luego, al comprobar se valida que la expresin k<5 sea falsa

(despus de 5 iteraciones k=5) y el programa saldr del bucle for.

Bucle Do-while
El bucle do-while se parece a lo siguiente:

do
operacin
while (cambiar_condicin);

La expresin cambiar_condicin se ejecuta al final del bucle, que significa que operacin se ejecuta como

mnimo una vez sin reparar en que si la condicin es verdadera o falsa. Si el resultado es distinto de 0

(verdadero), el procedimiento se repite.

Todos los siguientes ejemplos son equivalentes. Esta parte del cdigo visualiza "hello" en un LCD 10 veces

con un retardo de un segundo. Note que en este ejemplo se utilizan funciones predefinidas, que se

encuentran en las libreras del compilador mikroC PRO for PIC. No obstante le aconsejamos que no trate de
entenderlas en detalle. Su comportamiento general dentro del bucle se explica por medio de los comentarios.

i = 0; // Inicializacin del contador

while (i<10) { // Condicin


Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD
Delay_ms(1000); // Retardo de 1000 ms
Lcd_Cmd(_LCD_CLEAR); // Borrar el LCD
Delay_ms(500); // Retardo de 500ms
i++; // Contador se incrementa
}
for(i=0; i<10; i++) { // Inicializacin, condicin, incremento
Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD
Delay_ms(1000); // Retardo de 1000 ms
Lcd_Cmd(_LCD_CLEAR); // Borrar el LCD
Delay_ms(500); // Retardo de 500ms
}
i = 0; // Inicializacin del contador
do {
Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD
Delay_ms(1000); // Retardo de 1000 ms
Lcd_Cmd(_LCD_CLEAR); // Borrar LCD
Delay_ms(500); // Retardo de 500ms
i++; // Contador se incrementa
}
while (i<10); // Condicin

SENTENCIAS DE SALTO
SENTENCIA BREAK

A veces es necesario detener y salir de un bucle dentro de su cuerpo. La sentencia break se puede utilizar

dentro de cualquier bucle (while, for, do while) y en las sentencias switch tambin. En stas la sentencia break

se utiliza para salir de las sentencias switch si la condicin case es verdadera. En este ejemplo, Esperar est

parpadeando en la pantalla LCD hasta que el programa detecte un uno lgico en el pin 0 del puerto PORTA.
while(1){ // Bucle infinito
if(PORTA.F0 == 1) // Probar si el estado lgico del pin 0 del
puerto
break; // PORTA es 1; si equivale, salir del bucle
Lcd_Out(1,3,"Esperar"); // Visualizar Esperar en el LCD
Delay_ms(1000); // Retardo de 1000 ms
Lcd_Cmd(_LCD_CLEAR); // Borrar LCD
Delay_ms(500); // Retardo de 500ms
}

SENTENCIA CONTINUE

La sentencia continue colocada dentro de un bucle se utiliza para saltar una iteracin. A diferencia de la

sentencia break, el programa se queda dentro del bucle y las iteraciones continan.

// Si x=7, puede ocurrir una divisin por 0.


// continue se utiliza aqu para evitar esta situacin.
x=1;
while (x<=10) {
if (x == 7) { // saltar x=7 para evitar divisin por 0
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,3,"Division by 0");
Delay_ms(1000);
x++;
continue; // Despus de esta lnea, saltar a la sentencia while con
x=8
}

a = 1/(x-7); // Esta divisin generar un error si x=7

/* Muchas operaciones pueden ocurrir aqu */

Lcd_Out(1,3,"Division is OK"); // Poner este mensaje en el LCD


Delay_ms(1000);
x++;
}

SENTENCIA GOTO

La sentencia goto le permite hacer un salto absoluto al otro punto en el programa. Esta caracterstica se debe

utilizar con precaucin ya que su ejecucin puede causar un salto incondicional sin hacer caso a todos los

tipos de limitaciones de anidacin. El punto destino es identificado por una etiqueta, utilizada como un

argumento para la sentencia goto. Una etiqueta consiste en un identificador vlido seguido por un colon (:).

...

if(CO2_sensor) goto aire acondicionado; // Si se consta que el valor


... // de la variable CO2_sensor =1
// hacer salto a la lnea de
programa
// Aire acondicionado
...
Aire acondicionado: // Desde aqu sigue la parte del
cdigo que se ejecutar
// en caso de una concentracin
de CO2 demasiado alta
... // en el ambiente

2.7 TIPOS DE DATOS AVANZADOS


MATRICES

Una matriz es una lista de elementos del mismo tipo colocados en localidades de memoria contiguas. Cada

elemento es referenciado por un ndice. Para declarar una matriz, es necesario especificar el tipo de sus

elementos (denominado tipo de matriz), su nombre y el nmero de sus elementos encerrados entre corchetes.

Todos los elementos de una matriz tienen el mismo tipo.

tipo_de_matriz nombre_de_matriz [n_de_elementos];

Los elementos de una matriz se identifican por su posicin. En C, el ndice va desde 0 (el primer elemento de

una matriz) a N-1 (N es el nmero de elementos contenidos en una matriz). El compilador tiene que saber

cuntas localidades de memoria debe alojar al declarar una matriz. El tamao de una matiz no puede ser una

variable. Por eso, se pueden utilizar dos mtodos:

// mtodo 1
int display [3]; // Declaracin de la matriz display capaz de contener 3
enteros
// mtodo 2
const DGITOS = 5;
char Matriz_nueva[DGITOS]; // Declaracin de la matriz Matriz_nueva
// capaz de contener 5 enteros

Una matriz se puede inicializar a la vez que se declara, o ms tarde en el programa. En ambos casos, este

paso se realiza al utilizar llaves:

int array_1[3] = {10,1,100};


Para leer o modificar un elemento de matriz del ejemplo anterior, basta con introducir su ndice encerrado

entre corchetes:

/* Se supone que a ha sido declarado anteriormente como un entero */

a = array_1[0]; // A la variable a se le asigna el valor del miembro de


matriz

// con ndice 0 (a = 10)


array_1[2] = 20; // Miembro de matriz array_1[2] es modificado (nuevo
valor es 20)

El siguiente programa cambia el orden de los elementos de una matriz. Note que el ndice se puede expresar

mediante variables y operaciones bsicas.

void main() {
const MUESTRAS_DE_AGUA = 4; // Valor de la constante MUESTRAS_DE_AGUA
es 4
int i, temp; // Variables i y temp son de tipo int
int profunidad_de_sonda [MUESTRAS_DE_AGUA] = {24,25,1,1987};// Todos

// los miembros de la matriz profundidad


// de sonda son de tipo int

for(i=0;i<(MUESTRAS_DE_AGUA/2);i++){ // Bucle se ejecuta 2 veces


temp = profundiad_de_sonda [i]; // temp se utiliza para guardar
un valor
// temporalmente
profundiad_de_sonda [i] = profundiad_de_sonda [MUESTRAS_DE_AGUA-1-
i];
profundiad_de_sonda [MUESTRAS_DE_AGUA-1-i] = temp;
}

// Aqu tenemos: profundidad_de_sonda [MUESTRAS_DE_AGUA] =


{1987,1,25,24}
}

MATRICES BIDIMENSIONALES

Aparte de las matrices unidimensionales que se pueden interpretar como una lista de valores, el lenguaje C le

permite declarar matrices multidimensionales. En esta parte vamos a describir slo las matrices

bidimensionales, tambin denominadas tablas o matrices. Una matriz bidimensional se declara al especificar

el tipo de dato de matriz, el nombre de matriz y el tamao de cada dimensin.

tipo_de_matriz nombre_de_matriz [nmero_de_filas] [nmero_de_columnas];

En la declaracin de esta matriz nmero_de_filas y nmero_de_columnas representan el nmero de filas y

columnas en las que consiste una tabla, respectivamente. Vea la siguiente matriz bidimensional:
int Tabla [3][4]; // Tabla se define de modo que tenga 3 filas y 4
columnas

Esta matriz se puede representar en la forma de una tabla.

tabla[0][0] tabla[0][1] tabla[0][2] tabla[0][3]

tabla[1][0] tabla[1][1] tabla[1][2] tabla[1][3]

tabla[2][0] tabla[2][1] tabla[2][2] tabla[2][3]

Similar a las matrices unidimesionales, es posible asignar los valores a los elementos de una tabla en la lnea

de declaracin. La asignacin debe ser realizada lnea a lnea como en el siguiente ejemplo. Como hemos

visto anteriormente, esta matriz tiene dos filas y tres columnas:

int Tabla [2][3]= { {3,42,1},{7,7,19} };

La matriz anterior se puede representar tambin en la forma de una tabla de valores:

3 42 1

7 7 19

PUNTEROS

Un puntero es una variable destinada a recibir una direccin. Un puntero apunta a una localidad de memoria,

referenciada por una direccin. En C, la direccin de un objeto se puede obtener por medio un operador

unitario &. Para acceder al contenido de la memoria en una direccin especfica (tambin llamado objeto

apuntado), se utiliza un operador de indireccin (*).

'&n' es la direccin de la localidad de memoria 'n'.

'*(&n)' es el contenido de la direccin '(&n)', o sea de 'n'.

Para declarar un puntero, se debe que especificar el tipo de la variable apuntada:

tipo_de_variable *puntero;
En esta etapa, el puntero mi_puntero apunta al valor almacenado en esta localidad de memoria, o sea, a un

valor desconocido. As que, una inicializacin es muy recomendable:

puntero = &variable;

Ahora, puntero contiene la direccin de variable.

Para acceder al contenido de la variable apuntada, debe utilizar *. El siguiente ejemplo muestra el contenido

de memoria dependiendo de la accin realizada por medio del puntero.

Los punteros son muy tiles para manejar las matrices. En este caso, un puntero se utilizar para apuntar al

primer elemento de una matriz. Debido al hecho de que es posible realizar operaciones bsicas sobre los

punteros (aritmtica de punteros), es fcil manejar los elementos de una matriz.

Fjese en la diferencia entre *v+1 y *(v+1) en el siguiente ejemplo:

short int voltio[3] = {0,5,10};


short int *v;
v = &(voltio[0]); // v contiene la direccin de voltio[0]
*(v+1) = 2; // voltio[1] = 2
voltio[2] = *v+1; // tab[2] = 1 (tab[0] + 1)
*(v+2) = *(v+1); // voltio[2] = 2
v++; // v contiene la direccin de voltio[1]
*v = 1; // voltio[1] = 1

Los punteros tambin pueden ser declarados con el prefijo const. En este caso, su valor
no puede ser modificado despus de la inicializacin, similar a una constante.
A diferencia de C, el mikroC no admite alojamiento dinmico.
ESTRUCTURAS
Ya hemos visto cmo agrupar los elementos dentro de matrices. No obstante, al utilizar este mtodo todos los

elementos deben ser del mismo tipo. Al utilizar estructuras, es posible agrupar diferentes tipos de variables

bajo el mismo nombre. Las variables dentro de una estructura se le denominan los miembros de la estructura.

Las estructuras de datos se declaran al utilizar la siguiente sintaxis:

struct nombre_de_estructura {
tipo1_de_miembro1 miembro1;
tipo2_de_miembro2 miembro2;
tipo3_de_miembro3 miembro3;
..
};

No es posible inicializar variables dentro de la declaracin de la estructura de datos:

struct generador {
int voltaje;
char corriente;
};

Entonces, podr definir los objetos denominados turbina en el cdigo. A cada uno de estos tres objetos

(turbinas) se le asignan las variables corriente y voltaje.

struct generadores turbina_1, turbina_2, turbina_3;

Para acceder a las variables, es preciso utilizar el operador '.'

turbina_3.voltaje = 150;

turbina_3.corriente = 12;

Por supuesto, igual que al utilizar los punteros, todava se le permite realizar operaciones por medio de

operadores y sentencias definidos en las partes anteriores.

Si est familiarizado con el lenguaje C, recuerde que mikroC no admite la inicializacin de los miembros de

estructura por medio de las llaves. Por ejemplo, conjunto_1 ={15,m}; devuelve un error en mikroC.
2.8 FUNCIONES

Una funcin es una subrutina que contiene una lista de sentencias a realizar. La idea principal es dividir un

programa en varias partes utilizando estas funciones para resolver el problema inicial con ms facilidad.

Adems, las funciones nos permiten utilizar las destrezas y el conocimiento de otros programadores. Una

funcin se ejecuta cada vez que se llame dentro de otra funcin. En C, un programa contiene como mnimo
una funcin, la funcin main(), aunque el nmero de funciones es normalmente mayor. Al utilizar funciones el

cdigo se hace ms corto ya que es posible llamar una funcin tantas veces como se necesite. En C, el

cdigo normalmente consiste en muchas funciones. No obstante, en caso de que su programa sea muy corto

y simple, puede escribir todas las sentencias dentro de la funcin principal.

FUNCIN PRINCIPAL

La funcin principal main() es una funcin particular puesto que es la que se ejecuta al iniciar el programa.

Adems, el programa termina una vez completada la ejecucin de esta funcin. El compilador reconoce

automticamente esta funcin y no es posible llamarla por otra funcin. La sintaxis de esta funcin es la

siguiente:

void main (void) {

/* el primer 'void' significa que main no devuelve ningn valor. El


segundo
'void' significa que no recibe ningn valor. Note que el compilador
tambin admite la siguiente sintaxis: 'main()' o 'void main()' o
'main(void)' */

..

/* --- Introduzca su programa aqu --- */

.
};

Esto significa que f es una funcin que recibe un nmero real x como parmetro y devuelve 2*x-y.

La misma funcin en C se parece a lo siguiente:

float f (float x, float y) // variables flotantes x y y se pueden


utilizar en f
{
float r; // declarar r para almacenar el resultado
r = 2*x - y; // almacenar el resultado del clculo en r
return r; // devolver el valor de r
}

Cada funcin debe ser declarada apropiadamente para poder interpretarla correctamente durante el proceso

de compilacin. La declaracin contiene los siguientes elementos:

Tipo de resultado (valor devuelto): tipo de dato del valor devuelto


Nombre de funcin: es un identificador que hace posible llamar a una funcin.
Declaracin de parmetros se parece a la declaracin de variable regular (por ejemplo:
float x). Cada parmetro consiste en una variable, constante, puntero o matriz, precedidos
por la etiqueta de tipo de dato. Se utilizan para pasar la informacin a la funcin al llamarla.
Los parmetros diferentes estn delimitados por comas.
Cuerpo de funcin: bloque de sentencias dentro de llaves
Una funcin se parece a lo siguiente:

tipo_de_resultado nombre_de_funcin (tipo argumento1, tipo


argumento2,...)
{
Sentencia;
Sentencia;
...
return ...
}

Note que una funcin no necesita parmetros (funcin main() por ejemplo), pero debe estar entre parntesis.
En caso contrario, el compilador malinterpretara la funcin. Para hacerlo ms claro, puede sustituir el espacio

en blanco encerrado entre parntesis por la palabra clave void: main (void).
VALOR DEVUELTO

Una funcin puede devolver un valor (esto no es obligatorio) por medio de la palabra clave return. Al llegar a

return, la funcin evala un valor (puede ser una expresin) y lo devuelve a la lnea de programa desde la que

fue llamada.

return r; // Devolver el valor contenido en r


return (2*x - y); // Devolver el valor de la expresin 2*x-y

Una funcin no puede devolver ms de un valor, pero puede devolver un puntero o una estructura. Tenga

cuidado al utilizar matrices y punteros. El siguiente ejemplo es un error tpico:

int *reverse(int *tab) // Esta funcin debe devolver una matriz r


{ // cuyo contenido est en orden inverso con
// respecto a la matriz tab
int r[DIM]; // Declaracin de una nueva matriz denominada r
int i;
for(i=0;i<DIM;i++) // Bucle que copia el contenido de tab en r
r[i] = tab[DIM-1-i]; // al invertir el orden

return r; // Devolver el valor r


}

En realidad, el compilador reserva memoria para el almacenamiento de variables de la funcin reverse slo

durante su ejecucin. Una vez completada la ejecucin de reverse, la localidad de memoria para la variable i o

para la matriz r ya no est reservada. Esto significa que la direccin que contiene los valores de i o r[] est

libre para introducir datos nuevos. Concretamente, la funcin devuelve slo el valor &r[0], as que slo el

primer elemento de la matriz tab ser almacenado en la memoria. Las dems localidades de memoria, tales
como &tab[1], &tab[2], etc. sern consideradas por el compilador como espacios en blanco, o sea, estarn

listas para recibir los nuevos valores.

Para escribir esta funcin es necesario pasar la matriz r [] como parmetro (vea la subseccin Pasar los

parmetros).

La funcin puede contener ms de una sentencia return. En este caso, al ejecutar la primera sentencia return,

la funcin devuelve el valor correspondiente y se detiene la ejecucin de la funcin.

float abs (float x, float y) // Devolver el valor absoluto de 2*x-y


{
if ((2*x - y) >= 0)
return (2*x - y);
else
return (-2*x + y);
}

Si la funcin no devuelve ningn valor, la palabra void debe ser utilizada como un tipo de resultado en la

declaracin. En este caso, la sentencia return no debe ser seguida por ninguna expresin. Puede ser omitida

como en el siguiente ejemplo:

void wait_1 (unsigned int a)


{
cnt ++; // Incremento de una variable global cnt
Delay_ms(a) ; // Ejecucin de la funcin Delay_ms
} // Note que Delay_ms no devuelve nada

DECLARAR PROTOTIPOS DE FUNCIONES

Para utilizar una funcin, el compilador debe ser consciente de su presencia en el programa. En la

programacin en C, los programadores normalmente primero escriben la funcin main() y luego las funciones

adicionales. Para avisar al compilador de la presencia de las funciones adicionales, se requiere declarar los

prototipos de funciones en el principio de programa antes de la funcinmain(). Un prototipo de funcin est

compuesto por:
tipo de resultado
nombre de funcin
tipos de parmetros
un punto y coma (;)
El prototipo de la funcin main no necesita ser declarado.

float f (float, float);


/* no es obligatorio escribir los nombres de los parmetros. Este
prototipo
informa al compilador: en el programa se utilizar la funcin f,
que utiliza dos parmetros de tipo float y devuelve el resultado del
tipo
float. */

LLAMAR UNA FUNCIN

Mientras una funcin es definida y su prototipo declarado, se puede utilizar en culquier parte de programa. Sin

embargo, como la funcinmain es 'raiz' del programa, no puede ser llamada de ninguna parte de programa.

Para ejecutar una funcin, es necesario escribir su nombre y los parmetros asociados. Vea los siguientes

ejemplos:

float resultado,a,b; // resultado,a,b,time deben coincidir con los tipos


// definidos
int time = 100; // en la declaracin de las funciones f y wait_1
a = 10.54;
b = 5.2;
resultado = f(a,b); // Ejecutar la funcin f por medio de los
parmetros a y b

// El valor devuelto se le asigna a la variable


resultado
pausa_1(tiempo); // Ejecutar la funcin pausa_1 por medio de la
variable tiempo
funcinX(); // Ejecutar la funcin funcinX (sin parmetros)

Cuando se llama una funcin, el programa salta a la funcin llamada, la ejecuta, despus vuelve a la lnea

desde la que fue llamada.

PASAR LOS PARMETROS

Al llamar una funcin, se le pasan los parmetros. En C existen dos formas diferentes para pasar parmetros

a una funcin.

El primer mtodo, denominado paso por valor, es el ms fcil. En este caso, los parmetros se pueden

considerar como variables locales de la funcin. Cuando se llama una funcin, el valor de cada parmetro se

copia a un nuevo espacio de memoria reservado durante la ejecucin de la funcin. Como los parmetros se

consideran como variables locales por el compilador, sus valores pueden ser modificados dentro de la funcin,

pero sus modificaciones no se quedan en la memoria una vez completada la ejecucin de la funcin.

Tenga en cuenta de que la funcin devuelve un valor, y no una variable. Adems, se crean copias de los

valores de los parmetros, por lo que sus nombres en la funcin f pueden ser diferentes de los parmetros

utilizados en la main(). La mayor desventaja del paso por el valor es que la nica interaccin que una funcin
tiene con el resto del programa es el valor devuelto de un solo resultado (o la modificacin de las variables

globales).

El otro mtodo, denominado 'paso por direccin' le permite sobrepasar este problema. En vez de enviar el

valor de una variable al llamar a funcin, se debe enviar la direccin de memoria del valor. Entonces, la

funcin llamada ser capaz de modificar el contenido de esta localidad de memoria.

// Funcin 'sort'ordena los miembros de la matriz por valor ascendente


// y devuelve el miembro con mximo valor

int sort(int *); // Prototipo de funcin


const SIZE = 5; // Nmero de miembros a ordenar

void main() {
int maximum, input[SIZE] = {5,10,3,12,0}; // Declaracin de variables
en la matriz
maximum = sort(input); // Llamar a funcin y
asignarle el mximo
// valor a la variable maximum
}

int sort(int *sequence) {


int i, temp, permut; // Declaracin de variables
permut = 1; // Bandera de bit indica que se ha hecho una
permutacin

while(permut!=0) { // Quedarse en el bucle hasta reinicar la


bandera
permut = 0; // Bandera reiniciada
for(i=0;i<SIZE-1;i++) { // Comparar y oredenar los miembros de la
// matriz (dos a dos)

if(sequence [i] > sequence[i+1]){


temp = sequence [i];
sequence[i] = sequence[i+1];
sequence[i+1] = temp;
permut = 1; // Se ha hecho una permutacin, bandera de bit
//se pone a uno
}
}
}

return sequence[SIZE-1]; // Devolver el valor del ltimo miembro

} // que es al mismo tiempo el miembro con el mximo valor

En este ejemplo, por medio de una funcin se realizan dos operaciones: ordena los miembros de la matriz por

valor asdendente y devuelve el mximo valor.

Para utilizar una matriz en una funcin es necesario asignar la direccin a la matriz (o a su primer miembro).

Vea el siguiente ejemplo:


float mtodo_1(int[]); // Declaracin de prototipo de la
funcin Mtodo_1
float mtodo_2(int*); // Declaracin de prototipo de la
funcin Mtodo_2

const NMERO_DE_MEDICIONES = 7; // Nmero de los miembros de la matriz

void main()
{
double promedio1, promedio2; // Declaracin de las variables promedio1
// y promedio2
int voltaje [NMERO_DE_MEDICIONES] = {7,8,3,5,6,1,9}; // Declaracin
de la
// matriz
voltaje
promedio1 = mtodo_1(&voltaje[0]); // Parmetro de la funcin es la
direccin
// del primer miembro
promedio2 = mtodo_2(voltaje); // Parmetro de la funcin es la
direccin de
// la matriz
}

//
float mtodo_1(int voltaje[]) // Inicio de la funcin mtodo_1
{
int i, suma; // Declaracin de las variables
locales i y suma

for(i=0;i<NMERO_DE_MEDICIONES;i++) // Clculo del valor promedio de


voltaje
suma += voltaje[i]; // Es posible utilizar
*(voltaje+i)en vez de voltaje[i]

return(suma/NMERO_DE_MEDICIONES);
}

//
float mtodo_2 (int *voltaje) //Inicio de la funcin mtodo_2
{
int i, suma; // Declaracin de las variables locales i
y suma

for(i=0;i<NMERO_DE_MEDICIONES;i++) // Clculo del valor promedio de


voltaje
suma += *(voltaje+i); // Es posible utilizar voltaje[i]
en vez de *(voltaje+i)

return(suma/NMERO_DE_MEDICIONES);
}

Las funciones 'mtodo_1' y 'mtodo_2' son completamente equivalentes. Las dos devuelven el valor promedio

de la matriz 'voltaje[]'. Despus de declararla, la direccin del primer miembro se puede escribir como 'voltaje'

o '&voltaje[0]'.
2.9 CARACTERSTICAS PRINCIPALES DEL PREPROCESADOR

El preprocesador es un programa que procesa el cdigo antes de que pase por el compilador. Funciona bajo

el control de las lneas de comando del preprocesador denominadas directivas. Las directivas del

preprocesador se colocan en el cdigo fuente, normalmente en el principio del archivo. Antes de pasar por el

compilador, el cdigo fuente se examina por el preprocesador que detecta y ejecuta todas las directivas del

preprocesador. Las directivas del preprocesador siguen a una regla de la sintaxis especial, empiezan por un

smbolo # y no requieren ningn punto y coma al final (;).

DIRECTIVAS DEL PREPROCESADOR

La siguiente tabla contiene un conjunto de directivas del preprocesador frecuentemente utilizadas:

Las directivas del preprocesador se pueden dividir en tres categoras:

D I R E C T I VA S FUNCIONES

#include Define una sustitucin de macro

#undef Quita una definicin de nombre de macro

#define Especifica un archivo a ser incluido

#ifdef Prueba para definicin de macro

#endif Especificar el final de #if

#ifndef Prueba si una macro no est definida

#if Prueba las condiciones de compilar

#else Especifica alternativas cuando la prueba de #if falla

#elif Especifica alternativas cuando ms de dos condiciones se necesitan

Definiciones de macro
Inclusiones de archivos
Control de compilacin
Ahora, vamos a presentar slo las directivas del preprocesador utilizadas con ms frecuencia. Sin embargo,

no es necesario saber todas ellas para programar microcontroladores. Slo tenga en cuenta que el

preprocesador es una herramienta muy poderosa para los programadores avanzados en C, especialmente

para el control de compilacin.


DIRECTIVAS DEL PREPROCESADOR PARA DEFINIR MACROS

Por medio de los macros es posible definir las constantes y ejecutar funciones bsicas. Una sustitucin de

macro es un proceso en el que un identificador del programa se sustituye por una cadena predefinida. El

preprocesador sustituye cada ocurrencia del identificador en el cdigo fuente por una cadena. Despus de la

sustitucin, el cdigo ser compilado normalmente.

Esto significa que el cdigo sustituido debe respetar la sintaxis del mikroC. La accin se realiza por medio de

la directiva '#define'.

#define PI 3.14159 // Sustitucin simple, PI ser sustituido por


// el valor 3.14159 en todas las partes del programa

Tambin puede utilizar los parmetros para realizar substituciones ms complejas:

#define VOLUMEN (D,H) (((D/2)*(D/2)*PI))*H // Macro con parmetros

Entonces, en el cdigo, la siguiente sentencia:

Tanque_1 = VOLUMEN (Dimetro,altura);

ser sustituida por:

Tanque_1 = (((Dimetro/2)*(Dimetro/2)*PI)*altura;

Por medio de la directiva #undef es posible quitar una definicin de nombre de macro. As se especifica que la

substitucin que se ha definido anteriormente ya no va ocurrir en el siguiente cdigo. Esto es til cuando usted

quiere restringir la definicin slo a una parte particular del programa.

#undef TANQUE // Quitar la definicin del macro VOLUMEN

INCLUSIN DE ARCHIVOS

La directiva de preprocesador #include copia un archivo especfico en el cdigo fuente. El cdigo incluido

debe observar la sintaxis de C para ser compilado correctamente.

Hay dos formas de escribir estas directivas. En el primer ejemplo, slo el nombre de archivo se especifica, as

que el preprocesador lo buscar dentro del archivo include. En el segundo ejemplo, se especifica la ruta

entera, as que el archivo estar directamente incluido (este mtodo es ms rpido).


#include <nombre_de_archivo> // Se especifica slo el
nombre del archivo
#include "C:\Ruta\nombre_de_archivo.h" // Se especifica la localidad
// exacta del archivo

2.10 MIKROC PRO FOR PIC

Como ya hemos visto, hay varias divergencias entre los lenguajes mikroC y ANSI C. En este captulo vamos a

presentar las caractersticas especficas del mikroC con el propsito de facilitar la programacin de los

microcontroladores PIC.

ACCESO A LOS REGISTROS DE FUNCIONES ESPECIALES (SFR)

Como todos los microcontroladores, los de familia PIC tienen los registros de funciones especiales (SFR).
Para programar un PIC, es necesario acceder a estos registros (para leerlos o escribir en ellos). Al utilizar el

compilador mikroC PRO for PIC es posible de acceder a cualquier SFR del microcontrolador de cualquier

parte del cdigo (los SFR se consideran como variables globales) sin necesidad de declararlo anteriormente.

Los registros de funciones especiales se definen en un archivo externo e incluido dentro del compilador

(archivo .def). Este archivo contiene todos los SFR del microcontrolador PIC a programar.

TRISB = 0; // todos los pines del puerto PORTB se configuran como


salidas
PORTB = 0; // todos los pines del PORTB se ponen a 0

ACCESO A LOS BITS INDIVIDUALES

El compilador mikroC PRO for PIC le permite acceder a los bits individuales de variables de 8 bits por su

nombre o su posicin en byte:

INTCON.B0 = 0; // Poner a 0 el bit 0 del registro INTCON


ADCON0.F5 = 1; // Poner a 1 el bit 5 del registo ADCON0
INTCON.GIE = 0; // Poner a 0 el bit de interrupcin global (GIE)

Para acceder a un bit individual, se puede utilizar '.FX' as como '.BX' (X es un entero entre 0 y 7 que

representa la posicin de bit).

TIPO SBIT

Si quiere declarar una variable que corresponde a un bit de un SFR, hay que utilizar el tipo sbit. Una variable

de tipo sbit se comporta como un puntero y se debe declarar como una variable global:

sbit Botn_PARADA at PORTA.B7; // Botn_PARADA est definido


...
void main() { // Cualquier modificacin de Botn_PARADA
afectar a PORTA.B7
... // Cualquier modificacin de PORTA.B7
afectar a Botn_PARADA
}

En este ejemplo, El Botn_PARADA es una variable declarada por el usuario, mientras que PORTA.B7 (bit 7

del puerto PORTA) ser automticamente reconocido por el compilador.


TIPO BIT

El compilador mikroC PRO for PIC proporciona un tipo de datos bit que se puede utilizar para declarar

variables. No se puede utilizar en las listas de argumentos, punteros y los valores devueltos de funciones.

Adems, no es posible declarar e inicializar una variable de tipo bit en la misma lnea. El compilador determina

el bit en uno de los registros disponibles para almacenar las variables.

bit bf; // Variable de tipo bit vlida


bit *ptr; // Varibale de tipo bit invlida.
// No hay punteros a una variable de tipo bit
bit bg = 0; // ERROR ; declaracin con inicializacin no est permitida
bit bg;
bg = 0; // Declaracin e inicializacin vlidas

INSERTAR CDIGO ASM EN C

A veces el proceso de escribir un programa en C requiere las partes del cdigo escritas en ensamblador. Esto

permite ejecutar las partes complicadas del programa de una forma definida con precisin en un perodo de

tiempo exacto. Por ejemplo, cuando se necesita que los pulsos muy cortos (de unos microsegundos)

aparezcan peridicamente en un pin del microcontrolador. En tales casos la solucin ms simple sera utilizar

el cdigo ensamblador en la parte del programa que controla la duracin de pulsos.


Una o ms instrucciones en ensamblador estn insertadas en el programa escrito en C, utilizando el

comando asm:

asm
{
instrucciones en ensamblador
...
}

Los cdigos escritos en ensamblador pueden utilizar constantes y variables anteriormente definidos en C. Por

supuesto, como el programa entero est escrito en C, sus reglas se aplican al declarar estas constantes y

variables.

unsigned char maximum = 100; // Declarar variables: maximum = 100


asm
{ // Inicio del cdigo ensamblador
MOVF maximum,W // W = maximum = 100
...
} // Final del cdigo ensamblador

FUNCIN DE INTERRUPCIN

Una interrupcin detiene la ejecucin normal de un programa para ejecutar las operaciones especficas. Una

lista de sentencias a ejecutar debe estar escrita dentro de una funcin particular denominada interrupt(). La

sintaxis de una interrupcin en mikroC se parece a lo siguiente:

void interrupt() {
cnt++ ; // Al producirse una interrupcin
// la cnt se incrementa en 1
PIR1.TMR1IF = 0; // Poner a 0 el bit TMR1IF
}

A diferencia de las funciones estndar, no es necesario declarar el prototipo de la funcin interrupt(). Adems,

como la ejecucin de esta funcin no forma parte de la ejecucin de programa regular, no se debe llamar de

ninguna parte de programa (se ejecutar automticamente dependiendo de las condiciones que el usuario ha

definido en el programa). En el siguiente captulo vamos a dar una clara explicacin de la ejecucin y

definicin de subrutinas de interrupcin.


LIBRERAS

Usted probablemente ha notado que en los ejemplos anteriores hemos utilizado algunas funciones como son

'Delay_ms', 'LCD_out', 'LCD_cmd' etc. Estas funciones estn definidas en las libreras contenidas en el

compilador mikroC.

Una librera representa un cdigo compilado, anteriormente escrito en mikroC, que contiene un conjunto de

variables y funciones. Cada librera tiene un propsito especfico. Por ejemplo, la librera LCD contiene
funciones de visualizacin de la pantalla LCD, mientras queC_math proporciona algunas funciones

matemticas.

Antes de utilizar alguna de ellas en el programa, es necesario comunicrselo al compilador al marcarlas en la

lista de las libreras del compilador existentes. Si el compilador encuentra una funcin desconocida durante la

ejecucin de programa, primero va a buscar su declaracin en las libreras marcadas.

Aparte de las libreras existentes, es posible crear las libreras y luego utilizarlas en el programa. El

procedimiento de cmo crear libreras se describe en detalles en Help (Ayuda) del compilador.

El compilador mikroC incluye tres tipos de libreras:

- libreras ANSI C estndar:

LIBRARA DESCRIPCIN

ANSI C Ctype Library Utilizada principalmente para probar o para convertir los datos

ANSI C Math Library Utilizada para las operaciones matemticas de punto flotante

ANSI C Stdlib Library Contiene las funciones de libreras estndar

ANSI C String Library Utilizada para realizar las operaciones de cadenas y de manipulacin de memoria

- libreras miscelneas:

LIBRARA DESCRIPCIN

Button Library Utilizada para desarrollar los proyectos

Conversion Library Utilizada para la conversin de tipos de datos


Sprint Library Utilizada para formatear los datos con facilidad

PrintOut Library Utilizada para formatear los datos e imprimirlos

Time Library Utilizada para clculos de tiempo (formato UNIX time)

Trigonometry Library Utilizada para la implementacin de funciones trigonomtricas fundamentales

Setjmp Library Utilizada para los saltos de programa

- libreras para el hardware:

LIBRARA DESCRIPCIN

ADC Library Utilizada para el funcionamiento del convertidor A/D

CAN Library Utilizada para las operaciones con el mdulo CAN

CANSPI Library Utilizada para las operaciones con el mdulo CAN externo (MCP2515 o MCP251

Compact Flash Library Utilizada para las operaciones con las tarjetas de memoria Compact Flash

EEPROM Library Utilizada para las operaciones con la memoria EEPROM incorporada

EthernetPIC18FxxJ60 Library Utilizada para las operaciones con el mdulo Ethernet incorporado

Flash Memory Library Utilizada para las operaciones con la memoria Flash incorporada

Graphic Lcd Library Utilizada para las operaciones con el mdulo LCD grfico con resolucin 128x6

I2C Library Utilizada para las operaciones con el mdulo de comunicacin serial I2C incorpo

Keypad Library Utilizada para las operaciones con el teclado (botones de presin 4x4)

Lcd Library Utilizada para las operaciones con el LCD (de 2x16 caracteres)

Manchester Code Library Utilizada para la comunicacin utilizando el cdigo Manchester

Multi Media Card Library Utilizada para las operaciones con las tarjetas multimedia MMC flash

One Wire Library Utilizada para las operaciones con los circuitos utilizando la comunicacin serial On

Port Expander Library Utilizada para las operaciones con el extensor de puertos MCP23S17
PS/2 Library Utilizada para las operaciones con el teclado estndar PS/2

PWM Library Utilizada para las operaciones con el mdulo PWM incorporado

RS-485 Library Utilizada para las operaciones con los mdulos utilizando la comunicacin serial R

Software I2C Library Utilizada para simular la comunicacin I2C con software

Software SPI Library Utilizada para simular la comunicacin SPI con software

Software UART Library Utilizada para simular la comunicacin UART con software

Sound Library Utilizada para generar las seales de audio

SPI Library Utilizada para las operaciones con el mdulo SPI incorporado

SPI Ethernet Library Utilizada para la comunicacin SPI con el mdulo ETHERNET (ENC28J60)

SPI Graphic Lcd Library Utilizada para la comunicacin SPI de 4 bits con el LCD grfico

SPI LCD Library Utilizada para la comunicacin SPI de 4 bits con el LCD (de 2x16 caracteres)

SPI Lcd8 Library Utilizada para la comunicacin SPI de 8 bits con el LCD

SPI T6963C Graphic Lcd Library Utilizada para la comunicacin SPI con el LCD grfico

UART Library Utilizada para las operaciones con el mdulo UART incorporado

USB Hid Library Utilizada para las operaciones con el mdulo USB incorporado

2.11 PROGRAMAR LOS PIC UTILIZANDO MIKROC PRO FOR PIC

En las secciones anteriores hemos presentado el lenguaje mikroC, especialmente diseado para programar

los PIC. Ahora, lo que hemos revisado es suficiente para empezar a programar, es hora de presentar el

software que utilizar para desarrollar y editar los proyectos. Este software se le denomina Entorno de

desarrollo integrado (Integrated Developement Environment - IDE) e incluye todas las herramientas

necesarias para desarrollar los proyectos (editor, depurador etc.). Por extensin, IDE es a veces llamado

compilador. En esta seccin le ensearemos lo bsico que debe saber para empezar a desarrollar su primer

proyecto en mikroC utilizando el IDE del compilador mikroC PRO for PIC.

Aparte de todas las caractersticas comunes de cualquier IDE, mikroC PRO for PIC contiene las informaciones

de arquitectura de los microcontroladores PIC (registros, mdulos de memoria, funcionamiento de circuitos

particulares etc.) para compilar y generar un archivo legible por un microcontrolador PIC. Adems, incluye las

herramientas especficas para programar los microcontroladores PIC.


El proceso de crear y ejecutar un proyecto contiene los siguientes pasos:

1. Crear un proyecto (nombre de proyecto, configuracin de proyecto, dependencias entre


archivos)
2. Editar un programa
3. Compilar el programa y correccin de errores
4. Depurar (ejecutar el programa paso a paso para asegurarse de que se ejecutan las
operaciones deseadas).
5. Programar un microcontrolador (cargar el archivo .hex generado por el compilador en el
microcontrolador utilizando el programador PICflash).
INSTALAR MIKROC PRO FOR PIC

Antes que nada, usted debe instalar el compilador (con su IDE) en la PC. La instalacin del mikroC PRO for

PIC es similar a la instalacin de cualquier programa en Windows. Todo el procedimiento se lleva a cabo por

medio de los wizards (asistentes de instalacin):

Basta con seguir las instrucciones y pulsar sobre Next, OK, Next, Next... En general, es el mismo

procedimiento menos la ltima opcin: 'Do you want to install PICFLASH v7.11 programmer?'. Para qu sirve

este software? De eso vamos a hablar ms tarde. Por ahora, basta con saber que es un software autnomo

utilizado para cargar el programa en el microcontrolador.

Una vez ms: Next, OK, Next, Next...


Una vez completada la instalacin del PICflash, el sistema operativo le preguntar a instalar otro programa

similar, un software para programar un grupo especial de los microcontroladores PIC que funcionan en modo

de bajo consumo (3.3 V). Salte este paso...

El ltimo paso - la instalacin del controlador (driver)!

Pulse sobre Yes.

Un controlador es un programa que permite al sistema operativo comunicar con un perifrico. En este caso,

este dispositivo es el programador (hardware) del sistema de desarrollo.


El controlador a instalar depende del sistema operativo utilizado. Seleccione el controlador correspondiente al

SO (sistema operativo) utilizado (por medio de abrir la carpeta correspondiente) e inicie la instalacin. Otra

vez, Next, OK, Next, Next... Bueno, todo est instalado para iniciar a programar!

CARACTERSTICAS PRINCIPALES DEL MIKROC PRO FOR PIC


Al iniciar el IDE del compilador mikroC PRO for PIC por primera vez, aparecer una ventana como se muestra

a continuacin:

Desgraciadamente, una descripcin detallada de todas las opciones disponibles de este IDE nos tomara

mucho tiempo. Por eso vamos a describir slo lo ms importante del compilador mikroC PRO for PIC. De

todos modos, para obtener ms informacion presione el botn de Ayuda (Help) [F1].

MANEJAR LOS PROYECTOS

Antes de empezar a escribir el cdigo, usted debe crear un proyecto. Un programa escrito en el

compilador mikroC PRO for PIC no es un archivo fuente autnomo, sino que forma parte de un proyecto que

incluye un cdigo hex, un cdigo ensamblador, cabecera y otros archivos. Algunos de ellos se requieren para

compilar el programa, mientras que otros se crean durante el proceso de compilacin. Un archivo con

extensin .mcppi le permite abrir cualquiera de estos proyectos.

Para crear un proyecto, basta con seleccionar la opcin Project/New Project, y un wizard aparecer

automticamente. Qu hacer entonces? Siga las instrucciones...


PROJECT MANAGER (ADMINISTRADOR DEL PROYECTO)

Una vez creado el proyecto, es posible manejar todos los archivos que contiene al utilizar la ventana Project

Manager. Basta con pulsar con el botn derecho del ratn sobre una carpeta y seleccionar la opcin que

necesita para su proyecto.

PROJECT SETTINGS (CONFIGURACIN DE PROYECTOS)

Al compilar un proyecto, el compilador genera el archivo .hex que se cargar en el microcontrolador. Estos

archivos sern diferentes lo que depende del tipo del microcontrolador as como del propsito de la

compilacin. Por esta razn es necesario ajustar algunos parmetros de proyectos utilizando la

ventana Project Settings.

Device (dispositivo):
Al seleccionar el tipo de microcontrolador a utilizar permite al compilador extraer el archivo de definicin

(archivo .def) asociado. El archivo de definicin de un microcontrolador contiene las informaciones especficas

de sus registros SFR, de sus direcciones de memoria y algunas variables de programacin especficas a ese

tipo del microcontrolador. Es obligatorio crear un archivo .hex compatible.

Oscillator (oscilador):

Se debe especificar la velocidad de operacin del microcontrolador. Por supuesto, este valor depende del

oscilador utilizado. El compilador la necesita para compilar rutinas, lo que requiere informacin del tiempo (por

ejemplo, la funcin Delay_ms). Ms tarde, el programador necesitar esta informacin tambin. La velocidad

de operacin se configura de modo que permita al oscilador interno del microcontrolador funcionar a una

frecuencia seleccionada.

Build/Debugger Type:

Todo el proceso de compilar (building) est compuesto por anlisis sintctico (parsing), compilar, enlazar

(linking) y generar los archivos .hex. El tipo de compilacin le permite ajustar el modo de compilacin.

Dependiendo del modo seleccionado, difieren los archivos generados a cargar en el microcontrolador.

Release: Al elegir esta opcin , el compilador no puede afectar ms a la ejecucin de programa despus de la

compilacin. El programa a cargar en el microcontrolador no ser modificado de ninguna manera.

ICD debug: Al elegir esta opcin, una vez completado el proceso de la compilacin y cargado el programa en

la memoria del microcontrolador, el compilador se queda conectado al microcontrolador por medio del cable

USB y el programador, y todava puede afectar a su funcionamiento. El archivo .hex generado contiene los

datos adicionales que permiten el funcionamiento del depurador. Una herramienta denominada mikroICD

(Depurador en circuito - In Circuit Debugger) permite ejecutar el programa paso a paso y proporcionar un

acceso al contenido actual de todos los registros de un microcontrolador real.


El simulador no utiliza los dispositivos reales para simular el funcionamiento del microcontrolador, as que

algunas operaciones no pueden ser reproducidas (por ejemplo, interrupcin). De todos modos, resulta ms

rpido depurar un programa por medio de un simulador. Adems, no se requiere ningn dispositivo destino.

Note que es posible modificar cualquier configuracin en cualquier momento mientras se edita el programa.

No se olvide de recompilar y reprogramar su dispositivo despus de modificar una configuracin.

LIBRARY MANAGING (EDITOR DE LIBRERAS)

El compilador tiene que conocer todas las dependencias de su archivo fuente en mikroC para compilarlo

apropiadamente. Por ejemplo, si las libreras forman parte de su proyecto, debe especificar cules de ellas se

utilizan.
Las libreras contienen un gran nmero de funciones listas para ser utilizadas. Las libreras en mikroC

proporcionan muchas facilidades para escribir programas para los microcontroladores PIC. Abra la

ventana Library Manager, y marque las que quiere utilizar en el programa. Al marcar una librera, se aade

automticamente al proyecto y se enlaza durante el proceso de la compilacin. As, no necesita incluir las

libreras manualmente en sus archivos del cdigo fuente por medio de la directiva del preprocesador #include.

Por ejemplo, si su programa utiliza un LCD no hace falta escribir nuevas funciones ya que al seleccionar la

librera Lcd, usted podr utilizar funciones listas para ser utilizadas de la librera LCD (Lcd_Cmd, LCD_Init...)

en su programa. Si esta librera no est seleccionada en la ventana Library Manager, cada vez que intente

utilizar una funcin de la librera LCD, el compilador le informar de un error. Una descripcin de cada librera

est disponible al pulsar con el botn derecho del ratn sobre su nombre y seleccionar la opcin Help.

EDITAR Y COMPILAR PROGRAMAS


CODE EDITOR (EDITOR DE CDIGO)

El proceso de editar programas se debe realizar dentro de la ventana principal del IDE denominada Code

Editor. Al escribir el programa no se olvide de los comentarios. Los comentarios son muy importantes para

depurar y mejorar el programa. Adems, aunque el compilador no tenga las restricciones de formateo,

siempre debe seguir a las mismas reglas de editar (como en los ejemplos proporcionados en este libro). Como

no hay limitaciones de tamao, no vacile en utilizar los espacios en blanco para hacer su cdigo ms legible.
Al escribir un programa, no espere que termine la redaccin del programa para compilarlo. Compile su cdigo

de forma regular con el propsito de corregir cunto ms errores de sintaxis. Asimismo usted puede compilar

su programa cada vez que se complete la redaccin de una nueva funcin as como probar su

comportamiento al utilizar modo de depuracin (ver la prxima seccin). De este modo, resulta ms fcil

solucionar los errores de programa para no tomar un camino errneo en redactar su programa. De lo

contrario, usted tendr que editar el programa entero.

CODE EXPLORER (EXPLORADOR DEL CDIGO)

La ventana Code Explorer le permite localizar funciones y procedimientos dentro de los programas largos. Por

ejemplo, si usted busca una funcin utilizada en el programa, basta con pulsar dos veces sobre su nombre en

esta ventana, y el cursor estar automticamente posicionado en la lnea apropiada en el programa.

COMPILAR Y SOLUCIONAR LOS ERRORES

Para compilar su cdigo, pulse sobre la opcin Build en el men Project. En realidad, el proyecto entero se ha

compilado, y si la compilacin se ha realizado con xito, se generarn los archivos de salida (asm, .hex etc.).

Una compilacin se ha realizado con xito si no se ha encontrado ningn error. Durante el proceso de

compilacin se generan muchos mensajes que se visualizan en la ventana Messages. Estos mensajes

consisten en informacin, advertencia y errores. Cada error encontrado se asocia con su lnea de programa y

su descripcin.

Como un error en su cdigo puede generar mucho ms errores, simplemente debe intentar solucionar el

primer error en la lista y despus recompile su programa. En otras palabras, es recomendable solucionar los

errores uno a uno.


En el ejemplo anterior hay dos errores y una advertencia: faltan un punto y coma y una declaracin de

variable La advertencia le informa que falta el tipo del valor devuelto de la funcin main.

La compilacin le permite corregir su programa por medio de solucionar todos los errores en mikroC. Cuando
todos los errores se solucionen, su programa est listo para ser cargado en el microcontrolador. De todas

formas, su tarea todava no est terminada, porque an no sabe si su programa se comporta como se

esperaba o no.

DEPURAR EL PROGRAMA

La depuracin es un paso muy importante ya que permite probar el programa despus de una compilacin

realizada con xito, o solucionar los errores descubiertos mientras se ejecuta el programa. Como ya hemos

visto, hay dos modos de depurar: un depurador software que simula el funcionamiento del microcontrolador

(modo por defecto) y depurador hardware (mikroICD) que lee directamente el contenido de la memoria del

microcontrolador. El procedimiento de depuracin es el mismo sin reparar en el modo elegido. En caso de

elegir la opcin ICD debug, hay que cargar el programa en el microcontrolador antes de depurarlo.

Para iniciar la depuracin, pulse sobre la opcin Start debugger del men Run. El editor del cdigo ser

ligeramente modificado automticamente y aparecer una ventana denominada Watch Values. El principio de

depuracin se basa en ejecutar el programa paso a paso y monitorear el contenido de los registros y los

valores de las variables. De este modo, es posible comprobar el resultado de un clculo y ver si algo

inesperado ha ocurrido. Al ejecutar el programa paso a paso, podr localizar los problemas con facilidad.

Durante una depuracin el programa ser modificado, por lo que usted siempre debe recompilar el programa

despus de cada correccin, y reiniciar el depurador para comprobar qu ha sido modificado.

COMANDOS DEL DEPURADOR

Hay varios comandos disponibles para depurar el cdigo:

Step Into - Ejecuta una sola instruccin. Cuando la instruccin es una llamada a una
rutina, el depurador har un salto a la rutina y se detendr despus de ejecutar la primera
instruccin dentro de la rutina.
Step Over - Se ejecuta una sola instruccin. Cuando la instruccin es una llamada a una
rutina, el depurador no har un salto a la rutina, sino que se ejecutar toda la rutina. El
depurador se detiene a la primera instruccin despus de la llamada a la rutina.
Run To Cursor - El programa se ejecuta hasta la lnea en la que se encuentre el cursor.
Step out - Se ejecutan las dems instrucciones dentro de la rutina. El depurador se
detiene inmediatamente al salir de la rutina.

PUNTOS DE RUPTURA (BREAKPOINTS)

Los puntos de ruptura hacen el proceso de depurar los programas de una manera ms eficiente, puesto que

permiten ejecutar el programa a toda velocidad y detenerlo automticamente en una lnea especfica (punto

de ruptura). Eso resulta muy til, permitindole comprobar slo las partes crticas del programa y no perder el

tiempo probando todo el programa lnea a lnea. Para aadir o quitar un punto de ruptura basta con pulsar

sobre la lnea apropiada en el lado izquierdo del editor del cdigo, o presionar [F5]. Una pequea ventana

denominada Breakpoints muestra dnde estn los puntos de ruptura. Note que las lneas designadas como

puntos de ruptura estn marcadas en rojo.

La lnea que se est ejecutando actualmente est marcada en azul. Es posible leer el contenido de registros y

variables seleccionados en la ventana Watch Values en cualquier momento. Para ejecutar la parte de

programa desde la lnea en la que est el cursor hasta el punto de ruptura, utilice el comando Run/Pause

Debugger.
VENTANA WATCH VALUES

El depurador software y hardware tienen la misma funcin de monitorear el estado de los registros durante la

ejecucin del programa. La diferencia es que el depurador software simula ejecucin de programa en una PC,

mientras que el depurador ICD (depurador hardware) utiliza un microcontrolador real. Cualquier cambio de

estado lgico de los pines se indica en el registro (puerto) apropiado. Como la ventana Watch Values permite

monitorear el estado de todos los registros, resulta fcil comprobar si un pin est a cero o a uno. La ltima

modificacin est marcada en rojo en la ventana Watch Values. Esto le permite localizar la modificacin en la

lista de variables y registros durante el proceso de la depuracin.


Para visualizar esta ventana es necesario seleccionar la opcin View/Debug Windows/Watch Values.

Entonces usted puede hacer una lista de registros/variables que quiere monitorear y la manera de

visualizarlos.
STOPWATCH (CRONMETRO)

Si quiere saber cunto tiempo tarda un microcontrolador en ejecutar una parte del programa, seleccione la

opcin Run/View Stopwatch. Aparecer una ventana como se muestra en la figura a la derecha. Cmo

funciona un cronmetro? Eso es pan comido... El tiempo que tarda un comando (step into, step over,

run/pause etc.) en ejecutarse por el depurador se mide automticamente y se visualiza en la ventana

Stopwatch. Por ejemplo, se mide tiempo para ejecutar un programa, tiempo para ejecutar el ltimo paso etc.

PROGRAMAR EL MICROCONTROLADOR

Si ha solucionado todos los errores en su cdigo y cree que su programa est listo para ser utilizado, el

siguiente paso es cargarlo en el microcontrolador. El programador PICflash se utiliza para este propsito. Es

una herramienta diseada para programar todos los tipos de microcontroladores PIC. Est compuesto por dos

partes:
La parte hardware se utiliza para introducir un cdigo hexadecimal (el programa a ser
cargado en el microcontrolador) y para programar el microcontrolador por medio de niveles
de voltaje especficos. Durante el proceso de la programacin, un nuevo programa se
escribe en la memoria flash del microcontrolador, mientras que el programa anterior se
borra automticamente.
La parte de software se encarga de enviar el programa (archivo .hex ) a la parte hardware
del programador por medio de un cable USB. A la interfaz de usuario de este software se le
puede acceder desde IDE al pulsar sobre la opcin mE_Programmer del men Tools o al
pulsar [F11]. Por consiguiente, es posible modificar algunas configuraciones del
programador y controlar el funcionamiento de la parte hardware (Cargar, Escribir,
Verificar...).

Se puede reprogramar el microcontrolador tantas veces como se necesite.

OTRAS HERRAMIENTAS DEL COMPILADOR

El compilador mikroC PRO for PIC proporciona herramientas que en gran medida simplifican el proceso de

escribir el programa. Todas estas herramientas se encuentran en el men Tools. En la siguiente seccin

vamos a darle una breve descripcin de todas ellas.

TERMINAL USART

El terminal USART representa una sustitucin para la estndar Windows Hyper Terminal. Se puede utilizar

para controlar el funcionamiento del microcontrolador que utiliza la comunicacin USART. Tales

microcontroladores estn incorporados en un dispositivo destino y conectados al conector RS232 de la PC por

medio de un cable serial.

La ventana USART terminal dispone de opciones para configurar la comunicacin serial y visualizar los datos

enviados/ recibidos.
EDITOR EEPROM

Al seleccionar la opcin EEPROM Editor del men Tools, aparecer una ventana como se muestra en la

siguiente figura. As es cmo funciona la memoria EEPROM del microcontrolador. Si quiere cambiar de su

contenido despus de cargar el programa en el microcontrolador, sta es la forma correcta de hacerlo. El

nuevo contenido es un dato de un tipo especfico (char, int o double), primero debe seleccionarlo, introducir el

valor en el campo Edit Value y pulsar sobre Edit. Luego, pulse sobre el botn Save para guardarlo como un

documento con extensin .hex. Si la opcin Use EEPROM in Project est activa, los datos se cargarn

automticamente en el microcontrolador durante el proceso de la programacin.


VENTANA ASCII CHART

Si necesita representar numricamente un carcter ASCII, seleccione la opcin ASCII chart del men Tools.

Aparecer una tabla, como se muestra en la figura que est a continuacin. Usted probablemente sabe que

cada tecla de teclado est asociada con un cdigo (cdigo ASCII). Como se puede ver, los caracteres que

representan los nmeros tienen valores diferentes. Por esta razn, la instruccin de programa para visualizar

el nmero 7 en un LCD no visualizar este nmero, sino el equivalente a la instruccin BEL. Si enva el mismo

nmero en forma de un carcter a un LCD, obtendr el resultado esperado - nmero 7. Por consiguiente, si

quiere visualizar un nmero sin convertirlo en un carcter apropiado, es necesario aadir el nmero 48 a cada

dgito en el que consiste el nmero a visualizar.


EDITOR DE SIETE SEGMENTOS

Un editor de siete segmentos le permite determinar con facilidad el nmero a poner en un puerto de salida con

el propsito de visualizar un smbolo deseado. Por supuesto, se da por entendido que los pines del puerto

deben estar conectados a los segmentos del visualizador de manera apropiada. Basta con colocar el cursor

en cualquier segmento del visualizador y pulsar sobre l. Se visualizar inmediatamente el nmero a introducir

en el programa.
LCD CUSTOM CHARACTER (CARACTERES LCD DEFINIDOS POR EL USUARIO)

Adems de los caracteres estndar, el microcontrolador tambin puede visualizar los caracteres creados por

el programador. Al seleccionar la herramienta LCD custom character, se evitar un pesado trabajo de crear

funciones para enviar un cdigo apropiado a un visualizador. Para crear un smbolo, pulse sobre los cuadros

pequeos en la ventana LCD custom character, luego seleccione la posicin y la fila y pulse sobre el botn

GENERATE. El cdigo apropiado aparece en otra ventana. No es necesita pulsar ms. Copy to Clipboard

(copiar al portapapeles) - Paste (pegar)...

GENERADOR DE MAPA DE BITS PARA UN LCD GRFICO

El generador de mapa de bits para un LCD grfico es una herramienta insustituible en caso de que el

programa que escribe utilice el visualizador LCD (GLCD). Esta herramienta le permite visualizar un mapa de

bits con facilidad. Seleccione la opcin Tools/Glcd Bitmap Editor aparecer la ventana apropiada. Para

utilizarlo, seleccione el tipo de visualizador a utilizar y cargue un mapa de bits. El mapa de bits debe ser

monocromtico y tener la resolucin apropiada del visualizador (128 x 64 pxeles en este ejemplo). El

procedimiento a seguir es igual que en el ejemplo anterior: Copy to Clipboard...


Un cdigo generado que utiliza herramientas para controlar los visualizadores LCD y GLCD contiene

funciones de la librera Lcd. Si las utiliza en el programa, no se olvide de marcar la caja de chequeo junto a

esta librera en la ventana Library Manager. As el compilador ser capaz de reconocer estas funciones

correctamente.
La manera de escribir el cdigo en C es muy importante. Por ejemplo, C difiere entre minsculas y

maysculas, as que la funcin main() no se puede escribir MAIN() o Main(). Adems, note que dos lneas del

cdigo dentro de la funcin terminan con un punto y coma. En C todas las sentencias deben terminar con un

punto y coma ;, as el compilador puede aislarlas y traducirlas a cdigo mquina.

Você também pode gostar