Está en la página 1de 60

LENGUAJE C

LENGUAJE C
PARA SISTEMAS DEDICADOS
PARA SISTEMAS DEDICADOS
FUNDAMENTOS
FUNDAMENTOS
Computadora
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 ( systemcalls ).
Microcontrolador
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
A pesar que main es el punto de entrada
al programa, el firmware realiza tareas
previas a main. Entre ellas.
Cargar registros de configuracin.
Limpiar zonas de RAM.
Cargar el puntero de pila SP.
Cdigo en ensamblador
ORG $EE00
configuraci configuraci n n de los de los perif perif ricos ricos
.
BRA $
Cdigo en C
ORG $EE00
cdigo de inicializacin
CALL/JMP main
void main(void)
{
cdigo escrito por el usuario
while(1)
{
}
}
Recursos
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
Desventajas:
Llamados anidados
a funciones pueden
limitar la RAM libre.
Ventajas:
Al retornar de la
funcin se libera el
espacio de memoria.
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
Ventajas:
Pueden anidarse los
llamados a funciones
sin que crezca la pila
enormemente.
Desventajas:
La memoria usada
en el heap no puede
liberarse.
Uso de las funciones recursivas
void factorial(int n)
{
if(n == 1)
return 1;
else
return factorial(n-1) *
n;
}
factorial(8);
Variables
Variables
Tipos de datos bsicos
En PC:
char: 1 byte
int: 2 4 bytes
float: 4 bytes
En microcontroladores:
char: 1 byte
int: 2 bytes
float: 4 bytes
Variantes de los tipos bsicos
Se admiten los modificadores signed y
unsigned.
Tambin los modificadores short y long.
El float puede no estar contemplado en
versiones gratuitas de los compiladores.
Operaciones bsicas
Aritmticas
Suma +
Resta
Multiplicacin *
Divisin /
Resto %
Lgicas
AND &
OR |
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
En general queremos representar cifras
del tipo: 20,3 mV
Se trata de un nmero decimal de punto
fijo.
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
Es vlida aplicar una asignacin a un bit.
Son vlidas las operaciones lgicas
entre bits |, & y ^.
Ejemplos:
Freescale:
PTAD_PTAD4 = 1;
PIC:
PORTBbits.RB4 = 0;
Volatile
Cdigo en C
void findecuenta(void)
{

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

}
}
Posible compilacin en
ensamblador:
findecuenta:
LDA time

CMP #!100
BNE
CLR time

Volatile
Si time no cambia antes del if, la
compilacin anterior es vlida.
Si time proviene del mdulo timer puede
modificarse entre que es cargada y el if.
Solucin
Cdigo en C:
volatile int time;
void findecuenta(void)
{

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

}
}
Compilacin en
ensamblador:
findecuenta:

LDA time
CMP #!100
BNE
CLR time
Resea de punteros
Se declaran y usan de la forma
convencional:
int *p;
char *p;
int hola;
p= &hola;
*p = 3; ( hola = 3 )
Punteros a RAM
int hola;
int *p;
p = &hola;
*p = 3;
p apunta a una posicin en RAM.
Punteros a ROM
char *p;
char 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
Punteros a RAM:
char hola;
char *p;
p = &hola;
Punteros a ROM:
const char rom texto[20] = me duermo;
char rom*p;
p = texto;
Entrada y salida
Entrada y salida
En la computadora
Acceso al I/O de entrada:
a = getch();
Acceso al I/O de salida:
printf(Hola mundo);
Sistema dedicado
Crear bibliotecas de funciones:
LCD_printf(char *texto);
LCD_Dato(char caracter);
LCD_gotoxy(char x, char y);
sprintf resuelve todo
Genera textos.
Convierte datos int a
BCD.
Convierte datos float
a BCD.
Permite generar
salidas en formatos
muy complejos.
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
Acceso a pines individuales:
struct
{
byte PTAD0:1
byte PTAD1:1
byte PTAD2:1
byte PTAD3:1
byte PTAD4:1
byte PTAD5:1
byte PTAD6:1
byte PTAD7:1
}Bits;
Bits.PTAD0 = 1;
Mas sobre puertos
Acceso a todo el puerto:
typedef union
{
byte Byte;
struct
{
byte PTAD0:1
byte PTAD1:1
byte PTAD2:1
byte PTAD3:1
byte PTAD4:1
byte PTAD5:1
byte PTAD6:1
byte PTAD7:1
}Bits;
}PTADSTR;
PTADSTR.Byte = 0xff;
PTADSTR.Bits.PTAD0 = 1;
PTAD_PTAD0 = 1;
Manejo de perifricos
En PC usando systemcalls.
En microcontroladores:
Freescale:
Asistentes de configuracin ( Processor Expert )
Funciones de biblioteca.
En PIC:
Bibliotecas.
Processor Expert
Permite configurar
cualquier mdulo del
microcontrolador.
Processor Expert
Pueden configurarse
todos los parmetros
del mdulo.
Processor Expert
Genera el cdigo de
inicializacin
Genera funciones
para el manejo de
mdulo.
Genera vectores de
interrupcin.
Bibliotecas para PIC
A/D
Comparador
EEPROM
I2C
PWM

Temporizaci
Temporizaci

n
n
Demoras cortas
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
}
T
total
= 50 x 2s = 100s
T
int
= 10 ciclos x 200ns = 2s
Demoras largas
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
}
}
T
total
=100 x 10ms =1s
T
ext
=20 x 500s =10ms
T
int
=250 x 2s =500s
Demoras largas
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
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
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
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
Interrupciones
Arquitectura PIC
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
El Processor Expert resuelve buena
parte del cdigo.
Existen vectores independientes para
cada evento y perifrico.
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
CHAU
!
!

También podría gustarte