Aprendiendo a programar Microcontroladores PIC en Lenguaje C con CCS
Por Andrés Raúl Bruno Saravia
Entrega Nº 4. Se dice que el lenguaje C es un lenguaje de nivel medio. La razón de esta indicación está en que en C se pueden crear programas que manipulan la máquina casi como lo hace el lenguaje Ensamblador, pero utilizando una sintaxis que se asemeja más a los lenguajes de alto nivel. De los lenguajes de alto nivel toma las estructuras de control que permiten programar de forma estructurada. Al tener características de los lenguajes de bajo nivel se puede tomar el control absoluto del microcontrolador. Además tiene atajos que gustan mucho a los programadores al tener una sintaxis menos restrictiva que lenguajes como Pascal por ejemplo, lo que le convierte en el lenguaje idóneo para crear cualquier tipo de aplicación. Sus características básicas son: • • • • •
Es un lenguaje estructurado y modular. Lo que facilita su compresión y escritura Es un lenguaje que incorpora manejo de estructuras de bajo nivel (punteros, bits), lo que le acerca a los lenguajes de segunda generación Permite utilizar estructuras de datos complejas (arrays, pilas, colas, textos,...) Es un lenguaje compilado Permite crear todo tipo de aplicaciones
¿Cual es estructura de un programa en Lenguaje C? Un programa en C consta de una o más funciones, las cuales están compuestas de diversas sentencias o instrucciones. Una sentencia indica una acción a realizar por parte del programa. Una función no es más que (por ahora) un nombre con el que englobamos a las sentencias que posee a fin de poder invocarlas mediante dicho nombre.
La idea es: parámetros nombreDeFunción(parámetros) { Sentencias; } Los símbolos { y } indican el inicio y el final de la función. Esos símbolos permiten delimitar bloques en el código. El nombre de la función puede ser invocado desde otras sentencias simplemente poniendo como sentencia el nombre de la función. Como a veces las funciones se almacenan en archivos externos, necesitamos incluir esos archivos en nuestro código mediante una sentencia especial #include , que en realidad es una directiva de preprocesador. Una directiva de preprocesador es una instrucción para el compilador con el que trabajamos. El uso es: #include La directiva #include permite indicar un archivo de cabecera en el que estará incluida la función que utilizamos. En el lenguaje C estándar los archivos de cabecera tienen extensión h. Los archivos de cabecera son los que permiten utilizar funciones externas (o librerías) en nuestro programa. Una de las librerías más utilizadas en los programas, es la que contiene las etiquetas de todos los registros de funciones especiales del MCU PIC que hayamos seteado en el proyecto. En el caso de CCS esta librería está disponible en la cabecera 16Fxxx.h En todos los lenguajes de programación, el primer programa a realizar es el famoso Hola mundo, un programa que escribe este texto en pantalla. En el mundo de los microcontroladores PIC, este programa se traduce en hacer titilar un led. De esta forma en CCS el código de este programa es: #include <18f14k50.h> #use delay(crystal=12000000)// #fuses HS,NOWDT,NOLVP,NODEBUG,NOBROWNOUT,NOPLLEN,CPUDIV1,PUT,MCLR #define LED1 PIN_B4 void main(void) { setup_adc_ports(NO_ANALOGS); while(1) { output_high(LED1); delay_ms(500); output_low(LED1); delay_ms(500); } }
¿Cuáles son los elementos de un programa en C? Los programas en C se basan en sentencias las cuales siempre se incluyen dentro de una función. En el caso de crear un programa ejecutable, esas sentencias están dentro de la función main. A está función le antecede y precede la palabra void. Ahora bien al escribir sentencias hay que tener en cuenta las siguientes normas: (1) Toda sentencia en C termina con el símbolo "punto y coma" (;) (2) Los bloques de sentencia empiezan y terminan delimitados con el símbolo de llave ({ y }). Así { significa inicio y } significa fin (3) En C hay distinción entre mayúsculas y minúsculas. No es lo mismo main que MAIN. Todas las palabras claves de C están en minúsculas. Los nombres que pongamos nosotros también conviene ponerles en minúsculas ya que el código es mucho más legible así.
¿Qué es un comentario? Se trata de texto que es ignorado por el compilador al traducir el código. Esas líneas se utilizan para documentar el programa. Esta labor de documentación es fundamental. De otro modo el código se convierte en ilegible incluso para el programador que lo diseñó. Tan importante como saber escribir sentencias es utilizar los comentarios. Todavía es más importante cuando el código va a ser tratado por otras personas, de otro modo una persona que modifique el código de otra lo tendría muy complicado. En C los comentarios se delimitan entre los símbolos /* y */ para los bloque y // para las lineas // Esto es un comentario usado para las líneas /* Esto es un comentario el compilador hará caso omiso de este texto*/
¿Qué debemos considerar como importante en C? C no es un lenguaje dócil para enfrentarlo intuitivamente por primera vez; se requiere un mínimo conocimiento de sus fundamentos antes de poner las manos sobre el teclado. En este aspecto es particularmente importante comprender los diferentes tipos de datos y las reglas que rigen su operación. La idea directriz de C es la definición de procedimientos (funciones), que en principio devuelven un valor. Lo que para nosotros es - conceptualmente - el programa principal, también es en C una función (la más externa). Incidentalmente, su valor es devuelto al sistema operativo como código de conclusión del programa. Ante todo, C está diseñado con vistas a la compatibilidad. En este sentido, todas las definiciones que puedan hacerse no serán concretas, pues son adaptables de acuerdo con la implementación. Un entero, por ejemplo, es una entidad con ciertas características generales, pero su implementación diferirá en distintos equipos.
C maneja los datos en forma de variables y constantes, conceptos con los que supondremos que el lector está familiarizado. Las variables, simbolizadas mediante datos alfanuméricos (cuyas reglas de construcción trataremos más adelante), presentan características que será muy importante considerar: • • •
Tipo de dato: cada variable (también las constantes) está caracterizada por el tipo de dato que representa. Visibilidad: en un programa C, cada variable tiene un rango de visibilidad (procedimientos en los que es reconocida), que depende de cómo se la haya declarado. Existencia: relacionado con la anterior característica, es posible que el contenido de una variable perdure, o que se pierda, por ejemplo, al terminarse un procedimiento.
¿Cuál es el grupo de caracteres de C? C emplea dos conjuntos de caracteres: • •
El primero de ellos incluye todos los caracteres que tienen algún significado para el compilador. El segundo incluye todos los caracteres representables.
C acepta sólo ciertos caracteres como significativos. Sin embargo, otros caracteres pueden formar parte de expresiones literales (constantes literales, nombres de archivo, etc.) que no serán analizadas por C. Los caracteres a los que C asigna especial significado se pueden clasificar en alfanuméricos y signos especiales. Los caracteres alfanuméricos incluyen las letras (alfabeto inglés, de A a Z), mayúsculas y minúsculas, los dígitos, y el guión bajo (underscore: ‘_’). En todos los casos, las mayúsculas son consideradas distintas de las minúsculas. Toda cadena alfanumérica con significación en C está compuesta exclusivamente por estos caracteres. Los signos especiales son los listados a continuación. Ellos se emplean como delimitadores, operadores, o signos especiales. Mayúsculas: A - Z Minúsculas: a - z Dígitos: 0 – 9 Guión bajo: _ Coma , Punto . Punto y coma ; Dos puntos : Signo de interrogación ? Signo de admiración ! Comilla simple ‘ Comilla doble “ Barra vertical | Barra / Barra invertida \ Tilde ~
Signo más + Signo menos Paréntesis izquierdo ( Paréntesis derecho ) Corchete izquierdo [ Corchete derecho ] Llave izquierda { Llave derecha { Signo Mayor > Signo Menor < Signo igual = Asterisco * Ampersand & Porciento % Caret ^
¿Qué es un identificador? Los identificaremos se utilizan para identificar, (valga la redundancia): variables, constantes, funciones, etc. Deben comenzar con una letra. Máxima longitud: 32 caracteres. Sólo pueden contener letras y números, pero no caracteres especiales, salvo el guión bajo, (underscore). No se deben confundir con palabras reservadas de C, (una variable, por ejemplo no puede llamarse int, ni main, etc.) y hay diferencias entre mayúsculas y minúsculas. Como norma se utilizan las minúsculas; las mayúsculas se usan para las constantes. Las palabras reservadas o también conocidas como “palabras claves” sirven para indicar al microcontrolador que realice una tarea muy determinada (desde evaluar una comparación, hasta definir el tipo de una variable) y tienen un especial significado para el compilador es por ello que no pueden usarse como identificadores: auto break case char const continue default do
double else enum extern float for goto if
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while
¿Cuáles son los tipos de datos básicos que maneja CCS? El estándar Ansi define un conjunto de tipos básicos y su tamaño mínimo. En distintas implementaciones del lenguaje C estos tamaños puede cambiar, así por ejemplo: el int se define en Ansi C como un tipo de dato que almacena enteros en un rango de –32767 hasta +32767, sin embargo para el compilador CCS en 8 bits (PCB,PCM y PCH), el valor es un entero positivo en el rango 0 a 255. En CCS los tamaños están definidos por el ancho del bus de datos que posee el microcontrolador PIC, de esta forma los tamaños para los micros de 8 bits (PIC10,PIC12 y PIC16) no son iguales al de los micros de 16 bits de datos (PIC24, dsPIC30 y dsPIC33) :
Micros PIC10, PIC12,PIC16 y PIC18 TIPO ANCHO EN BITS char (carácter) 8 int (entero) 8 long(entero largo) 16 long long (entero extra largo)32 float (real) 32 short 1 void 0
BYTES 1 1 2 4 4 0 0
Micros PIC24, dsPIC30 y dsPIC33 TIPO ANCHO EN BITS char (carácter) 8 int (entero) 16 long(entero largo) 32 long long (entero extra largo)64 float (real) 32 double 64 short 8 void 0
BYTES 1 2 4 8 4 8 1 0
A diferencia del compilador ANSI C CCS tiene sus tipos de datos predefinidos sin signo, es decir que solo podemos almacenar valores positivos excepto que especifiquemos antes del tipo la palabra clave signed
¿Qué son los operadores aritméticos en C ? Son usados para definir una operación aritmética entre distintos operandos, estos pueden ser los siguientes: OPERADOR + * / % -++
ACCIÓN Resta Suma Multiplicación división. (sólo para enteros) Resto de la división entera Decremento Incremento
Los operadores de decremento e incremento equivalen a: a = a + 1 = a++ a=a-1=a-En caso de presentarse a con el operador delante: A = 8; B = ++A; B toma el valor de 9. Pero de plantearse lo siguiente: A = 8; B = A++; B toma el valor de 8. O sea que en este último caso, primero ocurre la asignación y luego el incremento en A.
¿Para qué son los operadores de relación? Estos operadores se usan para establecer una relación comparativa entre dos operandos. Los utilizados son los siguientes: OPERADOR > >= < <= == !=
ACCIÓN Mayor que Mayor igual que Menor que Menor igual que Igual que Distinto que
¿Qué son los operadores lógicos? Estos operadores se usan para establecer una relación lógica entre 2 comparaciones, generalmente se usan dentro de las estructuras condicionales que luego veremos. OPERADOR && || !
ACCIÓN And Or Not
La operación lógica no se realiza a nivel bit entre los operandos, sino que establece una relación entre condiciones comparativas en las que participan los operandos, ejemplo (condición 1) && (condición 2) establece que si se cumple la condición 1 y la condición 2.
En C, cualquier valor distinto de 0 es VERDADERO. FALSO es 0 (cero). Bueno hasta aquí hemos llegado con el artículo, nos encontraremos en nuestra próxima nota. Continuará.......