Вы находитесь на странице: 1из 25

14/08/2014

Programacin C para AVR


Programacion C
Escuela Militar de Ingenieria
Ing. Germn Pereira Muoz

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

14/08/2014

Herramientas de Programacion

Editor
Compilador
Linker
Loader
Debugger

07/22/10

Integrated
Development
Environment
Algunas veces solo es
una interface para
comandos basicos:
Programmers Notepad
[WinAVR]

Ing. Germn Pereira Muoz


Programacion C para AVR

WinAVR
WinAVR es un ejecutable, pertenece a las
herramientas de desarrollo (open source
software) para Atmel AVR de la serie de
microprocesadores RISC para plataforma
Windows. Incluye GNU GCC compilador
para C y C++.
http://winavr.sourceforge.net/
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

14/08/2014

Comentarios en C
/* Comentarios
de varias
lineas */
//Comentarios para fin de linea

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

Includes
Include es un archivo tipicamente es un archivo
cabecera que contiene declaraciones
#include <avr/io.h>
Es un archivo include de sistema estandar

#include "mystuff.h"
Archivo include para un proyecto especifico

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

14/08/2014

Definiciones
#define simbolo cualquier asignacion
Esto se llama macro
Define a cualquier cosa para ser un cadena
estring de texto
Ejemplo:
#define FALSE 0
#define Cadena hola
#define PI 3.1416
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

Prototipos de Funcion(Cabeceras)
Las Funciones deben ser declaradas antes de su uso:
Una declaracion no es mas que cabecera de la funcion no la funcion
en si
Las declaraciones de Funcion(cabeceras) puden ser incluidas en una
archivo include

La definicion de la funcion es incluida en el cuerpo de la funcion

void function_name(int, float); //cabecera


Retorno de tipo es requerido; void significa que no retorna nada
Tipos de Argumentos (los nombres no son necesarios, pero se puede
incluir los nombres si se decea)

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

14/08/2014

Main
Cualquier programa C necesita una funcion
llamada main
Generalmente definida (no declarada)
int main(void){
int x;
//variable local
x = add(3, 9); //llamada a funcion
return 0;
}

El cuerpo de programa se encuentra entre


laves { }
Esta funcion tradicionalmente retorna 0
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

Otras Funciones
Otras definiciones de funcion son
usualmente puestas por debajo de la funcion
main o en un archivo separado
int add(int a, int b){
return a+b;
}
Arguentos pasados
por valor a la
funcion
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

10

14/08/2014

Variables
Especificado por a tipo, scope, lifetime, y name
Tipo con char, int, float, etc
Los Tipos especiales de AVR como uint8_t, int16_t, etc

Scope son
Local (block) declaradas dentro de las funciones
Global (file) declaradas fuera de las funciones
Program (external) Usadas para enlazar entre varios archivos

Lifetime son
Automatic (por defecto para variables locales) (en el stack)
Static (por defecto para variables globales y de programa) (en la ram)
Dynamic (programa controlado de asignacion de almacenamiento) (en
la estructura de datos heap)

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

11

Asignacion de Variables
uint8_t x = 3; //asignacion e inicializacion externa
int8_t loquesea(uint_8 a)//parametro local automatico
{
int_8 negOne = 0xFF;
// local automatico
static int8_t serial = 1; //local statico
return (serial++) + a + negOne;
}

Locales automaticos existen solo cuando dura la


llamada de la funcion
Los datos globales y static son creados e inicializados
una sola vez en el programa; estos retiene valores entre
llamadas de funciones
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

12

14/08/2014

Literales
Los enteros pueden ser expresados en varias bases
decimal: 29, -13, 0
octal: 0377
hexadecimal: 0x34F2
binario: 0b011011
Characteres
'a'
String
Es un Strig terminado en NUL almacenado en
un ARRAY"
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

13

Arrays
Declaracion de ARRAYS
uint8_t edad[10];
int16_t temp[5];
int8_t ejemplo[] = {-1, 2, -5};

