PDF de programación - Lenguaje C para sistemas dedicados

Imágen de pdf Lenguaje C para sistemas dedicados

Lenguaje C para sistemas dedicadosgráfica de visualizaciones

Publicado el 13 de Octubre del 2019
964 visualizaciones desde el 13 de Octubre del 2019
818,8 KB
60 paginas
Creado hace 14a (24/02/2010)
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 periféricos.

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

periféricos ( system calls ).

Microcontrolador

No posee un S.O.

El firmware debe iniciar los periféricos.

El usuario debe crear sus propias subrutinas para

utilizar los periféricos.

En lenguaje C para sistemas
dedicados no podemos hacer:

printf(“Hola Mundo”);

Llamada a la función main

A pesar que main es el punto de entrada

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

Código en ensamblador

ORG

$EE00

…configuraci

configuracióónn de los

de los perif

perifééricos

ricos……

….

BRA

$

Código en C

ORG

$EE00

…código de inicialización…

CALL/JMP

main

main(void)

…código escrito por el usuario…

while(1)
{
}

void
{

}

Recursos
Recursos

Arquitecturas de memoria

Modelo tiny ( Freescale )

MOV PORTA,PORTB

Modelo small ( Freescale )

LDA PORTA
STA var1

Pasaje de parámetros

Al igual que en un computadora, la pila se

utiliza para el pasaje de parámetros:

int

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

Ejemplo de pasaje de parámetros
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 parámetros usando la pila

Ventajas:
Al retornar de la

función se libera el
espacio de memoria.

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

Uso del heap

Se hace declarando variables estáticas

externas, mas conocidas como
VARIABLES GLOBALES.

Ejemplo de pasaje de parámetros
usando el heap

iInt dunga, donga;

void main(void)
{

dunga = 3;
donga = 5;
suma();
resta();

}

int suma(void)
{

dunga = dunga + donga;

resta(void)

dunga = dunga - donga;

}

int
{

}

Pasaje de parámetros 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

factorial(int n)

void
{

if(n == 1)

return 1;

return factorial(n-1) *

else

n;

}

factorial(8);

Variables
Variables

Tipos de datos básicos

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 básicos

Se admiten los modificadores signed y

unsigned.

También los modificadores short y long.
El float puede no estar contemplado en
versiones gratuitas de los compiladores.

Operaciones básicas

Aritméticas
Suma +
Resta –
Multiplicación *
División /
Resto %

Lógicas
AND &
OR |
XOR ^

No necesariamente existe en
ensamblador una instrucción
para realizar cierta operación
aritmética. Ej: Los PIC 16F no
cuentan con instrucciones de

multiplicación.

En ese caso el compilador debe
generar un algoritmo en assembler

que ejecute esa operación.

Alternativas al tipo float

En general queremos representar cifras

del tipo: 20,3 mV

Se trata de un número decimal de punto

fijo.

Tampoco se dispone de representación

en punto fijo.

Solución:

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 válida aplicar una asignación a un bit.
Son válidas las operaciones lógicas

entre bits |, & y ^.

Ejemplos:

Freescale:

PTAD_PTAD4 = 1;

PIC:

PORTBbits.RB4 = 0;

Volatile

Código en C
void findecuenta(void)
{


if(time == 100)
{

time = 0;


}

}

Posible compilación en

ensamblador:

findecuenta:

LDA

CMP
BNE
CLR


time

#!100

time

Volatile

Si time no cambia antes del if, la

compilación anterior es válida.

Si time proviene del módulo timer puede
modificarse entre que es cargada y el if.

Solución

Código en C:
volatile

int time;

Compilación en

ensamblador:

void findecuenta(void)
{

findecuenta:



LDA
CMP
BNE
CLR

time
#!100

time


if(time == 100)
{

time = 0;


}

}

Reseña de punteros

Se declaran y usan de la forma

convencional:

*p;
int
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 posición en RAM.

Punteros a ROM

char
char

*p;
texto[20] = “Hola mundo”;

p = texto;

p apunta a una posición en ROM (FLASH).

Arquitectura Von Neumann

( Freescale )

La RAM y ROM están en un

mismo mapa. Pueden accederse
por una única clase de punteros.

Arquitectura Harvard ( PIC )

La RAM y ROM están en mapas
diferentes. Se deben indicar a que

mapa apunta el puntero.

Punteros en micros Hardvard

Punteros a RAM:

char
char
p = &hola;

hola;
*p;

Punteros a ROM:

const char rom
char
rom *p;
p = texto;

texto[20] = “me duermo”;

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:

union

Byte;

byte
byte
byte
byte
byte
byte
byte
byte

typedef
{

byte
struct
{

}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 periféricos

En PC usando system calls.
En microcontroladores:

Freescale:

Asistentes de configuración ( Processor Expert )
Funciones de biblioteca.

En PIC:

Bibliotecas.

Processor Expert

Permite configurar

cualquier módulo del
microcontrolador.

Processor Expert

Pueden configurarse
todos los parámetros
del módulo.

Processor Expert

Genera el código de

inicialización

Genera funciones
para el manejo de
módulo.

Genera vectores de

interrupción.

Bibliotecas para PIC

A/D
Comparador
EEPROM
I2C
PWM


Temporizacióónn
Temporizaci

Demoras cortas

Intercalando código en ensamblador:

unsigned char

contador_1;

asm
{
LDA #$32
STA contador_1

dem_100us_1:

NOP
NOP
NOP

Ttotal = 50 x 2µs = 100µs

Tint = 10 ciclos x 200ns = 2µs

DBNZ

}

contador_1,dem_100us_1

Demoras largas



Intercalando código 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 500µs = 10ms

Tint = 250 x 2µs = 500µs

Demoras largas

Módulo timer con interrupciones:

main(void)

void
{
TI1_SetPeriodSec(1);
}

ISR(TI1_Interrupt)
{

(void)TPM1C0SC;
TPM1C0SC = 0x80;

(código del usuario)

}

Código bloqueante

Durante el llamado a una función el programa

no continúa su ejecución hasta retornar de
ella.

Ej:

void main(void)
{

demora_seg(1);

}

Código no bloqueante

El programa puede continuar con otras tareas mientras una función no

entregue los resultados deseados.

main(void)

Ej:
void
{

}

ISR(TI1_Interrupt)
{

(void)TPM1C0SC;
TPM1C0SC = 0x80;

(código del usuario)

}

Timer tick de la PC

void __fastcall TForm1::Timer1Timer(TObject

*Sender)

{

}

( código del usuario )

Produce

interrupciones cada
1ms.

El usuario puede

generar eventos por
timer tick.

El usuario no debe

atender la
interrupción.

Eventos de timer con
microcontroladores

La velocidad del

timer tick es
determinada por el
firmware.

void TI1_OnInterrupt(void)
{

( código del usuario )

}

Pueden generarse

eventos por timer
tick.

El usuario no debe

atender la
interrupción.

Interrupciones
Interrupciones

Arquitectura PIC

Existen 1 ó 2 vectores

de interrupción.
El usuario debe

determinar con un if que
periférico disparó la
interrupción.

#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 código.

Existen vectores independientes para

cada evento y periférico.

El usuario no debe atender una

interrupción. El Processor Expert genera
el código que lo hace.

Evento de conversión A/D

word AD1_OutV;

ISR(AD1_Interrupt)
{

((TWREG*)(&AD1_OutV))->b.high = ADC1RH;
((TWREG*)(&AD1_OutV))->b.low = ADC1RL;
Out
  • Links de descarga
http://lwp-l.com/pdf16710

Comentarios de: Lenguaje C para sistemas dedicados (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad