Está en la página 1de 60

LENGUAJE C

PARA SISTEMAS DEDICADOS

FUNDAMENTOS

Computadora
z

Se dispone de un S.O.

El S.O. inicia y configura los perifricos.

El S.O. brinda al usuario subrutinas para utilizar los


perifricos ( system calls ).

Microcontrolador
z

No posee un S.O.

El firmware debe iniciar los perifricos.

El usuario debe crear sus propias subrutinas para


utilizar los perifricos.

En lenguaje C para sistemas


dedicados no podemos hacer:
printf(Hola Mundo);

Llamada a la funcin main


zA

pesar que main es el punto de entrada


al programa, el firmware realiza tareas
previas a main. Entre ellas.
Cargar registros de configuracin.
z Limpiar zonas de RAM.
z Cargar el puntero de pila SP.
z

Cdigo en ensamblador
ORG

$EE00

configuracin de los perifricos


.
BRA

Cdigo en C
ORG

$EE00

cdigo de inicializacin
CALL/JMP
void
{

main

main(void)
cdigo escrito por el usuario
while(1)
{
}

Recursos

Arquitecturas de memoria

Modelo tiny ( Freescale )


MOV PORTA,PORTB

Modelo small ( Freescale )


LDA PORTA
STA var1

Pasaje de parmetros
Al igual que en un computadora, la pila se
utiliza para el pasaje de parmetros:
int

funcion(char a, int b, float c,.)

Ejemplo de pasaje de parmetros


usando la pila
void main(void)
{
int
dunga, donga;
dunga = 3;
donga = 5;
dunga = suma(dunga, donga);
donga = resta(dunga, donga);
}
int
{

sum(int s1, int s2)


return s1 + s2;

}
int
{

resta(int r1, int r2)


return r1 r2;

Pasaje de parmetros usando la pila


Ventajas:
z Al retornar de la
funcin se libera el
espacio de memoria.

Desventajas:
z Llamados anidados
a funciones pueden
limitar la RAM libre.

Uso del heap


Se hace declarando variables estticas
externas, mas conocidas como
VARIABLES GLOBALES.

Ejemplo de pasaje de parmetros


usando el heap
iInt dunga, donga;
void main(void)
{
dunga = 3;
donga = 5;
suma();
resta();
}
int
{

suma(void)
dunga = dunga + donga;

}
int
{

resta(void)
dunga = dunga - donga;

Pasaje de parmetros usando el


heap
Desventajas:
Ventajas:
z Pueden anidarse los
z La memoria usada
llamados a funciones
en el heap no puede
sin que crezca la pila
liberarse.
enormemente.

Uso de las funciones recursivas


void
factorial(int n)
{
if(n == 1)
return 1;
else
return factorial(n-1) *
n;
}
factorial(8);

Variables

Tipos de datos bsicos


En PC:
z char: 1 byte
z int: 2 4 bytes
z float: 4 bytes

En microcontroladores:
z char: 1 byte
z int: 2 bytes
z float: 4 bytes

Variantes de los tipos bsicos


z Se

admiten los modificadores signed y


unsigned.
z Tambin los modificadores short y long.
z El float puede no estar contemplado en
versiones gratuitas de los compiladores.

Operaciones bsicas
Aritmticas
z Suma +
z Resta
z Multiplicacin *
z Divisin /
z Resto %

Lgicas
z AND &
z OR |
z XOR ^

No necesariamente existe en
ensamblador una instruccin
para realizar cierta operacin
aritmtica. Ej: Los PIC 16F no
cuentan con instrucciones de
multiplicacin.
En ese caso el compilador debe
generar un algoritmo en assembler
que ejecute esa operacin.

Alternativas al tipo float


z En

general queremos representar cifras


del tipo: 20,3 mV
z Se trata de un nmero decimal de punto
fijo.
z Tampoco se dispone de representacin
en punto fijo.

Solucin:
Trabajar las mangintudes
multiplicadas x10, x100,
La cifra 20,3 se almacena como
203. As puede contenerse en un
tipo int.

Manejo de bits como variables


z Es

vlida aplicar una asignacin a un bit.


z Son vlidas las operaciones lgicas
entre bits |, & y ^.
z Ejemplos:
Freescale:
PTAD_PTAD4 = 1;
z PIC:
PORTBbits.RB4 = 0;
z

Volatile
Cdigo en C
void findecuenta(void)
{

if(time == 100)
{
time = 0;

}
}
z

Posible compilacin en
ensamblador:

findecuenta:
LDA
time

CMP
#!100
BNE

CLR
time

Volatile
z Si

time no cambia antes del if, la


compilacin anterior es vlida.
z Si time proviene del mdulo timer puede
modificarse entre que es cargada y el if.

Solucin
z

Cdigo en C:
volatile
int time;

Compilacin en
ensamblador:

void findecuenta(void)
{

if(time == 100)
{
time = 0;

}
}

findecuenta:

LDA
CMP
BNE
CLR

time
#!100

time

Resea de punteros
z Se

declaran y usan de la forma


convencional:

int *p;
char *p;
int hola;
p= &hola;
*p = 3;
( hola = 3 )

Punteros a RAM
int
int

hola;
*p;

p = &hola;
*p = 3;
p apunta a una posicin en RAM.

Punteros a ROM
char
char

*p;
texto[20] = Hola mundo;

p = texto;
p apunta a una posicin en ROM (FLASH).

Arquitectura Von Neumann


( Freescale )
La RAM y ROM estn en un
mismo mapa. Pueden accederse
por una nica clase de punteros.

Arquitectura Harvard ( PIC )


La RAM y ROM estn en mapas
diferentes. Se deben indicar a que
mapa apunta el puntero.

Punteros en micros Hardvard


z

Punteros a RAM:
char
hola;
char
*p;
p = &hola;

Punteros a ROM:

const char rom


char rom *p;
p = texto;

texto[20] = me duermo;

Entrada y salida

En la computadora
z Acceso

al I/O de entrada:
a = getch();
z Acceso al I/O de salida:
printf(Hola mundo);

Sistema dedicado
z Crear

bibliotecas de funciones:

LCD_printf(char *texto);
LCD_Dato(char caracter);
LCD_gotoxy(char x, char y);

sprintf resuelve todo


z

Genera textos.

Convierte datos int a


BCD.
Convierte datos float
a BCD.
Permite generar
salidas en formatos
muy complejos.

z
z

z
z

sprintf(texto,
Chau);
sprintf(texto, %d,
a);
sprintf(texto, %f, d);
sprintf(texto, V =
%02.1f mV, voltios);

Uso de los puertos de E/S


z

Acceso a pines individuales:

struct
{
byte
byte
byte
byte
byte
byte
byte
byte
}Bits;

PTAD0:1
PTAD1:1
PTAD2:1
PTAD3:1
PTAD4:1
PTAD5:1
PTAD6:1
PTAD7:1

Bits.PTAD0 = 1;

Mas sobre puertos


z

Acceso a todo el puerto:

typedef
union
{
byte
Byte;
struct
{
byte
byte
byte
byte
byte
byte
byte
byte
}Bits;
}PTADSTR;

PTAD0:1
PTAD1:1
PTAD2:1
PTAD3:1
PTAD4:1
PTAD5:1
PTAD6:1
PTAD7:1

PTADSTR.Byte = 0xff;
PTADSTR.Bits.PTAD0 = 1;
PTAD_PTAD0 = 1;

Manejo de perifricos
z En

PC usando system calls.


z En microcontroladores:
z

Freescale:
Asistentes de configuracin ( Processor Expert )
z Funciones de biblioteca.
z

En PIC:
z

Bibliotecas.

Processor Expert
z

Permite configurar
cualquier mdulo del
microcontrolador.

Processor Expert
z

Pueden configurarse
todos los parmetros
del mdulo.

Processor Expert
z
z

Genera el cdigo de
inicializacin
Genera funciones
para el manejo de
mdulo.
Genera vectores de
interrupcin.

Bibliotecas para PIC


z
z
z
z
z
z

A/D
Comparador
EEPROM
I2C
PWM

Temporizacin

Demoras cortas
z

Intercalando cdigo en ensamblador:

unsigned char

contador_1;

asm
{
LDA #$32
STA contador_1
dem_100us_1:
NOP
NOP
NOP
DBNZ
contador_1,dem_100us_1
}

Ttotal = 50 x 2s = 100s
Tint = 10 ciclos x 200ns = 2s

Demoras largas
z

Intercalando cdigo en ensamblador:

unsigned char contador_1;


unsigned char contador_2;
unsigned char contador_3;
for(contador_3 = 0; contador_3 < 100;
contador_3++)
for(contador_2 = 0; contador_2 < 20;
contador_2++)
{
asm
{
LDA #$C8
STA contador_1
dem_1s_1:
NOP
NOP
NOP
DBNZ contador_1,dem_1s_1
}
}

Ttotal = 100 x 10ms = 1s


Text = 20 x 500s = 10ms

Tint = 250 x 2s = 500s

Demoras largas
z

Mdulo timer con interrupciones:

void
main(void)
{
TI1_SetPeriodSec(1);
}
ISR(TI1_Interrupt)
{
(void)TPM1C0SC;
TPM1C0SC = 0x80;
(cdigo del usuario)
}

Cdigo bloqueante
Durante el llamado a una funcin el programa
no contina su ejecucin hasta retornar de
ella.
Ej:

void main(void)
{
demora_seg(1);
}

Cdigo no bloqueante
z

El programa puede continuar con otras tareas mientras una funcin no


entregue los resultados deseados.

Ej:
void
{

main(void)

ISR(TI1_Interrupt)
{
(void)TPM1C0SC;
TPM1C0SC = 0x80;
(cdigo del usuario)
}

Timer tick de la PC
z

Produce
interrupciones cada
1ms.
El usuario puede
generar eventos por
timer tick.
El usuario no debe
atender la
interrupcin.

void __fastcall TForm1::Timer1Timer(TObject


*Sender)
{
( cdigo del usuario )
}

Eventos de timer con


microcontroladores
z

La velocidad del
timer tick es
determinada por el
firmware.
Pueden generarse
eventos por timer
tick.
El usuario no debe
atender la
interrupcin.

void TI1_OnInterrupt(void)
{
( cdigo del usuario )
}

Interrupciones

Arquitectura PIC
z
z

Existen 1 2 vectores
de interrupcin.
El usuario debe
determinar con un if que
perifrico dispar la
interrupcin.

#pragma code low_vector=0x18


void interrupt_at_low_vector(void)
{
_asm
GOTO low_isr
_endasm
}
#pragma code
#pragma interruptlow low_isr
void low_isr(void)
{
}

Arquitectura Freescale
z El

Processor Expert resuelve buena


parte del cdigo.
z Existen vectores independientes para
cada evento y perifrico.
z El usuario no debe atender una
interrupcin. El Processor Expert genera
el cdigo que lo hace.

Evento de conversin A/D


word AD1_OutV;
ISR(AD1_Interrupt)
{
((TWREG*)(&AD1_OutV))->b.high = ADC1RH;
((TWREG*)(&AD1_OutV))->b.low = ADC1RL;
OutFlg = TRUE;
AD1_OnEnd();
ModeFlg = STOP;
}
void AD1_OnEnd(void)
{
unsigned int medicion;
}

CHAU!

También podría gustarte