Programación en C para  microcontroladores

PICC en HI‐TECH Profesor: Adrián Montero Ulate

EL PIC

HISTORIA DE C

Historia y particularidades
• C fue inventado en 1974 para escribir el  sistema operativo UNIX • C es “más” bajo nivel que otros lenguajes de  alto nivel (bueno para microcontroladores) • C soporta diversas arquitecturas de µC • C puede hacer prácticamente cualquier cosa  que se pueda hacer en ensamblador • C es más rápido que ensamblador para  programar

ESTRUCTURA DE UN ARCHIVO .C

Estructura
#include <htc.h> #define _XTAL_FREQ void main(){

Archivo de encabezado
8000000

Declaración de constante Comentario

Declaración de variable

unsigned char var; TRISC = 0b00000000; PORTC = 0b00000001; //Configurar Puerto C como salidas

Función

while (1){ if(RD5 == 0){ PORTC = 0xF0; }else{ PORTC = 0x0F; } var = var + 2; } }

COMENTARIOS

Comentarios
• Dos maneras de hacerlos
– Bloque de comentario:
/* Esto es un comentario de dos líneas */

– Comentario en una sola línea:
//Comentario corto

VARIABLES

Variables
Una variable es un nombre que representa una  o más posiciones de memoria utilizadas para  guardar datos del programa. • Puede ser visto como un contenedor que  puede guardar datos usados en el programa int miVariable; miVariable = 5;

Variables ‐ Ejemplo
#include <htc.h> #define PI 3.14 void main(){
Tipo de dato

int radio, area;
Tipo de dato

Declaración de variables

//Calcular el área del círculo Variables en uso radio = 12; area = PI * radio * radio; }

Variables
• Las variables son nombres para posiciones de  Memoria de datos (RAM) memoria

int factor; char letra; float longitud;

Variables
• La declaración consiste en un identificador Memoria de datos (RAM) único (nombre)

int factor; char letra; float longitud;

Variables
• Y un tipo de dato
– Determina el tamaño – Determina como se  interpreta el dato
Memoria de datos (RAM)

int factor; char letra; float longitud;

IDENTIFICADORES

Identificadores
• Nombres dados a elementos tales como
– Variables – Funciones – Arreglos – Otros elementos

Identificadores
• Caracteres válidos en identificadores

IDENTIFICADOR
Primer Caracter ‘_’ (guión bajo) ‘A’ a la ‘Z’ ‘a’ a la ‘z’ Caracteres Restantes ‘_’ (guión bajo) ‘A’ a la ‘Z’ ‘a’ a la ‘z’ ‘0’ al ‘9’

• Sensible a mayúsculas y minúsculas • Solo reconoce los primeros 31 caracteres

PALABRAS RESERVADAS

Palabras reservadas del ANSI C

• Otros compiladores podrían incorporar más  palabras reservadas

TIPOS DE DATOS

Tipos de datos fundamentales
Tipo char Int float double Descripción Caracter simple Entero Coma flotante Coma flotante de doble precisión bits 8 16 32 64

• El tamaño de un int varía de un compilador a otro
– – – – MPLAB C30 int es de 16‐bits MPLAB C18 int es de 16‐bits CCS PCB, PCM & PCH int es de 8‐bits Hi‐Tech PICC int es de 16‐bits

Calificadores de tipos de dato
• Calificadores: unsigned, signed, short y long
Calificador
unsigned char char, signed char unsigned short int short int, signed short int unsigned int int, signed int unsigned long int long int, signed long int unsigned long long int long long int, signed long long int

Min 0 ‐128 0 ‐32768 0 ‐32768 0 ‐231 0 ‐231

Max 255 127 65535 32767 65535 32767 232 ‐ 1 231 264 ‐ 1 231

Bits 8 8 16 16 16 16 32 32 64 64

Declaración de variables
tipo identificador1, … , identificadorn;
• Una variable debe ser declarada antes de poder ser usada. • El compilador necesita saber cuanto espacio asignarle y como  manejar sus valores. • Ejemplos

int x, y, z; float factor; char texto unsigned int indice;

Declaración de variables
• Las variables se pueden declarar de varias  maneras:
Sintaxis Una declaración en una línea 
tipo identificador;

Una declaración en una línea con valor inicial
tipo identificador = ValorInicial;

Múltiples declaraciones del mismo tipo en una línea
tipo identificador1, identificador2, identificador3;

Múltiples declaraciones del mismo tipo en una línea con valor inicial
tipo identificador1 = Valor1, identificador2 = Valor2;

