20.01.2015 Views

Curso Programación MCUs PIC en lenguaje C - Edudevices

Curso Programación MCUs PIC en lenguaje C - Edudevices

Curso Programación MCUs PIC en lenguaje C - Edudevices

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Apr<strong>en</strong>di<strong>en</strong>do a programar<br />

Microcontroladores <strong>PIC</strong> <strong>en</strong><br />

L<strong>en</strong>guaje C con CCS<br />

Por Andrés Raúl Bruno Saravia<br />

Entrega Nº 6.<br />

¿Cuáles son las estructuras básicas de C<br />

Estas estructuras son las que le dan “intelig<strong>en</strong>cia al programa” permiti<strong>en</strong>do que el<br />

microcontrolador haga algo a partir de una condición que es evaluada<br />

S<strong>en</strong>t<strong>en</strong>cia if:<br />

Forma g<strong>en</strong>eral:<br />

if (condición)<br />

s<strong>en</strong>t<strong>en</strong>cia1;<br />

else<br />

s<strong>en</strong>t<strong>en</strong>cia2;<br />

Si la condición es verdadera (se cumple), se ejecuta la s<strong>en</strong>t<strong>en</strong>cia1, de lo contrario la<br />

s<strong>en</strong>t<strong>en</strong>cia2. (esta estructura su<strong>en</strong>a de la sigui<strong>en</strong>te forma: “si la (condición) se cumple, se<br />

ejecuta la s<strong>en</strong>t<strong>en</strong>cia1, sino, se ejecuta la s<strong>en</strong>t<strong>en</strong>ca2.<br />

También se pued<strong>en</strong> escalonar los if:<br />

if (condición)<br />

S<strong>en</strong>t<strong>en</strong>cia1;<br />

else if (condición)<br />

S<strong>en</strong>t<strong>en</strong>cia2;<br />

else<br />

S<strong>en</strong>t<strong>en</strong>cia3;


Y anidar:<br />

if (x)<br />

if (a


Ejemplo:<br />

La s<strong>en</strong>t<strong>en</strong>cia switch se usa <strong>en</strong> g<strong>en</strong>eral para seleccionar m<strong>en</strong>úes de opciones, <strong>en</strong> este<br />

segm<strong>en</strong>to de código lo que se explora es justam<strong>en</strong>te el valor de la opción seleccionada,<br />

y según la misma será la operación realizada:<br />

switch(opcion)<br />

{<br />

case 1:<br />

res = valor*valor;<br />

printf(“El cuadrado de %i es %i\n”, valor, res);<br />

break;<br />

case 2:<br />

res = valor*valor*valor;<br />

printf(“El cubo de %i es %i\n”, valor, res);<br />

break;<br />

case 3:<br />

res = valor % 2;<br />

if (res)<br />

prinf(“El número %i es impar\n”, valor);<br />

else<br />

printf(“El número %i es par\n”, valor);<br />

break;<br />

default:<br />

printf(“Opción erronea”);<br />

}<br />

La variable opcion conti<strong>en</strong>e el valor del m<strong>en</strong>ú seleccionado por el usuario. En cada case<br />

lo que se explora es si la variable ha adquirido ese valor.<br />

Los bucles o ciclos iterativos<br />

El bucle for:<br />

Esta s<strong>en</strong>t<strong>en</strong>cia nos permite repetir una o varias s<strong>en</strong>t<strong>en</strong>cias una cantidad de veces<br />

determinada por 3 parámetros.<br />

Forma g<strong>en</strong>eral del for:<br />

Para una sola s<strong>en</strong>t<strong>en</strong>cia .<br />

for(inicialización; condición; increm<strong>en</strong>to)<br />

s<strong>en</strong>t<strong>en</strong>cia;<br />

Para un bloque de s<strong>en</strong>t<strong>en</strong>cias (recordemos que el bloque queda definido por las llaves.<br />

for(inicialización; condición; increm<strong>en</strong>to)<br />

{<br />

s<strong>en</strong>t<strong>en</strong>cias;<br />

}


El sigui<strong>en</strong>te ejemplo muestra los primeros 100 números <strong>en</strong>teros:<br />

#include <br />

#fuses INTRC_IO,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP<br />

#use delay(clock=4000000)<br />

#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)<br />

void main(void)<br />

{<br />

setup_adc_ports(NO_ANALOGS); //Selecciona terminales<br />

while(1)// ciclo for infinito<br />

{<br />

}<br />

}<br />

for(i=1; i=1; i - -)<br />

printf(“%d”, i);<br />

Se pued<strong>en</strong> evaluar más de una variable:<br />

int i, j;<br />

for(i=1, j=100; i0; i++, j - -)<br />

printf(“i = %d, j= %d\n”, i, j);<br />

El sigui<strong>en</strong>te bucle no termina nunca, (bucle infinito):<br />

for( ; ; )<br />

Debemos recordar que si la cantidad de s<strong>en</strong>t<strong>en</strong>cias, (equival<strong>en</strong>cias, operaciones<br />

aritméticas, llamadas a funciones, etc.), pert<strong>en</strong>eci<strong>en</strong>tes al bucle son más de una, estas<br />

deb<strong>en</strong> ir <strong>en</strong>tre { }.<br />

El bucle while:<br />

El bucle while permite ejecutar una o mas s<strong>en</strong>t<strong>en</strong>cias <strong>en</strong> tanto se cumpla una condición.<br />

Si la condición deja de cumplirse, se dejan de ejecutar la o las instrucciones y se “sale<br />

del bloque while para continuar procesando las instrucciones que se <strong>en</strong>cu<strong>en</strong>tran después<br />

del mismo


while (condición)<br />

s<strong>en</strong>t<strong>en</strong>cia;<br />

while (condición)<br />

{<br />

s<strong>en</strong>t<strong>en</strong>cia1;<br />

s<strong>en</strong>t<strong>en</strong>cia2;<br />

s<strong>en</strong>t<strong>en</strong>cia3;<br />

s<strong>en</strong>t<strong>en</strong>cia4;<br />

.<br />

.<br />

S<strong>en</strong>tt<strong>en</strong>cia_n;<br />

}<br />

Ejemplo:<br />

char salir;<br />

salir = ‘n’;<br />

while (salir != ‘n’)<br />

{<br />

printf(“Estoy d<strong>en</strong>tro del mi<strong>en</strong>tras\n”);<br />

getc(“%c”, &salir);<br />

}<br />

printf(“\nYa salí”);<br />

El bucle también puede estar vacío. El sigui<strong>en</strong>te ejemplo funcionará hasta que se pulse<br />

la letra ‘A’:<br />

while ((letra = getc()) != ‘A’);<br />

El bucle do – while:<br />

La difer<strong>en</strong>cia que existe con el while, es que <strong>en</strong> el bucle do – while por lo m<strong>en</strong>os una<br />

vez, el programa ejecuta las s<strong>en</strong>t<strong>en</strong>cias del bucle, (hasta llegar a la s<strong>en</strong>t<strong>en</strong>cia while), y<br />

luego decide si continúa iterando, siempre que se cumpla la condición examinada por el<br />

while.<br />

La forma g<strong>en</strong>eral del bucle es:<br />

do<br />

{<br />

s<strong>en</strong>t<strong>en</strong>cia;<br />

} while (condición);


Operaciones A Nivel De Bits, (Bitwise):<br />

El l<strong>en</strong>guaje c proporciona la posibilidad de manipular los bits de un byte, realizando<br />

operaciones lógicas y de desplazami<strong>en</strong>to. En el caso de las operaciones lógicas, estas<br />

g<strong>en</strong>eralm<strong>en</strong>te son usadas para crear mascaras que fuerc<strong>en</strong> a que ciertos bits sean puestos<br />

<strong>en</strong> 1 o <strong>en</strong> 0.<br />

Los operadores a nivel de bits son los sigui<strong>en</strong>tes:<br />

OPERADOR ACCIÓN<br />

&<br />

AND <strong>en</strong>tre bits<br />

| OR <strong>en</strong>tre bits<br />

^<br />

XOR <strong>en</strong>tre bits, (or exclusivo).<br />

~ NOT , (si es 1 pasa a ser 0 y viceversa)<br />

> Desplazami<strong>en</strong>to a derecha<br />

Ejemplos de los operadores son los sigui<strong>en</strong>tes:<br />

var > n = se desplaza n bits a la derecha.<br />

1 & 1 = 1<br />

1 | 0 = 1, 0 | 1 = 1 y 1 | 1 = 1<br />

1 ^ 0 = 1 y 0 ^ 1 = 1<br />

~1 = 0 y ~0 = 1<br />

De forma g<strong>en</strong>eral convi<strong>en</strong>e t<strong>en</strong>er siempre pres<strong>en</strong>te estos resultados<br />

X & 1 = X , X & 0 = 0<br />

X | 1 = 1 , X | 0 = X<br />

X ^ 1 = ~X , X ^ 0 = X<br />

Estructuras De Datos:<br />

Arrays:<br />

Un array es una colección de elem<strong>en</strong>tos de un mismo tipo, que se refer<strong>en</strong>cian usando un<br />

nombre de variable común. En C, el array ocupa posiciones de memoria contiguas. La<br />

dirección más baja corresponde al primer elem<strong>en</strong>to y la más alta al último. Para acceder<br />

a un elem<strong>en</strong>to específico se usan índices.<br />

Arrays unidim<strong>en</strong>sionales:<br />

Forma g<strong>en</strong>eral de declararlos:<br />

tipo nombre-variable[tamaño];


Ejemplo:<br />

int numeros[10];<br />

Es un arreglo de 10 elem<strong>en</strong>to <strong>en</strong>teros, donde el primero es numeros[0] y el último<br />

numeros[9].<br />

Guardemos <strong>en</strong> este array los números dígitos, (0 al 9):<br />

for(i=0; i


¿Para que es la s<strong>en</strong>t<strong>en</strong>cia #define<br />

Esta s<strong>en</strong>t<strong>en</strong>cia permite declarar constantes y es muy usada para definir valores que<br />

usaremos d<strong>en</strong>tro del programa<br />

#define VREF 5 //define la t<strong>en</strong>sión de refer<strong>en</strong>cia<br />

#define ADCBITS 1024.0 // define la resolución del ADC<br />

¿Que son los Punteros<br />

La memoria de un Microcontrolador se repres<strong>en</strong>ta habitualm<strong>en</strong>te mediante direcciones<br />

expresadas <strong>en</strong> valores hexadecimales. Una variable, por ejemplo x, es una dirección de<br />

memoria donde se guarda algún valor. En los l<strong>en</strong>guajes de programación uno usa<br />

id<strong>en</strong>tificadores, (nombres simbólicos), para reservar lugares de la memoria necesarios<br />

para almac<strong>en</strong>ar datos que permitan realizar operaciones. Estos lugares son tan amplios<br />

como el tipo de dato <strong>en</strong> que fue declarada la variable, esto es:<br />

Si declaro una variable x de tipo <strong>en</strong>tera, (int), estaría reservando 2 bytes <strong>en</strong> memoria, si<br />

declaro una de tipo char sería 1 byte, etc.<br />

Un puntero es una variable de algún tipo que permite guardar una dirección de<br />

memoria, esto permite, indirectam<strong>en</strong>te, acceder al cont<strong>en</strong>ido de esa dirección.<br />

Un puntero se declara de forma g<strong>en</strong>eral de la sigui<strong>en</strong>te manera:<br />

tipo *nombre-variable;<br />

Ejemplo :<br />

int *p;<br />

char *q;<br />

Veamos un pequeño segm<strong>en</strong>to de programa que ilustre las cualidades de los punteros:<br />

int *p; (1)<br />

int x = 5; (2)<br />

p = &x; (3)<br />

printf(“El valor de x es: %d\n”, x); (4)<br />

printf(“p apunta a x, <strong>en</strong>tonces <strong>en</strong> x hay: %d”, *p); (5)<br />

Este ejemplo dará como resultado la visualización del cont<strong>en</strong>ido de la variable x, o sea<br />

5, dos veces.<br />

Veamos línea por línea:<br />

En (1) se declara un variable puntero, p, a los <strong>en</strong>teros<br />

En (2) una variable x <strong>en</strong>tera con el valor inicial de 5.<br />

En (3) se almac<strong>en</strong>a <strong>en</strong> el puntero, p, la dirección de memoria de x; el operador &<br />

permite ver la dirección de memoria de una variable.


Luego <strong>en</strong> (4) se muestra el cont<strong>en</strong>ido de x.<br />

Como <strong>en</strong> (3) se guardó la dirección de x <strong>en</strong> p, éste, que es un puntero, ti<strong>en</strong><strong>en</strong> la cualidad<br />

de “ver” el cont<strong>en</strong>ido de esa dirección de forma indirecta por medio del operador *.<br />

Esto es lo que se hace <strong>en</strong> (5), ver el cont<strong>en</strong>ido de x, pero desde el puntero, ya que él<br />

ti<strong>en</strong>e almac<strong>en</strong>ada la dirección de memoria de x. Por eso se visualiza dos veces el<br />

cont<strong>en</strong>ido de x.<br />

Continuará .......

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!