Generando Un Pulso Con Pic

31
Generando un pulso. 1ª Parte. Onda cuadrada simétrica mediante INTRTCC A.- Conceptos involucrados: Decíamos en Midiendo un pulso. 4ª Parte. El pulso completo. El Periodo y la Frecuencia que ... dadle un vistazo porque vamos a tratar con los mismos elementos, o mejor aún los vamos a repetir en este mismo !ilo. Decíamos allí que el "iempo T que transcurre ente dos #lancos sucesivos de su$ida %o de $ajada& es lo que conocemos como Periodo del Pulso %Period&, o sea lo que dura un pulso completo. 'ada " se(undos %) milise(undos, ) microse(undos& tenemos un nuevo pulso completo. 'omo vemos, cada pulso tiene un "iempo en *lto %+i(! "ime& y un "iempo en estado ajo %-o "ime&. -a suma de los dos es el Periodo " del pulso.

description

generando un pulso con un pic

Transcript of Generando Un Pulso Con Pic

Generando un pulso. 1 Parte. Onda cuadrada simtrica mediante INTRTCC

A.-Conceptosinvolucrados:

Decamos enMidiendo un pulso. 4 Parte. El pulso completo. El Periodo y la Frecuenciaque ... dadle un vistazo porque vamos a tratar con los mismos elementos, o mejor an: los vamos a repetir en este mismo hilo.

Decamos all que el TiempoTque transcurre ente dos flancos sucesivos de subida (o de bajada) es lo que conocemos comoPeriodo del Pulso(Period), o sea: lo que dura un pulso completo.

Cada T segundos ( milisegundos, microsegundos) tenemos un nuevo pulso completo.

Como vemos, cada pulso tiene un Tiempo en Alto (High Time) y un Tiempo en estado Bajo (Low Time). Lasuma de los dos es el PeriodoT del pulso.

Como vemos en la imagen superior un pulso completo comienza con un flanco de subida en T1, sigue con uno de bajada en T2 y concluye en el nuevo flanco de subida T3.

Entre T1 y T2 permanece el pulso en Alto, Wh, mientras que entre T2 y T3 lo hace en bajo, Wl.

El tiempo transcurrido entre T1 y T3 es el Periodo del Pulso. Si este periodo lo expresamos en Segundos entonces su inverso, 1 / Periodo, es la Frecuencia del tren de pulsos.

Estos dos valores son los que vamos a generar con nuestro PIC: el Periodo T y la frecuencia F.

B.-Tcnicaa Aplicar:

Para generar elperiodo Tde nuestro pulso vamos a utilizar dos recursos de los que disponen la gran mayora de los PIC's, tanto los de la serie 18F como los 16F:

ElTIMER0y laInterrupcin Por Desbordamiento de TIMER.

Sobre el TMR0 podis leer lo escrito anteriormente en los hilos que preceden a ste hablando del TMR1 ...

Aqu solo recordar que el TMR0 es un contador queincrementasu valor cadaFOSC*4segundos y que cuando alcanza su valor mximo, 255 en TMR0 de bits 65535 en los PIC en que TMR0 es de 16 bits, dispara una Peticin de Servicio por Interrupcin llamada RTCC.

Esta interrupcin se produce cada256*FOSC*4segundos si el TMR0 es de 8 bits o cada65536*FOSC*4si es de 16 bits.

Recordad tambin que podemos aplicar distintos divisores a estas velocidades,Preescaler, de tal forma que podemos ralentizar su cronometraje a1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:128 1:256con lo que la formula anterior queda automticamente multiplicada por el divisor que usemos. El mnimo es 1:2.

Adems de todo esto tenemos tambin otro grado de libertad con estos recursos: Podemosasignar un valor determinado al TMR0distinto de 0 cada vez que se nos dispare la interrupcin RTCC. Con ello conseguimos que el contador al no empezar en 0 sino en un valor mayor n no deba completar su recorrido para disparar de nuevo la interrupcin, sino que solo deba contar255-n65535-nsegn el tipo de TMR0 que estemos usando.

As entre FOSC (el cristal que oscila a una determinada frecuencia), el divisor de frecuencia aplicado (Preescaler) y el valor de TMR0 asignado cada RTCC (offset) tenemos una gran capacidad de maniobra para poder contar tiempos bastante precisos.

Como en las Tcnicas anteriores medamos una onda de entrada cuya frecuencia era aproximadamente de 2 Khz (0.5 ms de periodo) vamos en esta tcnica a generar este mismo tipo de onda.

As lo que vamos a hacer es generar unaRTCCcada semiperiodo de onda conmutando el estado del Pin de alto a bajo y viceversa: la mitad del periodo con el Pin en Alto y la otra mitad con el Pin en bajo.

Cada RTCC volvemos a poner TMR0 a 177 para que recorra slo 255 - 177 = 78 Ticks de TMR0.

C.-Implementacinen C:

Para implementar nuestroCdigo en Cvamos a centrarnos en los puntos que hemos descrito en la seccin anterior.

Paraconfigurar la interrpcin RTCCutilizaremos lo siguiente:

setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT);// Ajusto divisor de TMR1 para RTC cada 0.25 msenable_interrupts(int_rtcc);enable_interrupts(global); // Habilito las interrupciones necesarias