Si es posible los Arrays son Dinamicamente


asignados arrays, pero requieren una
funcion de asignacion de memoria
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

14

14/08/2014

Estructuras (struct)
Basicamente las Structuras no son mas que
coleccion de variables llamadas miembros
Las Variables dentro de la estructura no tienen el
mismo tipo
Declaracion general de una estructura:
struct structure_tag_name{
type member1;
type member2;
...
type memberX
};

07/22/10

struct structure_tag_name{
type member1;
type member2;
...
type memberX
} structure_variable_name

Ing. Germn Pereira Muoz


Programacion C para AVR

15

Ejemplo: struct
struct posicion {
int x;
int y;
}robot;
Tambien se puede utilizar lo siguiente:
robot.x=10;
robot.y=15;
O simplemente
robot={10,15};
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

16

14/08/2014

Enumeracion de Variables
Similar a #define donde se puede describir un conjunto de
constantes. Usando #define tenemos:
#define cero 0
#define uno 1
#define dos 2
La alternativa es usando una enumeracion usando enum:
enum (cero=0,uno, dos); //cero=0, uno=1; dos=2
La Enumercacion por defecto asigna los valores de 0

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

17

Ejemplo
Usando el siguiente ejemplo
int n;
enum (cero=0,uno, dos);
n=uno; //n=1
Se puede usar la enumeracion de la siguiente manera:
enum escapes { BELL = '\a', BACKSPACE = '\b', HTAB = '\t', RETURN = '\r',
NEWLINE = '\n', VTAB = '\v' };
o enum boolean { FALSE = 0, TRUE };
La ventaja usar enum sobre #define es que la variable solo es visible en el bloque
donde fue declarada
Ejemplo:
main() {
enum mes {Ene=1, Feb, Mar, Apr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dec};
//
^--tabla de enumeracion ^--lista de alias
printf("%d\n", mes=Sep); // Asigna un valor entero via el alias
// esta instruccion retorna 9
}
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

18

14/08/2014

Seleccion
if (condicin) si es verdadero;
En expresiones Aritmticas es verdadero si el resultado
es diferente de cero y falso cuando es 0

if (condicin) {
Si es verdadero;
}

else { //este bloque solo si es necesario


Si es falso;

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

19

Seleccion multiple
Intruccion switch
switch (condicion)
{ case exprecion constate }
Ejemplo:
switch (i/10)
{ case 0: { printf ("Numero menor a 10"); // A
break;}
case 1: { printf ("Numero menor a 20"); // B
break;}
case 2: { printf ("Numero menor a 30"); // C
break;}
default: { printf ("Numero mayor o igual a 40"); // D
break;}
}
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

20

10

14/08/2014

Repeticion
while (condicion) {
// repite el bucle si la condicion es verdadero
};
do{ // repite el bucle si la condicion es verdadera
} while (condicion);
for (inicio; condicion; incremento)
{ //repite el bucle mientras se cumple la condicion
}
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

21

Puertos de E/S
DDRx - Este registro determina la direccion (input/output)
de los pins en port[x]
A '0' bit en DDR pone al pin del puerto como entrada (input)
A '1' bit en DDR pone al pin del puerto como salida (output)
PORTx - Este registro contienen el estado para salida
de los pines en port[x]
A '0' bit pone al pin del puerto como salida=0 (LOW ~0V)
A '1' bit pone al pin del puerto como salida=1 (HIGH ~5V)
PINx - Este registro contiene el estado de entrada de los pines en port[x]
A '0' bit indica que el pin del puerto es = 0 (LOW ~0V)
A '1' bit indica que el pin del puerto es = 1 (HIGH ~5V)
La X puede ser reemplazada por A,B,C,D,E,F, o G dependiendo del puerto
designado.
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

22

11

14/08/2014

Instrucciones AVR-GCC
En el Lenguaje C de AVR-GCC, los puertos pueden ser atendidos usando dos
comandos

inb()
lectura de byte

outb()
salida de byte
Ejemplo:
outb(DDRB, 0xFE); conf. el bit menos significativo del PORTB como entrada
a = inb(PINB);
Lectura del estado de entrada de los pines del PORTB

inb() y outb() pueden ser usados cuando se intenta leer o escribir


varios bits en un registro a la vez.

cbi() pone en cero un bit

sbi() pone en uno un bit


Ejemplo:
sbi(DDRD, 7);
// coloca PD7 como salida
sbi(DDRD, 0);
// coloca PD0 como salida
cbi(DDRD, 4);
// coloca PD4 como entrada
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

23

Puertos
PORT E/S y manipulacion de bit
PORTB = 0xFF;
GICR |= (1<<INT0);
PORTB &= ~((1<<5)|(1<<7));
PORTB &= ~(_BV(5)|_BV(7));
_BV(b) es un macro para (1<<b)
uint8_t pins = PIND;
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

24

12

14/08/2014

Testeando Bits
if (PIND & _BV(4)){
//bit 4 en uno
}
if (~PIND & _BV(4)){
//bit 4 en cero
}
if (!(PIND & _BV(4))){
//bit 4 en cero
}

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

25

Interrupciones
sei() y cli() habilitan o deshabilitan las
interrupciones
Para preservar el estado de la interrupcion
activa se puede usar:
uint8_t sreg = SREG;
cli();

SREG = sreg;
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

26

13

14/08/2014

Uso en C de los Registros


Los Procedimientos pueden usar libremente los registros
R18-R27, R30-R31
Si se llama una funcion C desde assembler, este seguro de salvar
estos registros si el contenido es importante

Los Procedimientos pueden salvar los registros R2-R17,


R28-R29
La funciones en Ensamblador llamadas desde C deben salvar sus
registros

R0 es un registro temporal y puede ser usado libremente


R1 es siempre usado en el codigo C
En una funcion en lenguaje ensamblador llamada desde C se debe
estar seguro de limpiar este registro antes del retorno

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

27

Llamada a funciones en C
Los Argumentos son pasados a los pares de
registros

Arg1 esta en R25:R24 (byte data en R24)


Arg2 esta en R23:R22

Arg9 esta en R9:R8


Para argumentos adicionales son colocados el pila
de datos (data stack)

El retorno de valores esta en los registros R25:R24


(datos de 8-bit si sign/zero), R25-R22 (32-bit), y
R25-R18 (64-bit)
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

28

14

14/08/2014

Punteros
Los punteros son variables que contienen la
direccion de datos
uint8_t num = 5; //una variable uint8
uint8_t * numPtr; //un puntero a un valor
uint8
Operador de Direccion
numPtr = &num; //direccion de variable
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

29

Punteros y Arrays
Los Nombres de Array son punteros
constantes
El nombre, representa la direccion base
de un array, pero solo como valor
int16_t numbers[4] = {5, 7, -2, 6};
int16_t * aPtr;
numbers
aPtr = numbers;
5
7 -2
aPtr = &numbers;
Las ultimas 2 son identicas aPtr
0060

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

El Array es almacenado en
la direccion $0060 - $0067
30

15

14/08/2014

Aritmetica de Punteros
bytes
5

42
7

-2

int8_t bytes[4]
= {5, 7, -2, 6};
int8_t * aPtr = bytes;
aPtr
5
0060
PORTB = *aPtr;
-2
PORTB = *(aPtr+2);
*(aPtr+1) = PIND;
aPtr
42
5 aPtr++;
0061
PORTB = *(aPtr-1);
aPtr+=2;
aPtr
6 PORTB = *aPtr;
0063

07/22/10

Aritmetica de Punteros
respecto al tamao de los
datos apuntados
p+1 es uno {byte,
word, double word,
etc} pasa donde p
apunta dependiendo
del tipo de datos
Solo soporta adicion y
sustraccion

Ing. Germn Pereira Muoz


Programacion C para AVR

31

Parametros por Referencia


La funciones en C con
llamada por valor
void func_v(char x){
PORTB = x;

func_v(a);
}

Se puede pasar y recivir la


direccion de un dato,
resultando la llamada por
referencia
char a;
func_r(&a);
07/22/10

void func_r(char * x){


*x = '$';
}
Ing. Germn Pereira Muoz
Programacion C para AVR

32

16

14/08/2014

Cadena de Caracteres (Strings)


Los Strings son implementados en arrays de
caracteres
p
char p[6]; //no inicializado
char q[6] = "Joe"; q
//Usa 4 de lo 6 bytes

?? ?? ?? ?? ?? ??

4A 6F 65 00 ?? ??

NUL

Los Arrays pueden ser implicitamente creados


como un puntero
4A 6F 65
n
char * n = "Joe";

00

07/22/10

33

Ing. Germn Pereira Muoz


Programacion C para AVR

Datos en la Flash
#include <avr/pgmspace.h>
prog_uint16_t myData[]
= {874, 299, 14987, 37};
prog_char Texto[] = Hola Mundo";
Esto crea datos en la memoria de programa
(flash)
Debe ser una asignacion statica

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

34

17

14/08/2014

Macros de Datos de Programa


uint16_t x = pgm_read_word(miDato+2);
for (i=0; i<3; i++)
char y = pgm_read_byte(&Texto[i]);

Estos macros requieren que la direccion


(address) los datos sea accedida
La direccion de un Array es una direccion
miDato+2 es lo mismo que &miDato[2]
&Texto[i] es lo mismo que Texto+i

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

35

Funciones para String de la Memoria


de Programa
Adicionando _P a una funcion estandar para
usar los string de la memoria programa
int n = strlen_P(Texto);

El destino de los strings debe ser la RAM


strcpy_P(ramStr, Texto);

Use PGM_P para declarar un puntero a string


en la memoria de programa
PGM_P pptr = Texto;
char c;
while (c =
pgm_read_byte(pptr++)){...
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

36

18

14/08/2014

Delays
#define F_CPU 4000000UL
#include <avr/delay.h>
_delay_us(93);
Maximo delay: 768 us / F_CPU en MHz

_delay_ms(10);
Maximo delay: 262.14 ms / F_CPU en MHz.

_delay_loop_1(24);
Usa un contador de 8 bit, 3 ciclos por iteracion
Pasa 0 para un maximo de (256) iterationes

// 4 MHz
Numero de bucles
de iteracion(para
implementar el
delay) esta basado
en la velocidad del
procesador

_delay_loop_2(1039);
Usa un contador de 16 bit, 4 cicles por iteracion
Pasa 0 para un maximo de (65536) iteraciones

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

37

math.h
Incluye todas las funciones matematicas
necesarias
fabs, sqrt, sin, asin, ceil, floor,
Nota: trabaja con datos de punto flotante, y tambien
con datos tipo entero requeridos en la mayodira de
lo programas de AVR

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

38

19

14/08/2014

Manejo de Interrupciones
#include <avr/interrupt.h>
ISR(interrupt name)
{
//codigo de interrupcion
//No se necesita salvar ni restaurar el estado del CPU, este
proceso es automtico
//la instruccion RETI es adicionada automaticamante

}
In addition to defining the handler, you need to
enable/disable interrupts
GICR |= (1<<INT0); //por ejemplo
sei();
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

39

Ejemplo de
Programa
Diagrama
Circuital
iotest.c

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

40

20

14/08/2014

Programa Ejemplo iotest.c


archivo: global.h
#ifndef GLOBAL_H
#define GLOBAL_H
// global AVRLIB defines
#include "avrlibdefs.h"
// global AVRLIB types definitions
#include "avrlibtypes.h"
// project/system dependent defines
// CPU clock speed
#define F_CPU
16000000
//#define F_CPU
14745000
//#define F_CPU
8000000
//#define F_CPU
7372800
//#define F_CPU
4000000
//#define F_CPU
3686400

// 16MHz processor
// 14.745MHz processor
// 8MHz processor
// 7.37MHz processor
// 4MHz processor
// 3.69MHz processor

#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per


microsecond
#endif
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

41

########### change this lines according to your project ##################


#put the name of the target mcu here (at90s8515, at90s8535, attiny22, atmega603 etc.)
MCU = atmega16
#put the name of the target file here (without extension)
TRG = iotest
#put your C sourcefiles here
SRC = $(TRG).c
#put additional assembler source file here
ASRC =
#additional libraries and object files to link
LIB =
#additional includes to compile
INC =
#assembler flags
ASFLAGS = -Wa, -gstabs
#compiler flags
CPFLAGS = -g -Os -Wall -Wstrict-prototypes -I$(AVRLIB) -Wa,-ahlms=$(<:.c=.lst)
#linker flags
LDFLAGS = -Wl,-Map=$(TRG).map,--cref
########### you should not need to change the following line #############
include $(AVRLIB)/make/avrproj_make
buffer.o : buffer.c
buffer.h
uart.o
: uart.c
uart.h
global.h
uart2.o : uart2.c
uart2.h
global.h
rprintf.o : rprintf.c
rprintf.h
Ing. Germn Pereira Muoz
a2d.o
: a2d.c
a2d.h
Programacion C para AVR
timer.o : timer.c
timer.h
global.h
pulse.o : pulse.c
pulse.h
timer.h
global.h
07/22/10
42
lcd.o
: lcd.c
lcd.h
global.h

Programa Ejemplo
iotest.c
archivo: make

21

14/08/2014

Programa Ejemplo
iotest.c
Cabecera
//----- Archivos Include --------------------------------------------------------#include <avr/io.h>
// include I/O definiciones (nombres : port, pin , etc)
#include <avr/signal.h>
// include nombres "signal" (nombres
interrupcion)
#include <avr/interrupt.h> // include soporte para interrupciones
#include "global.h" // include configuraciones globales
#include <avr/delay.h>

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

43

Programa Ejemplo
iotest.c

Funcion main

//----- Inicio de Codigo -----------------------------------------------------------int main(void)


{
u08 a,cont;
// declarando variables
outb(DDRB, 0xFE); // configura el bit menossignificatibo del PORTB como entrada
a = inb(PINB);
// Lectura del estado de entrada de los pines del PORTB
outb(DDRC, 0xFF); // configura todo el PORTC como salida
outb(PORTC, 0xF0);
// PORTC PC4-7 en HIGH Y PC0-3 to LOW
sbi(DDRD, 7);
// configura PD7 como salida
sbi(DDRD, 0);
// configura PD0 como salida
while(1)
{
BUCLE INFINITO
}
return 0;
}
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

44

22

14/08/2014

Programa Ejemplo
iotest.c

Bucle infinito

while(1)
{
for(cont=0;cont<255;cont++)
{
outb(PORTC, cont);
sbi(PORTD, 0);
_delay_ms(50);
cbi(PORTD, 0);
_delay_ms(50);
a = inb(PINB);
if(a==1)
{
sbi(PORTD, 7); // sets PD7 to output a 1
}
else{
cbi(PORTD, 7); // sets PD7 to output a 0
}
}
}
07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

45

Programmers Notepad

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

46

23

14/08/2014

Programmers Notepad

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

47

Simulacin en AVRStudio

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

48

24

14/08/2014

Simulacin en AVRStudio

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

49

Simulador/Debugger
Para trasar atravez del codigo assembler, se
necesita usar disassembly window

Puntero de
depuracio
n

07/22/10

Ing. Germn Pereira Muoz


Programacion C para AVR

50

25

Вам также может понравиться