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

LENGUAJE C

PARA SISTEMAS DEDICADOS

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 ( system calls ).

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 configuracin de los perifricos . BRA $

Cdigo en C
ORG $EE00 cdigo de inicializacin CALL/JMP void { main(void) cdigo escrito por el usuario while(1) { } } main

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 { } int { } resta(int r1, int r2) return r1 r2; sum(int s1, int s2) return s1 + s2;

Pasaje de parmetros usando la pila


Ventajas: Al retornar de la funcin se libera el espacio de memoria. Desventajas: 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 { } int { } resta(void) dunga = dunga - donga; suma(void) dunga = dunga + donga;

Pasaje de parmetros usando el heap


Desventajas: Ventajas: Pueden anidarse los 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: 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 CMP BNE CLR time #!100 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 int hola; *p;

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

Punteros a ROM
char char p = texto; p apunta a una posicin en ROM (FLASH). *p; texto[20] = Hola mundo;

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 char rom *p; p = texto; texto[20] = me duermo;

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 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


Acceso a todo el puerto: typedef union { byte Byte; struct { byte byte byte byte byte byte byte byte }Bits; }PTADSTR; PTADSTR.Byte = 0xff; PTADSTR.Bits.PTAD0 = 1; PTAD_PTAD0 = 1;

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

Manejo de perifricos
En PC usando system calls. 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

Temporizacin

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 }

Ttotal = 50 x 2s = 100s Tint = 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 } } Ttotal = 100 x 10ms = 1s Text = 20 x 500s = 10ms

Tint = 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

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!

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