Con esta configuracin inicial podemos ya escribir nuestrarutina ISRque es extremadamente simple:

#int_rtccvoid handle_rtcc_int(){

Output_Toggle(OUT); // Conmuto PIN de Salida; Set_timer0(177);}

Fijaos que en la rutina ISR anterior lo nico que hacemos es conmutar el Pin de Salida y poner el offset del TMR0 a 177 para obtener los 255-177 Ticks de TMR1 que necesitamos para hacer saltar RTCC aproximadamente cada 0.25 ms.

Con todo esto el programa completo para nuestroGenerar una Onda Cuadrada Simtrica de 2 Khz de Frecuenciaqueda as:

///////////////////////////////////////////////////////////////////////////////////////// generando_un_pulso_5_intrtcc.c//// SERIE: "Tcnicas en C" para el Foro TODOPIC//// (c) 10.2006 by RedPic//// Propsito: Generar un pulso de 2 Khz (0.5 ms de periodo)//// Tcnica Empleada: Habilitar INTRTC para conmutar un PIN cada semiperiodo//////////////////////////////////////////////////////////////////////////////////////

#include #fuses HS,MCLR,CCP2B3,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

//////////////////////////////////////////////////////////////////////////////////////// Defines y Constantes//////////////////////////////////////////////////////////////////////////////////////

#define LED PIN_E0 // Defino el Pin del Led#define OUT PIN_B3

//////////////////////////////////////////////////////////////////////////////////////// Interrupcin por Externa por Cambio de Flanco en RB0//////////////////////////////////////////////////////////////////////////////////////

#int_rtccvoid handle_rtcc_int(){ Output_Toggle(OUT); // Conmuto PIN de Salida; Set_timer0(177); Output_Toggle(LED); // Conmuto PIN de Led;

}

//////////////////////////////////////////////////////////////////////////////////////// Main//////////////////////////////////////////////////////////////////////////////////////

void main() {

////////////////////////////////////////// INICIALIZACIONES GENERALES

delay_ms(333); // Espero a que todo se estabilice e ... disable_interrupts(global); // Inicializo el Micro y ... disable_interrupts(int_timer1); // deshabilitando todo lo no necesario ... disable_interrupts(int_rda); disable_interrupts(int_ext); disable_interrupts(int_ext1); disable_interrupts(int_ext2); setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_spi(FALSE); setup_psp(PSP_DISABLED); setup_counters(RTCC_INTERNAL,RTCC_DIV_2); setup_timer_0(RTCC_OFF); setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); setup_timer_2(T2_DISABLED,0,1); setup_timer_3(T3_DISABLED); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); port_b_pullups(FALSE); delay_ms(333);

/////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION

setup_timer_0(RTCC_DIV_16 | RTCC_8_BIT); // Ajusto divisor de TMR1 para RTC cada 0.25 ms enable_interrupts(int_rtcc); enable_interrupts(global); // Habilito las interrupciones necesarias

printf("\r\nGenerando un pulso : RTCC\r\n"); printf("By Redpic para Foro TODOPIC\r\n\n");

do {

} while (TRUE);}

D.-Ejemplofuncionando:

Generando un pulso. 2 Parte. Onda cuadrada simtrica mediante INTCCP

A.-Conceptosinvolucrados:

Seguimos dndole vueltas al mismo concepto que en todas lasTcnicas en Canteriores. Si lo deseis podis repasar esto mismo en cualquiera de ellas.

Volvemos a generar un pulso de PeriodoTcon dos semiperiodos iguales, simtrico, y de unos 2 Khz de frecuencia: unos 0.25 ms en alto y otros 0.25 ms en bajo, total 0.5 ms de periodo.

B.-Tcnicaa Aplicar:

Para generar elperiodo Tde nuestro pulso vamos a utilizar de nuevo elmdulo CCPdel que disponen la gran mayora de los PIC's, tanto los de la serie 18F como los 16F.

Recordemos: En la TcnicaMidiendo un pulso. 2 Parte. Tiempo en Alto con INTCCPhacamos uso de este mismo mdulo utilizando su modoCaptureen el que cuando detectbamos un flanco externo se noscapturabael valor en ese momento delTMR1. Jugando con los sucesivos valores obtenamos la duracin del pulso.

En sta tcnica que ahora describimos vamos a hacer lo diametralmente opuesto: Vamos a utilizar elCCPen modoComparepara que el CCP vayacomparandoautomticamente el valor deTMR1con unvalor de referenciaque le damos,CCP_x, y en cuanto lo alcance se realice laconmutacin del Pinasociado a l y nos dispare la Peticin de Servicio de Interrupcin (ISR)INT_CCPxcorrespondiente.

En el cdigo de esta interrupcin volvemos a hacer lo mismo pero configurando elComparepara que cuando TMR1 alcance el valor de referenciaconmutenuestro Pin CCP al estado contrario.

Siambos valoresde TMR1 de referencia, para el Compare a Alto y el Compare a bajo,son igualestendremos un tren depulsos simtricos, estn el mismo tiempo en alto que en bajo, o sea que tienen un Duty Cycle del 50%. En caso contrario estarn mas tiempo en un estado que en otro y ser una onda asimtrica, o sea que tendr un Duty Cicle distinto del 50%.

Elperiodo ser la suma de ambos tiempos, el que permanece en estado alto mas el que est en estado bajo.

Calculando cuidadosamente dichos tiempos podremos generar una onda del periodo que deseamos.Pondremos a 0 siempreTRM1y cargaremosCCP_xcon el nmero deTicksde TMR1 en que deseamos que se dispare nuestra conmutacin/interrupcin.

C.-Implementacinen C:

Para implementar nuestroCdigo en Cvamos a centrarnos en los puntos que hemos descrito en la seccin anterior.

Paraconfigurar la interrupcin CCPutilizaremos lo siguiente:

setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 en modo COMPARE cambiando a Altoenable_interrupts(int_ccp2); // Habilito la interrpcin INT_CCP2enable_interrupts(global); // Habilito las interrupciones necesarias

Con esta configuracin inicial podemos ya escribir nuestrarutina ISRque es muy simple ya que nicamente selecciona mediante unflagsi debe el siguiente cambio es aAlto o a Bajoy colocar el tiempo en que deseamos en que esto se produzca:

#int_ccp2void handle_ccp2_int(){

if(++flagConmuta==1){ setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Bajo } else{ setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Alto } CCP_2=0; // Pongo a cero el valor a comparar ... set_timer1(0); // y el TMR1. CCP_2 = 1250; // Quiero que se dispare cada 0.25 ms ... // luego pongo los Ticks de TMR1 para ese tiempo.}

Notad que estoy trabajando con una configuracin particular a la que me sujeta el Hardware especfico del que dispongo: El mdulo CCP2 y un cuarzo de 20 Mhz.

Con un Cristal de 20 Mhz los clculos me indican que el nmero de Ticks de TMR1 necesarios para realizar una conmutacin cada 0.25 ms es de 1250 (0.00025 / (1/ FOSC)*4)

Con todo esto el programa completo para nuestroGenerar una Onda Cuadrada Simtrica de 2 Khz de Frecuenciaqueda as:

///////////////////////////////////////////////////////////////////////////////////////// generando_un_pulso_6_intccp.c//// SERIE: "Tcnicas en C" para el Foro TODOPIC//// (c) 11.2006 by RedPic//// Propsito: Generar un pulso de 2 Khz (0.5 ms de periodo)//// Tcnica Empleada: Habilitar INTCCP para conmutar el PIN CCP2 cada semiperiodo// utilizando el recurso CCP en modo compare.//////////////////////////////////////////////////////////////////////////////////////

#include #fuses HS,MCLR,CCP2B3,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN#use delay(clock=20000000)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

//////////////////////////////////////////////////////////////////////////////////////// Defines y Constantes//////////////////////////////////////////////////////////////////////////////////////

#define LED PIN_E0 // Defino el Pin del Led#define OUT PIN_B3

//////////////////////////////////////////////////////////////////////////////////////// Variables en RAM//////////////////////////////////////////////////////////////////////////////////////

int1 flagConmuta=0;

//////////////////////////////////////////////////////////////////////////////////////// Interrupcin CCP por Compare TMR1//////////////////////////////////////////////////////////////////////////////////////

#int_ccp2void handle_ccp2_int(){

if(++flagConmuta==1){ setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Bajo } else{ setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Alto } CCP_2=0; // Pongo a cero el valor a comparar ... set_timer1(0); // y el TMR1. CCP_2 = 1250; // Quiero que se dispare cada 0.25 ms ... // luego pongo los Ticks de TMR1 para ese tiempo. Output_Toggle(LED); // Monitorizo visualmente con el PIN de Led;}

//////////////////////////////////////////////////////////////////////////////////////// Main//////////////////////////////////////////////////////////////////////////////////////

void main() {

////////////////////////////////////////// INICIALIZACIONES GENERALES

delay_ms(333); // Espero a que todo se estabilice e ... disable_interrupts(global); // Inicializo el Micro y ... disable_interrupts(int_timer1); // deshabilitando todo lo no necesario ... disable_interrupts(int_rda); disable_interrupts(int_ext); disable_interrupts(int_ext1); disable_interrupts(int_ext2); setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_spi(FALSE); setup_psp(PSP_DISABLED); setup_counters(RTCC_INTERNAL,RTCC_DIV_2); setup_timer_0(RTCC_OFF); setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); setup_timer_2(T2_DISABLED,0,1); setup_timer_3(T3_DISABLED); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); port_b_pullups(FALSE); delay_ms(333);

/////////////////////////////////////////// INICIALIZACIONES PERTINENTES A LA APLICACION

setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Alto enable_interrupts(int_ccp2); // Habilito la interrpcin INT_CCP2 enable_interrupts(global); // Habilito las interrupciones necesarias

printf("\r\nGenerando un pulso : INTCCP Compare\r\n"); printf("By Redpic para Foro TODOPIC\r\n\n");

do { } while (TRUE);}

D.-Ejemplofuncionando:

La fotografa es la misma que enGenerando un pulso. 1 Parte. Onda simtrica con INTRTCCya que la nica diferencia est en el Firmware del PIC: el resto visualmente y desde fuera es absolutamente igual.

Esta serie de contenidos tituladaTcnicas en Cpretende mostrar con ejemplos comentados la forma deimplementarciertosprocesos muy usualesdurante el uso de los Microcontroladores PIC de las series 16F y 18F.

Librera de Funciones "tiles"

A.-Un poco deTeora:

Utilizando una Librera de Funciones "tiles" en CCS C

Los conceptos fundamentales a tener en cuenta son varios y todos importantes, voy a intentar haceros una descripcin simple y a ser posible completa.

1.-Se hace uso una directiva de compilacin que permite insertar cualquier cdigo fuente all donde la utilicemos. Se trata de la directiva#includeque hace exactamente eso: Incluye en esa posicin el contenido del fichero descrito en la directiva.

As#include "lib_utils.c"coloca, a partir de la lnea donde aparece la directiva, el contenido completo del ficherolib_utils.c.

Esta directiva tiene dos formas de delimitar el nombre del fichero a incluir:

Delimitado el nombre condobles comillas"", como en el ejemplo anterior que hemos puesto, y que hace que se busque el fichero en su direccin absoluta, podemos entonces escribir #include "c:\proyectos\librerias\lib_utils.c" y entonces se buscar el fichero en esa direccin. Si omitimos alguna parte de su direccin se buscar entonces partiendo del directorio actual en uso, as poniendo solo "lib_utils.c" se entender que el directorio donde se encuentra es el mismo en el que est el programa que estamos compilando y que incluye a aqul.

Delimitado con los smbolosmayor y menor que hace que el fichero a incluir sea buscado en el/los directorio/s predefinido/s en el compilador para la inclusin de fuentes. En CCS C esta opcin se encuentra en el menOptions/Include Dirs...

Por lo dems ambas formas de citar al fichero a incluir son exactamente iguales.

2.-Otro concepto que tenemos que aplicar es el de laprecedenciaenC. En este lenguaje, como en todos los estructurados, es fundamental el hecho de tener quedeclararcualquier cosaantesde poder usarla. De esta forma solo podremos usar un funcin en nuestro programa si, y solo si, el compiladorconocela funcin antes de usarla.

Hay que tener en cuenta que el compilador va a recorrer, compilando, nuestro programa de arriba a abajo, siendo la parte superior la que primero se compila y la inferior la ltima en serlo.

As si en nuestro main() utilizamos una funcin sta debe estar colocada antes del main() para que pueda ser compilada, en otro caso el compilador nos lanzar un error indicndonos que dicha funcin no est declarada.

Este caso compilara perfectamente ya que al utilizar en main() la funcin miFuncion() ha sido desarrollada antes de llegar all el compilador y por lo tanto "la conoce" antes de usarla:

int8 miFuncion(void){ return 100}

void main(void){ int8 n;

n = miFuncion();}

Y sin embargo ste no lo hara ya que al compilar main() el compilador no sabra qu es miFuncion() al estar desarrollada despus de ser usada:

void main(void){ int8 n;

n = miFuncion();}

int8 miFuncion(void){ return 100}

La solucin a ste ltimo caso sera o mover miFuncin() para colocarla antes del main(), que es lo que tenamos en el ejemplo anterior, o mejor an:Declararla, colocando suprototipoantes del mismo y podramos as dejar su desarrollo donde quisisemos. Esto lo haramos de la siguiente forma:

int8 miFuncion(void);

void main(void){ int8 n;

n = miFuncion();}

int8 miFuncion(void){ return 100}

Fijaos en que solo he puesto una lnea exactamente igual que la que describe mi funcin pero sin desarrollarla, sin poner qu hace la funcin por dentro,solo qu parmetros recibe la funcin y qu devuelve la misma.

As el compilador sabe qu es lo que debe hacer con ella y su llamada desde el main() es correcta, aunque an no sepa qu debe hacerdentrode la funcin, que viene mas abajo y an no ha sido compilada.

Notad que tenemos en este ltimo ejemplo tres partes perfectamente diferenciadas:Cabecera, Main y Desarrollo. Vamos a escribir de nuevo el ejemplo pero diferenciando sus partes:

// Cabecera //////////////int8 miFuncion(void);// Fin de Cabecera ////////

// Main ///////////////////void main(void){ int8 n;

n = miFuncion();}// Fin de Main ////////////

// Desarrollo /////////////int8 miFuncion(void){ return 100}// Fin de Desarrollo //////

Nos vamos acercando a nuestro objetivo ...

3.-Por ltimo vamos a cortar nuestro cdigo y dividirlo en tres ficheros distintos. A la parte que hemos llamadoCabecerala vamos a poner en un fichero que se llame "Lib_Utils.h", la extensin .h viene de la palabra inglesaheadero sea cabecera en espaol. La parte que hemos llamadoDesarrollola vamos a colocar en un fichero que se llame "lib_utils.c" ya que contiene el cdigo C que desarrolla nuestras funciones. Y a la parteMainla vamos a colocar en su propia "main.c" que es la que nosotros compilamos.

Como es necesario compilar todo el cdigo fuente y ahora lo tenemos dividido en tres ficheros distintos es necesario decirle al compilador que incluya los ficheros correspondientes en el que estamos compilando, as nuestro main.c debera incluir a los otros dos:

#include "Lib_utils.h"

// Main ////////////////////////void main(void){int8 n;

n = miFuncion();}// Fin de Main /////////////////

#include "lib_utils.c"

Esta forma de escribirlo es exactamente igual que la anterior, el compilador va a recorrer las mismas lneas de cdigo en el mismo orden generando exactamente el mismo cdigo objeto compilado. La nica diferencia entre ellos es que el compilador ha tenido que unir las distintas lneas de cdigo contenidas en los distintos ficheros mediante los #include antes de compilar.

Y4.-Hacemos uso por fin de una caracterstica muy til del compilador y que es que ste solo compila efectivamente, y traslada al cdigo objeto compilado, aquellas funciones que realmente son llamadas desde el main(), o que son llamadas desde una funcin que a su vez es llamada desde el main(), o que son llamadas desde una funcin que a su vez es llamada desde una funcin que a su vez es llamada desde el main() ....

Esta caracterstica del compilador nos posibilita para escribir cien funciones en nuestro "lib_utils.c" y declarar esas mismas cien funciones en el "Lib_Utils.h", incluirlas todas en el "main.c" pero que al ser compiladas slo exclusivamente aquella o aquellas que usemos en el main sean las que realmente se compilen, independientemente de cuantas funciones contengan nuestro ficheros de utilidades.

Finalizando.

Si unimos todas las funciones "tiles" que tengamos a mano en nuestro nico fichero "lib_utils.c" y colocamos todas sus descripciones o prototipos en "Lib_Utils.h" tendremos nuestra libera completa y lista para su uso:

Lib_Utils.h

/** \file lib_Utils.h* \brief Este fichero contiene las cabeceras necesarias para* el manejo de la Librera de Utilidades*** \author (c) 08.2008 by RedPic*/

// Prototipos de funciones

int8 bin_to_bcd(int8 binary_value);int8 bcd_to_bin(int8 bcd_value);void int8_to_bits_string(int8 val,char* pF);int8 bits_string_to_int8(char* pF);int1 get_bit_in_byte(int8 byte_for_bits, int8 pbit);int8 set_bit_in_byte(int8 byte_for_bits, int1 vbit, int8 pbit);void fill_end_with_char(char c, int8 maxlen,char* pF);int8 str_to_int8(char* pF);void decode_timestamp(char *pF, int8 &day, int8 &mth, int16 &year, int8 &hr, int8 &min, int8 &sec);void encode_timestamp(char *pF, int8 day, int8 mth, int16 year, int8 hr, int8 min, int8 sec);void replace_char(char c, char p, char* pF);int8 ascii_to_hex(char d);int8 hex_to_int8(char* pF);int16 hex_to_int16(char* pF);int32 hex_to_int32(char* pF);void right_trim(char* pF);int1 are_all_char_code_printable(char *pF);void insert_char_in_string_in_position(char *pF, char c, int8 position, int8 len);/////////////////////////////////////////////////////////////////////////////////////////////////////// end of lib_Utils.h/////////////////////////////////////////////////////////////////////////////////////////////////////

lib_utils.c

/** \file lib_utils.c* \brief Este fichero contiene un compendio de funciones de utilidad varia.** \author (c) 08.2008 by RedPic*/

/** \brief Funcin auxiliar que convierte de \c BIN a \c BCD** \param binary_value Valor binario a convertir.* \return Valor BCD convertido.*/int8 bin_to_bcd(int8 binary_value){

int8 temp;int8 retval;

temp = binary_value;retval = 0;while(1){if(temp >= 10){temp -= 10;retval += 0x10;}else{retval += temp;break;}}return(retval);}

/** \brief Funcin auxiliar que convierte de \c BCD a \c BIN** \param bcd_value Valor BCD a convertir.* \return Valor Binario convertido.*/int8 bcd_to_bin(int8 bcd_value){

int8 temp;

temp = bcd_value;temp >>= 1;temp &= 0x78;return(temp + (temp >> 2) + (bcd_value & 0x0f));}

/** \brief Funcin que convierte un Byte (de 8 bits) a bits string ASCII.** Convierte un Byte (de 8 bits) a string ASCII terminado en NULL (\\0).** \param val Valor del Byte a convertir.* \param[out] pF Puntero a string_null_ended.** \return void*/void int8_to_bits_string(int8 val,char* pF){

int8 i,j;

for(i=0,j=7;i