Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

27
  Código C Eficiente para Sistemas Embebidos Página 1 CeTAD   Facultad de Ingeniería - UNLP Código C Eficiente para Sistemas Embebidos y Software Codewarrior (Basado en el Compilador de Freescale)  Cátedra de Circuitos digitales y Microprocesadores Autores: Ing. Jorge R. Osio Ing. Walter Aróztegui Ing. José A. Rapallini Octubre de 2011 Versión 2.0

Transcript of Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

Page 1: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 1

CeTAD – Facultad de Ingeniería - UNLP

Código C Eficiente para SistemasEmbebidos y Software Codewarrior

(Basado en el Compilador de Freescale) 

Cátedra de Circuitos digitales y Microprocesadores

Autores:Ing. Jorge R. OsioIng. Walter ArózteguiIng. José A. Rapallini

Octubre de 2011 Versión 2.0

Page 2: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 2

INDICE.

1. Código C Eficiente para Sistemas Embebidos…...…3 

1.1. Compilador de Código C a Código de Máquina1.1.1. Creación de Código C eficiente para el MC68HC08

1.1.1.1. Modelo del Registro de la CPU081.1.1.2. Tipos de datos Básicos1.1.1.3.  Variables locales Vs variables Globales1.1.1.4.  Variables de Página directa1.1.1.5.  Bucles1.1.1.6.  Estructuras de datos

1.1.1.7. Ejemplos1.1.1.7.1. Registro 11.1.1.7.2. Copia de datos 11.1.1.7.3. Copia de datos 21.1.1.7.4. Copia de datos 31.1.1.7.5. Bucle

1.1.2. Estructura de un programa en C

2.  Software CodeWarrior………...………………...12 

2.1. Creación de Proyectos………………………………122.2. Generación de código mediante Processor Expert..15 

2.3. Compilación y Emulación en Tiempo real ………..20

3.  Interrupciones en Lenguaje C…………………...24

3.1.  La directiva #pragma TRAP_PROC……………...243.2. La instrucción interrupt……………………………26

Page 3: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 3

1. Código C Eficiente para Sistemas Embebidos

1.1. Compilador de Código C a Código de Máquina

1.1.1. Creación de Código C eficiente para el MC68HC08

Comparado con los otros microprocesadores la Arquitectura del HC908 seadapta bien al lenguaje de programación en C. Tiene un conjunto de instruccionesefectivas con modos de direccionamiento que permiten la eficiente implementación deinstrucciones en C. El conjunto de instrucciones incluye instrucciones para el manejodel puntero de pila. Los modos de direccionamiento, incluyen direccionamientoindexado, modos con el índice incluido y el registro índice o el registro de puntero de

 pila. Estas características permiten acceso eficiente a variables locales.El lenguaje C es ideal para crear un programa para el micro HC08 [1], pero

  para producir el código de máquina mas eficiente, el programador debe construir el  programa cuidadosamente. En este contexto “Código Eficiente” significa tamaño de

código compacto y rápido tiempo de ejecución. A continuación se detallan algunassugerencias y consejos para ayudar al programador a escribir código C de manera queun compilador pueda convertirlo en código de maquina eficiente.

1.1.1.1. Modelo del Registro de la CPU08

Para visualizar mejor los consejos en la figura 1 se detalla el modelo deregistro del HC08.

Figura 1. Modelo del Registro del CPU08

  Acumulador: El acumulador es un registro de 8 bits de propósito general. LaCPU lo usa para almacenar los operando o resultados de operaciones.

  Registro Índice: El registro índice de 16 bits es llamado H:X y es usado por losmodos de direccionamiento indexado para determinar la dirección efectiva de unoperando. El registro indice puede acceder a 64 Kbytes de espacios de

Page 4: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 4

direcciones en este modo. El byte mas bajo X se usa para almacenar el operando para la multiplicación y división de instrucciones. H:X para el almacenamientode la ubicación de datos temporarios.

  Puntero de Pila: Los 16 bits del puntero de pila se usan para almacenar la

dirección de la próxima ubicación disponible sobre la pila. La CPU usa elcontenido del registro del puntero de pila como un índice para acceder aoperandos sobre la pila en modos de direccionamiento offset de puntero de pila.La pila puede se ubicada en cualquier dirección donde hay RAM en los 64 K 

 bytes de espacio de direcciones.  Contador de Programa: Los 16 bits del contador de programa contienen la

dirección de la próxima instrucción u operando a ser utilizado. El contador de programa puede acceder a 64 K bytes de espacio de direcciones.

  Registro de código de condición: Los 8 bits del registro de código de condicióncontienen el bit mascara de interrupción global y 5 flags (indicadores) queindican el resultado de la instrucción que ejecutada. Los bits 5 y 6 son

 permanentemente sesteados a 1 lógico.

Estos registros junto con los modos de direccionamiento se encuentran biendesarrollados en el Apunte “Descripción General de un Microcontrolador (CPU)” y esnecesario conocerlos bien para poder aprovechar al máximo los consejos para lacreación de código C eficiente.

1.1.1.2. Tipos de datos Básicos

Los tipos de datos básicos son los siguientes:

Tipos de datos Básicos Tamaño Rango sin signo Rango con signoChar 8 bits 0 a 255 -128 a 127Short int 16 bits 0 a 65535 -32768 a 32767Int 16 bits 0 a 65535 -32768 a 32767Long int 32 bits 0 a 4294967295 -2147483648 a 2147483647

La mejor performance en tamaño de código y tiempo de ejecución se puedelograr definiendo el tipo de datos mas apropiado para cada variable. Esto es apropiado

 para microcontroladores de 8 bits donde el tamaño de datos interno natural es de 8 bits.El tipo de datos preferido en C es el “int”. El estándar ANSI no define precisamente el

tamaño de los tipos de datos naturales, pero los compiladores para microcontroladoresde 8 bits implementan “int” como un valor de 16 bits con signo. Como losmicrocontroladores de 8 bits pueden procesar tipos de datos de 8 bits maseficientemente que de 16 bits. Los tipos de datos “int” y “long int” deben ser usados,

solo donde se requiere, por el tamaño de datos a ser representado. Las operaciones dedoble precisión y punto flotante son ineficientes y deben ser evitadas donde laeficiencia es importante. Esto quizás parece obvio, pero frecuentemente se pasa por altoy tiene un enorme impacto sobre el tamaño de código en tiempo de ejecución.

Como se sabe la magnitud del tipo de datos requeridos y el signo deben ser especificados. El estándar ANSI C especifica „int‟ con signo por defecto, pero el „char‟

no está definido y puede variar entre compiladores. Por lo tanto para crear código portable, el tipo de datos „char‟ no debe ser usado. Y para el tipo „char el signo debe ser 

definido explícitamente: „unsigned char‟ o „signed char‟. 

Page 5: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 5

Es buena práctica crear definiciones de tipos para estos tipos de datos en unencabezado de archivo que se incluye en todos los otros archivos. También vale la penacrear definiciones de tipos para todos los otros tipos de datos usados, por consistencia, y

 para permitir portabilidad entre compiladores. Se puede usar algo así:

typedef unsigned char UINT8;typedef signed char SINT8;typedef unsigned int UINT16;typedef int SINT16;typedef unsigned long int UINT32;typedef long int SINT32;

Una variable se usa en mas de una expresión, pero algunas de estas expresionesno requieren el tamaño de datos completo o con signo de la variable. En este caso elahorro se puede hacer definiendo la variable, o parte de la expresión que contiene la

variable, al tipo de datos mas apropiado.

1.1.1.3.  Variables locales Vs variables Globales

Las variables pueden estar clasificadas por su alcance. Las variables globalesson accesibles por cualquier parte del programa y son almacenadas permanentemente enRAM. Las variables locales son accesibles sólo por la función dentro de la cual sondeclaradas y son almacenadas en la pila.

Las variables locales por consiguiente sólo ocupan RAM mientras se ejecuta lafunción a la cual pertenecen. Su dirección absoluta no se puede determinar cuando el

código es compilado y conectado así es que son ubicadas en memoria relativa al punterode pila. Para acceder a las variables locales el compilador puede usar el modo dedireccionamiento del puntero de pila. Este modo de direccionamiento requiere un byteadicional y un ciclo adicional para acceder a una variable, comparado a la mismainstrucción en el modo de direccionamiento indexado. Si el código requiere variosaccesos consecutivos a las variables locales, entonces el compilador transferirá el

 puntero de pila al registro índice de 16 bits y usará direccionamiento indexado en lugar de este. El acceso ' estático ' modificado puede ser usado con variables locales. Estocausa que la variable local sea almacenada permanentemente en la memoria, como unavariable global, así es que el valor de la variable es preservado entre llamados afunciones. Sin embargo la variable local estática es sólo accesible por la función dentro

de la cual está declarada.Las variables globales son almacenadas permanentemente en memoria en unadirección absoluta determinada cuando el código es conectado. La memoria ocupada

 por una variable global no puede ser reusada por cualquier otra variable. De cualquier manera las variables globales no están protegidas, ya que cualquier parte del programa

  puede tener acceso a una variable global en cualquier momento. Esto da origen alasunto de consistencia de datos para las variables globales de más de un simple byte detamaño. Esto quiere decir que los datos variables podrían ser corrompidos si una partede la variable proviene de un valor y el resto de la variable proviene de otro valor. Losdatos inconsistentes aparecen cuando una variable global es accedida (leída o escrita)

 por una parte del programa y antes de que cada byte de la variable haya sido accedido el

  programa se interrumpe. Esto se puede deber a una interrupción de hardware por ejemplo, o un sistema operativo, si se usa uno. Si la variable global es entonces accedida

Page 6: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 6

 por la rutina de interrupción entonces pueden aparecer los datos inconsistentes. Esto sedebe evitar si se desea la ejecución confiable del programa y se logra frecuentementedeshabilitando las interrupciones al acceder a las variables globales.

El acceso 'estático' modificado también puede ser usado con variables globales.

Esto da algún grado de protección a las variables como restringir el acceso a la variable para esas funciones en el archivo en el cual la variable ha sido declarada.El compilador generalmente usará el modo de direccionamiento extendido para

acceder a las variables globales o el modo de direccionamiento indexado si sonaccedidas a través de un puntero. El uso de variables globales generalmente no resultasignificativamente más eficiente en código que las variables locales. Hay algunasexcepciones limitadas para esta generalización, una es cuando la variable global estáubicada en la página directa.

Sin embargo, el uso de variables globales impide que una función sea recursivao entrante, y frecuentemente no hace el uso más eficiente de RAM, lo cual es un recursolimitado en la mayoría de microcontroladores. El programador por consiguiente debe

hacer una elección meticulosa en decidir que variables definir como globales en elámbito. Las ganancias importantes en eficiencia algunas veces pueden obtenersedefiniendo justamente unas pocas de las variables, más intensivamente usadas, comoglobales en el ambiente, particularmente si estas variables están ubicadas en la páginadirecta.

1.1.1.4.  Variables de Página directa

El rango de direcciones $ 0000 a $ 00FF es llamado la página directa, la página  base o la página cero. En los microcontroladores M68HC08, la parte inferior de la

 página directa siempre contiene los registros I/O y de control y la parte superior de la página directa siempre contiene RAM. Después de un reset, el puntero de pila siemprecontiene la dirección $ 00FF. La página directa es importante porque la mayoría de lasinstrucciones del CPU08 tienen un modo de direccionamiento directo por medio del que

 pueden acceder a los operandos en la página directa en un ciclo de reloj menos que en elmodo de direccionamiento extendido. Además la instrucción de modo dedireccionamiento directo requiere un byte menos de código. Algunas instruccionesaltamente eficientes sólo surtirán efecto con operandos de la página directa. Estos son:BSET, BCLR, BRSET y BRCLR. La instrucción MOV requiere que uno de losoperandos esté en la página directa.

Un compilador no puede sacar ventaja del modo de direccionamiento directo

eficiente a menos que las variables sean explícitamente declaradas para estar en la  página directa. No hay en estándar ANSI modo de hacer esto y los compiladoresgeneralmente ofrecen soluciones diferentes. El compilador hiware usa una declaración#pragma:

#pragma DATA_SEG SHORT myDirectPageVarsUINT16 myDirectPageVar1; /* entero sin signo en página directa */#pragma DATA_SEG DEFAULT

Esto declara los segmentos de página directa myDirectPageVars que contienenla variable myDirectPageVar1 y puede ser accedida usando el modo de

direccionamiento directo. El programador debe acordarse de hacer la conexión alsegmento myDirectPageVars en una dirección de la página directa.

Page 7: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 7

La cantidad de RAM en la página directa es siempre limitada, por eso solo lasvariables más intensivamente usadas deberían estar ubicadas en la página directa.

Muchos I/O y registros de control están ubicados en la página directa y ellosdeberán estar declarados como tal, así el compilador puede usar el modo de

direccionamiento directo donde sea posible. Dos formas posibles de hacer esto son:Defina el nombre del registro y su dirección juntos:

#define PortA (*((volatile UINT8 *)(0x0000)))#define PortB (*((volatile UINT8 *)(0x0001)))

O define los nombres del registro en un segmento de página directa y define ladirección del segmento en tiempo de conexión:

#pragma DATA_SEG SHORT myDirectPagePortRegistersvolatile UINT8 PortA;

volatile UINT8 PortB;#pragma DATA_SEG DEFAULT

1.1.1.5.  Bucles

Si un bucle debe ser ejecutado menos de 255 veces, se usa 'unsigned char' parael tipo bucle contador. Si el bucle debe ser ejecutado más que 255 veces, se usa'unsigned int' para el bucle contador. Esto es porque la aritmética de 8 bits es máseficiente que la aritmética de 16 bits y la aritmética sin signo es mas eficiente que consigno.

Si el valor del bucle contador es irrelevante, entonces es más eficiente elcontador para el decremento y comparar con cero que para incrementar y comparar conun valor distinto de cero. Esta optimización no es efectiva si el bucle debe ser ejecutadocon el bucle contador igual a cero, como cuando el bucle contador se usa para indexar un arreglo de elementos y el primer elemento debe ser accedido.

Si se usa el bucle contador en expresiones dentro del bucle, entonces se debeguardar el tipo de datos más apropiado cada vez que se usa.

Cuando un bucle se ejecuta un número fijo de veces y aquel número es  pequeño, como tres o cuatro, es frecuentemente más eficiente no tener un bucle. Enlugar de eso, se escribe el código explícitamente tantas veces según lo solicitado. Estodará como resultado más líneas de código C pero a cambio generará menos código

ensamblador y puede ejecutarse mucho más rápido que un bucle. Los ahorros realesvariarán, dependiendo del código a ser ejecutado.

1.1.1.6.  Estructuras de datos

Al programar en C es fácil crear estructuras de datos complejas, por ejemplo unarreglo de estructuras, donde cada estructura contiene un número de tipos de datosdiferentes. Esto producirá código complejo y lento en un microcontrolador de 8 bits quetiene un número limitado de registros de CPU para usar por indexado. Cada nivel dereferencia resultará en una multiplicación del número de elementos por el tamaño delelemento, con el resultado probablemente puesto encima de la pila en orden, para hacer el siguiente cálculo. Las estructuras deberán ser evitadas donde sea posible y lasestructuras de datos mantenerse simples. Esto puede hacerse organizando datos en

Page 8: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 8

simples arreglos unidimensionales de un tipo de datos simple. Esto dará como resultadoun gran número de arreglos, pero el programa podrá acceder a los datos mucho másrápidamente. Si las estructuras son inevitables, entonces no deberán hacerse pasar comoun argumento de función o un valor de retorno de función, en lugar de esto deberán

 pasarse por referencia.

1.1.1.7. Ejemplos

Los siguientes ejemplos están basados en las siguientes definiciones de tipos:

typedef unsigned char UINT8;typedef signed char SINT8;typedef unsigned int UINT16;typedef int SINT16;

1.1.1.7.1. Registro 1

Este ejemplo muestra manipulación de bits para un registro en paginado directo(port A) y para un not en paginado directo (CMCR0). El Seteado o borrado de uno omas bits en una dirección que no es registro en el paginado directo requiere 7 bytes derom y 9 ciclos de CPU. El Seteado o borrado de un simple bit en un registro en el

 paginado directo requiere 2 bytes de rom y 4 ciclos de CPU. 

Código C CódigoEnsamblador

Bytes Ciclos

#define PORTA (*((volatile UINT8

*)(0x0000)))

#define CMCR0 (*((volatile UINT8

*)(0x0500)))

void

register1(void)

{

CMCR0 &= ~0x01; /* clr bit1 */

PORTA |= 0x03; /* set b1,2 */

PORTA &= ~0x02; /* clr bit2 */

}

LDHX #0x0500

LDA ,X

AND #0xFE

STA ,X

LDA 0x00

ORA #0x03

STA 0x00

BSET 0,0x00

RTS 

31212222

1

32223234

4

1.1.1.7.2. Copia de datos 1

Este es un ejemplo del uso inapropiado de „int‟ para la variable „i‟ que se usa

en el bucle contador y en el arreglo índice. El compilador es forzado a usar 16 bit consigno aritméticos para calcular la dirección de cada elemento de dataPtr[ ]. Esta rutinarequiere 50 bytes de ROM y con 4 Iteraciones del bucle, ejecutados en 283 ciclos deCPU.

Código C Código Ensamblador Bytes CiclosUINT8 buffer[4]; PSHAPSHX

11

22

Page 9: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 9

void

datacopy1(UINT8 * dataPtr)

{

int i;

for (i = 0; i < 4; i++)

{buffer[i] = dataPtr[i];

}

}

AIS #-2TSXCLR 1,XCLR ,XTSX

LDA 3,XADD 1,XPSHALDA ,XADC 2,XPSHAPULHPULXLDA ,XTSXLDX ,XPSHXLDX 3,SP

PULHSTA buffer,XTSXINC 1,XBNE *1INC ,XLDA ,XPSHALDX 1,XPULHCPHX #0x0004BLT *-39AIS #4

RTS

21211

2211211111113

1312211121322

1

22322

3322322222224

2424332232332

4

1.1.1.7.3. Copia de datos 2

En  este  ejemplo, el bucle contador y la variable son  optimizados  para  un „unsigned char'. Esta  rutina  ahora  requiere  33  bytes  de  ROM, 17  bytes  menos que en copia de datos 1. Con  cuatro  iteraciones, la copia de datos 2  ejecuta  en  180  ciclos deCPU, 103  ciclos  menos que en copia de datos 1. En  este  ejemplo  el  valor   del  buclecontador   es  importante; El   bucle debe ejecutarse  con  i = 0, 1, 2  y  3.   No se obtiene

  Ninguna mejora significante, en este caso, por  decrementar el bucle contador en lugar de incrementarlo. Tampoco, se obtiene ninguna mejora significante, en este caso, si lavariable „buffer‟ se ubica en la página directa: La instrucción „STA buffer, X‟ usadireccionamiento directo en lugar de extendido, ahorrando un byte de código y un ciclode CPU por iteración.

Código C CódigoEnsamblador

bytes Ciclos

UINT8 buffer[4];

void

datacopy2(UINT8 * dataPtr)

{UINT8 i;

for (i = 0; i < 4; i++)

PSHAPSHXPSHHTSX

CLR ,XLDA ,XADD 2,X

1111

112

2222

223

Page 10: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 10

{

buffer[i] = dataPtr[i];

}

}

PSHACLRAADC 1,XPSHAPULH

PULXLDX ,XTXATSXLDX ,XCLRHSTA buffer,XTSXINC ,XLDA ,XCMP #0x04BCS *-25AIS #3

RTS

11211

1111113111222

1

21322

2212214232232

4

1.1.1.7.4. Copia de datos 3

En este ejemplo, los datos son copiados sin usar un bucle. Esta rutina requiere23 bytes de ROM y se ejecuta en 36 ciclos de CPU. Ésta usa 10 bytes menos de ROM y144 ciclos menos de CPU que en copia de datos 2. Si se copiaran 8 bytes, entonces estemétodo requeriría 10 bytes más de ROM que copia de datos 2, pero se ejecutaría en 280ciclos menos de CPU. Aunque hay ahorros potenciales que se dan si la variable „buffer‟ está ubicada en la página directa, el compilador no saca mucha ventaja de ellos en este

caso.

Código C Código Ensamblador Bytes CiclosUINT8 buffer[4];

void

datacopy3(UINT8 * dataPtr)

{

buffer[0] = dataPtr[0];

buffer[1] = dataPtr[1];

buffer[2] = dataPtr[2];

buffer[3] = dataPtr[3];

}

PSHXPULHTAXLDA ,XSTA buffer LDA 1,XSTA buffer:0x1

LDA 2,XSTA buffer:0x2LDA 3,XSTA buffer:0x3RTS 

111132323

231

221243434

344

1.1.1.7.5. Bucle

Si sólo importa el número de iteraciones y no el valor del bucle contador, esmás eficiente el decremento del bucle contador y compárar la variable con cero. En esteejemplo la declaración „for‟ requiere 7 bytes de ROM, y el incremento y test del bucle

contador en dirección opuesta toman 6 ciclos de CPU por cada iteración. Esto ahorra 2  bytes de ROM y 9 ciclos de CPU por iteración comparada a la declaración „for‟ en

Page 11: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 11

copia de datos 2. De cualquier forma esta optimización no puede ser aplicada a copia de

datos 2 ya que el código dentro de este bucle es ejecutado con i= 4, 3, 2 y 1.

Código C Código Ensamblador Bytes Ciclos

Voidloop1(void)

{

UINT8 i;

for(i=4; i!=0; i--)

{

/* code */

}

}

PSHHLDA #0x04TSXSTA ,X

TSXDBNZ ,X,*-offsetPULHRTS 

12111211 

22222424 

1.1.2. Estructura de un programa en C

Un programa en C define una función llamada main. El compilador conecta el  programa con el código de arranque y las funciones de librería en un archivo"ejecutable", llamado para poder ejecutarlo en su target. En resumen, un programa en Cnecesita un ambiente de target para establecer e inicializar el código de arranque en eltarget que satisface estos requisitos.

En general, su rutina principal “main” realiza algunos pasos de inicialización yejecuta un bucle infinito. Como ejemplo, se examinará el archivo hello.c en el directorio

\icc\examples.08:#include < hc08.h>//#Include "vectors.c" //es un programa autónomo que provee los vectores de registros 

main () {setbaud (BAUD9600);

 printf  ("Hola Mundo\n");while (1) 

;

}

Como se puede ver, éste es un programa muy simple que coloca el baud rate a9600, usando una constante definida en el hc08.h. Esta constante es válida sólo si susistema usa un cristal de 10 Mhz para el HC08, así es que puede ser necesariomodificarlo. Luego, usa una función estándar C para imprimir "Hola Mundo," e ir a un

 bucle infinito.

El compilador del HC08, ICC08 incluye un Editor de aplicaciones GUI quegenera código de inicialización de periféricos vía una interfase.

Page 12: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 12

2.  Software CodeWarrior

El Codewarrior [5] es una herramienta de uso libre, que reúne un compilador, un

linkeador y un debugger de código assembler fuente, y que puede ser ampliada segúnlas necesidades del usuario.La versión "Standard Edition" ofrece ensamblado de código fuente (assembler)

en forma ilimitada y limitada a 16K bytes en código “C”, además provee capacidades de

Debugging muy interesantes aún para programadores avanzados.Esta herramienta poderosa, combina un Ambiente de Desarrollo Integrado de

Alta perfomance (I.D.E) con:

- Simulación Completa de Chip y programación de la memoria FLASH desde el sistemaEVAL08QTY.- Un Compilador ANSI C altamente optimizado y un Debugger en nivel fuente C

- Generación automática de código C con "Processor Expert" desde unidades.

Ejecutar una sección de programación o debugging con proyectos basados enentornos CodeWarrior IDE es tan simple como efectuar un doble "click" en el nombredel proyecto (El formato es "nombredelproyecto.mcp") desde el archivo almacenado.Comenzar un nuevo proyecto es un poco más complejo, pero los tutoriales, FAQs yguías rápidas de comienzo son fáciles de seguir y ayudan a construir un nuevo proyecto,usando "templates" pre-construidos, en muy poco tiempo.

Por otro lado, la nueva versión del entorno integrado de trabajo (IDE), elCodeWarrior 5.0 ha sido pensada para simplificar el manejo de este poderoso entorno

  por parte de usuarios  no habituados a los ambientes profesionales de desarrollo, cosaque no ocurría con las antiguas versiones de CodeWarrior  para HC08 y HCS08. 

Para mayor información de uso, ejemplos y tutoriales ver en el Web Site deFreescale (www.freescale.com en la sección Codewarrior).

2.1. Creación de Proyectos

Para mostrar como se crea un nuevo proyecto usando el codeWarrior serealizará un ejemplo que efectúe una interrupción en forma periódica, cada “n”

milisegundos, basado en el uso del Timer en modo TOV (Timer Overflow). Estesencillo programa servirá como base para ejecutar un número de tareas más complejas

en forma periódica de modo similar a como lo haría un sistema operativo más complejo.Primeramente se configura el sistema  EVAL08QTY   para trabajar con el MCUMC68HC908QY4 que es el microcontrolador disponible en la placa que viene con elkit del sistema.

Configurado el sistema EVAL08QTY , se procede a iniciar el programa en elsistema CodeWarrior 5.0 efectuando los siguientes pasos:

1) Al ejecutar el CodeWarrior IDE, se abrirá una ventana de opciones como se ve en lafigura 2. Se debe elegír la opción “Create New Project” para armar el nuevo proyecto.2) Se ingresará en la pantalla de configuración del proyecto donde se elegirá la opcióngeneración de lenguaje ASSEMBLY, y se le pondrá un nombre con extención “.mcp”,

según se puede ver en la figura 3. 