Ejemplos
unsigned int x; unsigned int y = 12; int a, b, c; long int var = 0x12345678; char primero = ‘a’, segundo, tercero = ‘c’; float numeroGrande = 6.02e+23; *Se acostumbra usar la notación “camel case” para las  variables: primera palabra en minúscula y todas las siguientes  con la primera letra en mayúscula.
Ejemplo: unaVariable, estoEsUnNombreLargo, otroNombreAlternativo

Variables
• Algunas veces las variables (y otros  elementos) son declarados en un archivo  separado llamado archivo de encabezado • Los archivos de encabezado terminan con la  extensión ‘.h’ • Se enlazan al programa  MiPrograma.h principal por medio de  la directiva #include
MiPrograma.c

CONSTANTES

FUNCIONES

DECLARACIONES

OPERADORES

Operadores
Definición: una expresión aritmética es una expresión que  contiene uno o más operandos y operadores aritméticos

• Los operandos pueden ser variables,  constantes o funciones que retornan un valor
– Generalmente se trata los registros de un µC como  variables

• Existen 9 operadores aritméticos:
– Operadores binarios: +, ‐, *, /, % – Operadores unarios: +, ‐, ++, ‐‐

Operadores
Operador * / % + ‐ +(unario) ‐(unario) Operación Multiplicación División Modulo Suma Resta Positivo Negativo Ejemplo x * y x / y x % y x + y x – y + x ‐x Resultado Producto de x por y Cociente de x entre y Residuo de x entre y Suma de x más y Resta de x menos y Valor de x Valor opuesto de x

Conversiones implícitas
• En algunas expresiones, el tipo de un  operando será temporalmente “promovido” al  tipo más grande de operando int x float z = x float = 10; y = 2.0, z; * y; //x es promovido a durante la operación

El tipo más pequeño es convertido al tipo  más grande en la expresión

Jerarquía de conversión implícita

Incremento y decremento
Operador ++ ‐‐ Operación Incremento Decremento Ejemplo x++ ++x x---x Resultado Usa x y luego incrementa por 1 Incrementa x por 1 y luego lo usa Usa x y luego decrementa por 1 Decrementa x por 1 y luego lo usa Ejemplo con prefijo

Ejemplo con sufijo

x = y = //y //x

5; (x++) + 5; = 10 = 6

x = y = //y //x

5; (++x) + 5; = 11 = 6

Sentencias de asignación
Definición: una sentencia de asignación es una sentencia que  asigna un valor a una variable

• Hay dos tipos de sentencias de asignación:
– Asignación simple
• variable = expresión;

La expresión se evalúa y luego se asigna a la variable

– Asignación compuesta
• variable = variable operador expresión;

La variable aparece de los dos lados del igual

Operadores de asignación
Operador = += ‐= *= /= %= &= ^= |= <<= >>= Asignación  compuesta Operación Asignación Ejemplo x = y x += y x ‐= y x *= y x /= y x %= y x &= y x ^= y x |= y x <<= y x >>= y Resultado Asigna a x el valor de y x = x + y x = x – y x = x * y x = x / y x = x % y x = x & y x = x ^ y x = x | y x = x << y x = x >> y

Operadores relacionales
Operador < <= > >= == != Operación Menor que Menor o igual que Mayor que Mayor o igual que Igual a Diferente de Ejemplo x < y x <= y x > y x >= y x == y x != y Resultado 1 si x es menor que y, sino 0 1 si x es menor o igual a y, sino 0 1 si x es mayor que y, sino 0 1 si x es mayor o igual a y, sino 0 1 si x es igual a y, sino 0 1 si x es diferente de y, sino 0

Diferencia entre = y ==
• = es el operador de asignación
x = 5 //Asigna 5 a la variable x

• == es el operador relacional “igual a”
x == 5 //REVISA si x es igual a 5

Operadores Lógicos
Operador && || ! Operación AND Lógico OR Lógico NOT Lógico Ejemplo x && y x || y !x Resultado 1 si x ≠ 0 y y ≠ 0, sino 0 0 si si x = 0 y y = 0, sino 1 1 si x =0, sino 0

Cualquier valor diferente de cero es interpretado como TRUE (Verdadero). Un 0 siempre es falso.

Operadores Lógicos de bits
Operador & || ^ ~ Operación AND (bits) OR (bits) XOR (bits) NOT (bits) Ejemplo x & y x | y x ^ y ~x Resultado (para cada bit en el dato) 1, si hay un 1 en ambos x,y 0, si hay un 0 en uno o ambos x,y 1, si hay un 1 en x O y 0, si hay un 0 en ambos x,y 1, si hay un 1 en x O y, pero no en los dos 0, si hay un 0 ó 1 en ambos x,y 1, si hay 0 en x 0, si hay 1 en x