Page 13: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 13

Figura 2. Pantalla “Startup” con opciones de ayuda. 

Figura 3. Pantalla de configuración del proyecto. 

3) En la siguiente pantalla se debe configurar la familia y dispositivo en particular autilizar en el proyecto (MC68HC908QY4) según se puede ver en la figura 4. 

Page 14: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 14

Figura 4. Pantalla de configuración de Familia, dispositivo y tipo de conexión. 

Como se observa en la figura 4, se debe elegir la familia HC08, dispositivoMC68HC908QY4 y en cuanto a la conexión con la herramienta debe elegirse la opción“Mon08 Interface” ya que es la opción universal de conexión para los sistemas dedesarrollo como los EVAL08QTY, E-FLASH08, FLASH_POD y toda otra herramientaque no figure explícitamente en el listado de conexiones.

Figura 5. Pantalla de adición de archivos al proyecto. 

4) Al hacer click en el botón “siguiente” se  pasa a una pantalla (Figura 5) que permiteadicionar cualquier archivo al proyecto, para incluirlo en el trabajo. En este caso, sesaltea está opción siguiendo a la próxima pantalla.5) En la pantalla que se observa en la figura 6, se puede elegir la generación de códigode inicialización de los distintos periféricos asistida o no. En este caso se seleccionará lageneración de código asistida, por medio del aplicativo “Processor Expert”, que guía alusuario paso a paso en la inicialización de los distintos periféricos del MCU elegido.

Page 15: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 15

Figura 6. Pantalla de elección o no de generación de código asistido(Processor Expert).

6) Al hacer click en el botón “Finalizar”, se generarán todos los archivos del proyecto,se lanzará la pantalla principal de trabajo del mismo y se podrá ver una interfaz gráficacon los pines y los distintos módulos que constituyen el MCU (Figura 7).

2.2. Generación de código mediante Processor Expert 

Figura 7. Pantalla principal del proyecto e interfaz gráfica de

Generación de código (Processor Expert). 

Page 16: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 16

Ahora solo queda generar el código de inicialización del Timer para producir una interrupción periódica que será la base del sistema de disparo de tareas, inicializar los puertos I/O, los registros de configuración, etc.

Para hacer esto, se debe usar el generador de código asistido “Processor Expert”

haciendo click primeramente en el modulo CPU para configurar el Clock del sistema yotros aspectos como se observa en la figura 8. 

Figura 8. Pantalla del módulo de CPU. 

Para este ejemplo se debe configurar el módulo de CPU para:

• Clock ---- Externo ---- 9,8304Mhz (lo inyectará el EVAL08QTY  por pin OSC1).• LVI ----- Habilitado ---- 3V trip point ----- LVI deshabilitado en modo STOP.• Interrupciones Habilitadas.• Vector de Reset apuntando a la etiqueta “_Startup” • Pin de Reset externo no disponible.

Figura 9. Pantalla con los detalles de configuración del CPU.

A continuación se procede a configurar el módulo de Timer (TIM)ingresando al mismo como muestra en la figura 10. 

Page 17: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 17

Figura 10. Pantalla del Módulo de Timer. 

Ahora se debe configurar el módulo del TIMER según lo siguiente:• Prescaler = 32 ----- FBUS = 2,4576 MHz.• Período del timer = 100 ms• Modo de funcionamiento ----- Timer Overflow Interrupt (INT_TIMOvr).•

Overflow Interrupt = habilitado.• Nombre de la interrupción = isrINT_TIMOvr • Inicialización = Comienzo de la cuenta (arranque del timer).  

Figura 11. Pantalla de configuración del TIMER  

Una vez que se ha configurado el módulo de TIMER, se deben configurar los puertos I/O según lo siguiente:

PORTA ---- PTA0 ---- INPUT ----- PTA1/PTA7 DISABLE.

PORTB ---- PTB5 ---- OUTPUT --- PTB0 / PTB7 DISABLE. 

Page 18: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 18

Figura 12. Pantallas de configuración de puertos (PORTA / PORTB). 

Si luego se presiona el botón “Generation Code”, el generador de código del Processor Expert generará código y mostrará una ventana explicando los pasos a seguir  para incorporarlo efectivamente al resto del programa. 

Figura 13. Pantalla de generación de Código que produciráarchivos bajo el Nombre “MCUinit” para inicializar el MCU. 

Figura 14. Pantalla de ayuda para integrar el código generado al proyecto. 

Page 19: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 19

Según lo sugerido por la ventana de ayuda una vez generado el código, se procede a modificar y comentar lo siguiente:

Comentar en el archivo “Project.prm” la línea --- VECTOR 0 _Startup /* Resetvector. Con una barra cruzada y asterisco (/*) delante de la sentencia y luego salvarlo. • Descomentar en el archivo “main.asm” la línea “JSR MCU_int”   para que de estaforma en el programa principal se pueda invocar a la sub rutina MCU_int queninicializa al MCU.

Figura 15. Ventana con código a modificar para utilizarlo.

Luego de realizar esas modificaciones sugeridas por el   Processor Expert , sedeben introducir las líneas de código en la subrutina de interrupción por Timer Overflow (isrINT_TIMOvr)   para realizar, por ejemplo, un Toggle (inversión deestado) del puerto PTB5 cada vez que se atienda la interrupción propiamente dicha. Eneste punto se pueden poner todas las tareas en forma de llamado a subrutina que se iránejecutando una a una cada 100 ms. 

Page 20: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 20

Figura 16. Agregado de las líneas de código en la rutina de manejo de laInterrupción por Timer Overflow (isrINT_TIMOvr).

2.3. Compilación y Emulación en Tiempo real

Una vez introducido el código, se debe compilar haciendo click en el botón“Make” en la barra de proyecto o en la barra de herramientas general. Si no hay ningúnerror de compilación se estará en condiciones de pasar a la etapa de EMULACION ENTIEMPO REAL del programa.

Para realizar ello, primero se debe establecer una conexión entre el CodeWarrior 5.0 y el sistema de desarrollo  EVAL08QTY que se irá configurando a lo largo de lassiguientes pantallas luego de hacer click en el botón “Debugger” (fecha verde en la

 barra de proyecto).

Page 21: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 21

Figura 17. Pantalla de selección de la interfaz con el hardware a utilizar.

En la ventana “Interface Selection” se elige la opción “Class 1 – ICS Boardwith processor installed” y luego se debe presionar el botón “ok”. 

Figura 18. Pantalla de manejo de la conexión con el hardware (EVAL08QTY). 

Luego se debe configurar la siguiente pantalla eligiendo el número de puertoCOM en el que esté asignado el puerto utilizado por el  EVAL08QTY  para la conexiónPLACA – PC y se debe asignar un Baud Rate de 9600 Bps de acuerdo a lo configuradoen el sistema anteriormente.

Como se podrá observar en la figura, también se configurará la opción deborrado y grabación de la memoria FLASH del MCU en forma previa y automáticacada vez que se quiera entrar en el modo de Debugging (Emulación en Tiempo Real) yaque es la condición necesaria para que cualquier HC908 pueda trabajar como unaverdadera herramienta de desarrollo.

Page 22: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 22

Se debe hacer click en el icono “contact target with these sedttings....”  paraestablecer la comunicación con la placa EVAL08QTY y entrar al entorno de Debugging

 propiamente dicho.

Figura 19. Ventana de borrado y Programación de la Flash

Una vez que el sistema sortea las etapas de seguridad con éxito, aparecerá unaventana (Erase and Program Flash?)   preguntando por el borrado y grabación de laFLASH antes de ingresar al modo de Debugging propiamente dicho. Se debe hacer Click en el icono “Yes”   para proceder a borrar y grabar el programa en la memoria

flash e ingresar al modo Debugging.

Figura 20.- Pantalla de Debugging (Emulación en Tiempo Real).

En esta instancia se posee la pantalla principal de Debugging (Emulación enTiempo Real) y solo resta correr el programa haciendo Click en el icono con la“flechita verde”  (Run / Continue)   para poder ver la señal cuadrada de 200 ms deperíodo que se obtiene en el puerto PTB5 del QY4 en la placa EVAL08QTY , segúnse observa en la figura 21.

Page 23: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 23

Figura 21. Oscilograma de la señal de salida en PTB5. 

El sistema EVAL08QTY   puede soportar de igual forma, herramientas deentorno integrado como el CodeWarrior de Metrowerks, asi como, el WinIDE ICS08de P&E Microsystems sin modificación alguna.

Page 24: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 24

3  Interrupciones en Lenguaje C

El empleo de Interrupciones o ISR (Interrupt Service Routine, o Rutina de Serviciode Interrupciones) es indispensable en la programación de microcontroladores. Seutilizan tanto para responder a una interrupción externa, una interrupción del timer, delconversor A/D o de cualquier módulo existente en el microcontrolador que poseainterrupciones.

Hay dos mecanismos para escribir Interrupciones en C, uno es muy sencillo yfunciona solo en el compilador codewarrior y el otro es más genérico y es soportado por la mayoría de los compiladores en C. Las 2 formas mencionadas son:

• Usando la instrucción interrupt (Propietaria de Codewarrior)• Usando la directiva #pragma TRAP_PROC y el archivo de parámetros del Linker 

3.1  La directiva #pragma TRAP_PROC

Esta directiva le indica al compilador que una función es una INTERRUPCIÓN.Una ISR necesita cierto código especial de entrada y de salida que la hace diferente decualquier otra función.

Ejemplo:#pragma TRAP_PROCvoid Mi_INTERRUPCION(void) {...}

Una vez preparada la función que contiene el Código a ejecutarse durante lainterrupción, es necesario indicarle al Linker (programa que une todas los “archivos” de código en un único programa) que instale la dirección de esta función en el vector correspondiente. Para ello se debe editar el archivo de parámetros del linker correspondiente al modelo de compilación que se está empleando. Por ejemplo, si secompila un programa para el Micro GP32, este archivo se llamará GP32-FLASH.PRM

[6].El contenido es el siguiente:

NAMES END

SECTIONS/* Z_RAM = READ_WRITE 0x0040 TO 0x00FF; *//* 0xF0 to 0xFF reserved for Monitor stacking */Z_RAM = READ_WRITE 0x0040 TO 0x00EF;RAM = READ_WRITE 0x0100 TO 0x023F;ROM = READ_ONLY 0x8000 TO 0xFDFF;

PLACEMENTDEFAULT_ROM, ROM_VAR, STRINGS INTO ROM;DEFAULT_RAM INTO RAM;

Page 25: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 25

 _DATA_ZEROPAGE INTO Z_RAM;END

STACKSIZE 0x50

VECTOR ADDRESS 0xFFFE _Startup

El bloque titulado “SECTIONS” sirve para asignar nombres a las áreas de memoriadel micro. En el ejemplo anterior, se han definido los nombres Z_RAM para la memoriaaccesible con direccionamiento directo (hasta 0xFF), RAM para el resto de la memoriaRAM y ROM para la Flash, a excepción de las direcciones reservadas a los vectores.

El bloque titulado “PLACEMENT” permite ubicar las distintas secciones y

componentes del programa en áreas específicas de la memoria (RAM, Flash, etc)La instrucción “STACKSIZE” define el tamaño del stack (0x50 bytes en el ejemplo).

Finalmente, las instrucciones “VECTOR”   permiten especificar el contenido de losvectores de interrupción del micro. La instrucción VECTOR tiene el siguiente formato:

VECTOR ADDRESS <dirección_vector> <contenido_vector>

La <dirección_vector> es una de las direcciones donde están los vectores deinterrupciones del micro. Por ejemplo en un GP32, en la dirección 0xFFFE (y 0xFFFF)se almacena el vector de reset.

El valor <contenido_vector> puede especificarse como un valor absoluto en hexa ocon el nombre de la función. Opcionalmente en este caso también puede especificarseun offset.

Ejemplo:

VECTOR ADDRESS 0xFFFE 0x1000VECTOR ADDRESS 0xFFFE StartUpVECTOR ADDRESS 0xFFFE StartUp OFFSET 2

En este caso, la función que se ha definido con #pragma TRAP_PROC se llamaMi_INTERRUPCION. Si se desea usarla para atender las interrupciones del móduloTime Base (TBM) cuyo vector se encuentra en la dirección 0xFFDC, se debe escribir:

VECTOR ADDRESS 0xFFDC Mi_INTERRUPCION

Un programa completo que use el Timebase para generar una onda cuadrada por 

PTA7 tendría la siguiente forma:#define TBON 2#define TACK 8 //Ack del TBCR

#define ENABLE_INT {asm cli;}#define DISABLE_INT {asm sei;}

#pragma TRAP_PROCvoid Mi_INTERRUPCION (void){TBCR |= TACK; // Acknowledge IntPTA ^= 0x80; // invierte el estado de PTA7

}

Page 26: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 26

//*********************************************************************************//void main (void){CONFIG1 = 1; //Parar COPDDRA = 0xFF; //PTA todo salida

TBCR = 0x04; //Timebase divide por 8192ENABLE_INT //Habilitar las interrupcionesTBCR |= TBON; //Prender el Timebasewhile (1) { //Hacer nada}}

3.2  La instrucción interrupt

Code Warrior tiene una instrucción especial que no se encuadra dentro del estándar ANSI-C llamada “interrupt” que permite simplificar el proceso de definición de una

interrupción [7]. Debe usarse como si fuera un calificador de tipo pero seguida de unnúmero que especifica la entrada en la tabla de vectores de interrupción que contendrála dirección de la función que se está definiendo. Si no se especifica ese número, tiene elmismo efecto que TRAP_PROC y el vector debe definirse con la sentencia VECTOR en el archivo de parámetros del linker, tal como se vio antes.

Ejemplo:

interrupt 17 void Mi_INTERRUPCION();

Instala Mi_INTERRUPCION en la entrada 17 de la tabla de vectores,

correspondiente al Timebase Module.Con esta modificación, el código de ejemplo quedaría de la siguiente forma:

#define TBON 2#define TACK 8 //Ack del TBCR#define ENABLE_INT {asm cli;}#define DISABLE_INT {asm sei;}

interrupt 17 void Mi_INTERRUPCION(void){TBCR |= TACK; // Acknowledge IntPTA ^= 0x80;}

//*********************************************************************************//void main (void){CONFIG1 = 1; //Parar COPDDRA = 0xFF; //PTA todo salidaTBCR = 0x04; //Timebase divide por 8192ENABLE_INT //Habilitar las interrupcionesTBCR |= TBON; //Prender el Timebasewhile (1) { //bucle infinito}}

Page 27: Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011

5/13/2018 Codigo C Eficicnete Para Sistemas Embebidos y Code Warrior 2011 - slidepdf.com

http://slidepdf.com/reader/full/codigo-c-eficicnete-para-sistemas-embebidos-y-code-warrior-

 

Código C Eficiente para Sistemas Embebidos Página 27

Bibliografía:

[1] Stuart Robb, “Creating Efficient C Code for the MC68HC08”, Nota de Aplicación,East Kilbride, Scotland, 2000.[2] “Embedded C Development tools, ” http://www.imagecraft.com, 1994.[3] Reference Manual: “Software ICCHCxx”, ImageCraft Creations Inc.,2000.[4] “Ing. Gabriel Dubatti”, http://www.ingdubatti.com.ar , 2007[5] User Guide: “PROCESSOR EXPERT FOR MOTOROLA HC(S)08 FAMILY”

Codewarrior V 1.4 may,2004[6] MC68HC908GP32 Technical Data (Motorola)[7] Motorola HC08 Compiler (Metrowerks)[8] Manual Smart Linker (Metrowerks)