• La operación se lleva a cabo en cada bit del  primer operando comparado al bit  correspondiente del segundo operando

Diferencias entre operadores lógicos & y &&
Tenga cuidado de no confundir el & con el &&.  No son intercambiables

• & es el operador AND entre bits
0b1010 & 0b1101 = 0b1000

• && es el operador Lógico AND
0b1010 && 0b1101 = 0b0001 (TRUE)

<No‐cero> && <No‐cero> = 1 (TRUE) •

Operador condicional
• Sintaxis:
(expr-prueba) ? hacer-si-cierto : hacer-si-falso;

Ejemplo:
int x = 5; (x % 2 != 0) ? printf(“%d es impar”, x) : printf(“%d es par”, x);

EXPRESIONES

Expresiones
• Representan un solo dato (ej: caracter,  número, etc) • Puede consistir de:
– Entidad simple (una constante, variable, etc) – Combinación de entidades conectadas por  operadores (+, ‐, +, /, etc)

Ejemplos de Expresiones
a + b x = y velocidad = dist / tiempo z = k c <= 7 x == 25 contador++ d = a + 5

SENTENCIAS

Sentencias
• Ocasionan una acción • Hay tres tipos de sentencias en C:
– Sentencias de expresión – Sentencias compuestas – Sentencias de control

Expresiones
• Una expresión es seguida por un ‘;’ • El ejecutar la sentencia de expresión hace que  la expresión sea evaluada Ej:
i = 0; i++; a = 5 + i; y = (m * x) + b;

Sentencias compuestas
• Un grupo de expresiones individuales  agrupadas por corchetes { y } • Puede contener cualquier tipo de sentencias,  inclusive otras compuestas • Permite incluir sentencias dentro de otras • NO termina con un ; • También llamados “bloques de código”

Sentencias de control
• Usadas para lazos, decisiones y pruebas  lógicas • Usualmente requieren otra expresión dentro  de ellas Ejemplo:
while (distancia < 400){ printf(“Siga corriendo”); distancia += 0.1; }

DECISIONES EXPRESIONES BOOLEANAS

Expresiones booleanas
• C NO tiene tipo de dato booleano • Las expresiones booleanas retornan un valor  entero (int)
– 0: Falso – 1: Verdadero (diferente de cero, no es 1 garantizado)

DECISIONES IF

IF
Sintaxis:
if (expresión) sentencia

• La expresión es evaluada por un valor  booleano: Verdadero (≠ 0) ó Falso (= 0) • Si expresión es verdadero se ejecuta la  sentencia

IF ‐ Diagrama
Sintaxis:
if (expresión) sentencia

IF ‐ Anidados
int potencia = 10; float banda = 2.0; float frecuencia = 146.52; if (potencia > 5){ if(banda == 2.0){ if((frecuencia > 144) && (frecuencia < 148)){ //Frecuencia adecuada!! } } }

DECISIONES  IF ELSE

IF ‐ ELSE
Sintaxis:
if (expresión) sentencia1 else sentencia2

• La expresión es evaluada por un valor  booleano: Verdadero (≠ 0) ó Falso (= 0) • Si expresión es verdadero se ejecuta la  sentencia1, sino se ejecuta la sentencia2

IF – ELSE ‐ Diagrama
Sintáxis:
if (expresión) sentencia1 else sentencia2

DECISIONES IF ELSE IF

IF – ELSE IF
Sintaxis:
if (expresión1) sentencia1 else if (expresión2) sentencia2 else sentencia3

• La expresión1 es evaluada por un valor  booleano: Verdadero (≠ 0) ó Falso (= 0) • Si es verdadero se ejecuta sentencia 1 • Si es falso, se evalúa la expresión 2 • Si es verdadero se ejecuta la sentencia2 • Si es falso se ejecuta la sentencia3

IF – ELSE ‐ Diagrama
Sintaxis:
if (expresion1) sentencia1 else if (expresion2) sentencia2 else sentencia3

DECISIONES  SWITCH

SWITCH
Sintaxis:
switch (expresion) { case const-expr1: sentencia1 … case const-expr2: sentencia2 default: sentencian+1 } else sentencia2

• “expresion” es evaluado contra cada valor de           const‐ expr en cada “case” • La sentencia en el “case” adecuado es la que se ejecuta • Si ninguna condición se cumple se ejecuta la sentencia en  el default

SWITCH Diagrama (pre‐definido)
Nótese que el comportamiento pre‐ definido del switch es el de  continuar con el siguiente caso una  vez que se ejecuta el presente.

SWITCH Diagrama (modificado)
Para evitar que luego de una  sentencia se ejecute la siguiente  automáticamente insertamos un  break a cada bloque de código  dentro de las sentencias. Esto permite que se ejecute  únicamente la porción de código  deseada.

SWITCH – Ejemplo 1
switch (puerto) { case 1: PORTA = 0xFF; break; case 2: PORTB = 0xFF; break; case 3: PORTC = 0xFF; break; case 4: PORTD = 0xFF; break; default: PORTA = 0x00; }

SWITCH – Ejemplo 2
switch (canal) Aplicar a los casos: 4, 5, 6 y 7 { case 4..7: printf(“Estación VHF”); break; case 9..12: printf(“Estación VHF”); break; case 3: Casos 3 y 8 “caen” al caso 13,  case 8: ya que no tienen un break; case 13: printf(“Señal Débil”); break; case 14..69: printf(“Estación UHF”); break; default: printf(“No hay señal disponible”); }

CICLOS  FOR

Ciclo FOR
Sintaxis:
for (expresion1; expresion2, expresion3) sentencia • expresion1 inicializa una variable para el conteo al  inicio del ciclo (ej: i = 0) • expresion2 es la condición de prueba, el ciclo  continuará mientras esta condición sea cierta (ej: i <=10) • expresion3 se ejecuta al final de cada iteración, 

usualmente para modificar la variable de conteo.  (Ej: i++)

Ciclo FOR Diagrama
for (expresion1; expresion2, expresion3) sentencia

Inicializar variable  para el ciclo

i = 0

Modificar variable  de ciclo

i++
Probar variable  ante  condición de salida

Ciclo FOR – Ejemplo 1
int i; for (i = 0; i < 5; i++) { PORTB = i; //Cada ciclo el valor de i varía por 1, y se cambia lo que se muestra en el puerto. }
Salida en el Puerto B: 0x00 0x01 0x02 0x03 0x04

Ciclo FOR Particularidades
• Cualquiera de las expresiones puede obviarse en  el for, pero deben aparecer los ‘;’ • Si expresion1 o expresion3 faltan, sus acciones  simplemente desaparecen, o no se lleva a cabo  ninguna acción. • Si la expresion2 falta, se asume que es  verdadera.
for ( ; { … } ; )
Este ciclo se ejecutará  indefinidamente, o hasta que  se salga de él con un break;

CICLOS  WHILE

Ciclo WHILE
Sintaxis:
while (expresion) sentencia

• Si expresion es verdadera, sentencia será  ejecutada. Luego expresion será re‐evaluada  para determinar si se ejecuta de nuevo  sentencia o no. • Es posible que sentencia nunca se ejecute si al  evaluar por primera vez expresion esta es  falsa.

Ciclo WHILE Diagrama
while (expresion) sentencia

Ciclo WHILE – Ejemplo
int i = 0;
Se inicializa la variable afuera del ciclo La condición se verifica al inicio de  while (i < 5) cada iteración { PORTB = i; Ciclo incrementado manualmente i++; //Cada ciclo el valor de i varía por 1, y se cambia lo que se muestra en el puerto. Salida en el Puerto B: } 0x00 0x01 0x02 0x03 0x04

Ciclo WHILE Particularidades
• La expresion SIEMPRE debe aparecer, no se  puede obviar. • Es utilizado más frecuentemente que el for para hacer ciclos infinitos.

while (1) { … }

Este ciclo se ejecutará  indefinidamente, o hasta que  se salga de él con un break;

CICLOS  DO WHILE

Ciclo DO‐WHILE
Sintaxis:
do sentencia while (expresion) • sentencia es ejecutada y luego expresion se 

evalúa para determinar si se debe o no ejecutar  de nuevo la sentencia. • sentencia SIEMPRE se va a ejecutar al menos  1 vez, aún cuando expresion sea falsa cuando  se inicie el ciclo.

Ciclo DO‐WHILE Diagrama
do sentencia while (expresion)

Ciclo DO‐WHILE – Ejemplo
int i = 0; do { PORTB = i; Ciclo incrementado manualmente i++; //Cada ciclo el valor de i varía por 1, y se cambia lo que se muestra en el puerto. Salida en el Puerto B: } while (i < 5) 0x00
La condición se verifica al  final de cada iteración 0x01 0x02 0x03 0x04 Se inicializa la variable afuera del ciclo

CICLOS  BREAK

CICLOS  CONTINUE

ARREGLOS

PUNTEROS

ESTRUCTURAS

ENUMERACIONES

MACROS

INTERRUPCIONES

DELAYS

ARCHIVOS ENLAZADOS

PUERTOS A/D

LEDS

LCD

EEPROM

TIMERS

RS‐232

SPI

PWM

STEPPERS

Sign up to vote on this title
UsefulNot useful