This is a multi-part message in MIME format. ------=_NextPart_000_00E1_01C27DC9.36B3D990 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit I wrote a printf-like function for my project. It just does what I needed... I've translated some of the comments from Spanish... Hope it helps you! Ovidio Vazquez Jara ----- Original Message ----- > Hi everyone, > I used CCS PCM compiler before and it has really nice printf() and delay_xs() functions. I just bought the Microchip C18 compiler and found that it doesn't have the printf() function. I am really disappointed! It has delayXXTCYx() function, but it is very hard to use. This is because everytime I want to delay for certain period, I have to take my calculator out and calculate how many clock cycle required. :( Does any one write the printf() and delay() function? Could you share the code? Thank you in advance! -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details. ------=_NextPart_000_00E1_01C27DC9.36B3D990 Content-Type: text/plain; name="stdio.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="stdio.c" /************************************************************************= ************************/ /* Name : stdio.c = */ /* Rev. : 09.06.2003 - First stable version. Needs to be cheched! = */ /************************************************************************= ************************/ /* Author: Ovidio V=E1zquez Jara = */ /************************************************************************= ************************/ /* Notes : -It doesn't follows C standards. It was just made for my own = application. */ /* -Variable argument lists doesn=B4t work in MPLAB C18 v2.10. = */ /* You have to change the following definitions in : = */ /* */=20 /* #define va_start(ap,l) {(ap)=3D(void*)((char*)&(l));} */ /* #define va_arg(ap,t) *((t*)( (ap) =3D ((t*)(ap)) - 1 ) ) */ /* */=20 /* -In MPLAB C18 v2.20 the macros where deleted. This is an extract = from the */ /* file "readme.c18" (which comes with the compiler): */ /* */ /* (21311) Macros for accessing variable argument lists are = incorrect. The file */ /* stdarg.h has been removed until this problem is fixed. */ /* */ /* I haven't tested my macros with this version of the compiler, but I = think they */ /* should work (?). */ /* */ /************************************************************************= ************************/ /* Conversion specification: */ /* */ /* %[flags][width]conversion */ /* */ /* width: Minimum field size (paded with zeros and right justified) = */ /* flags: 0: Pads whith zeros to the left */ /* +: Writes the sign even if value > 0 */ /* @: Writes a dot between the last and next to last digits */ =09 /* =3D: When writing a string, it is centered within the field = */ /* ~: When writing a string, a char * argument is taken instead of a = const rom char* */ /* */=20 /* conversions: (argument type; written as...) = */ /* = */ /* % : none ; prints '%' = */ /* d : int ; signed decimal */ /* u : int ; unsigned decimal = */ /* x : int ; hex */ /* c : int ; character = */ /* s : char* ; prints a string */ /************************************************************************= ************************/ #include #include "stdio.h" extern void putchar(char); #define ISSIGNED 0x01 /* Se convierte un numero con signo */ #define FORCESIGN 0x02 /* Especificacion de conversion contiene '+' = */ #define ZEROPAD 0x04 /* La especificacion de conversion contiene '0' = */ #define PRINTDOT 0x08 /* Especificacion contiene '@' */ #define CENTERJUST 0x10 /* '=3D' */ #define WIDTH 0x20 #define FROMRAM 0x40 /* Cambia procedencia de una cadena de ROM a RAM = */ unsigned char strlen_ram(char *s) { unsigned char len =3D 0; =09 while(*s++) len++; return len; } unsigned char strlen_rom(const rom char *s) { unsigned char len =3D 0; =09 while(*s++) len++; return len; } void printf(const rom char *fmt, ...) { va_list ap; const rom char* p; char c; unsigned char d1,d2; unsigned int ival; unsigned int t; unsigned char radix; char width,rem; unsigned char flags; const rom char *str; char *sram; =09 va_start(ap, fmt); for(p=3Dfmt; *p; p++) { =09 if (*p !=3D '%') { putchar(*p); // continue; } else { radix =3D 10; width =3D 0; flags =3D 0; loop: c =3D *++p; switch(c) { case '%': putchar('%'); break; case 'x': radix =3D 16; goto decimal; case 'd': flags |=3D ISSIGNED; goto decimal;=09 case 'u': decimal: ival =3D va_arg(ap, unsigned int); =09 =09 /* Convertimos ival a un numero positivo (el signo esta el el flag = issigned) */=09 if(flags & ISSIGNED) { if(((int)ival) < 0) ival =3D -((int)ival); else flags &=3D ~ISSIGNED; } =09 /* = */ /* Calculamos la longitud del relleno */ /* El numero de caracteres de relleno (si es > 0) va a quedar en la = variable width */ /* La cifra menos significativa siempre se imprime, aunque sea un = cero */ /* La segunda cifra m=E1s significativa tambien se imprime siempre = si @ */ /* = */ d1 =3D ival%radix; ival /=3D radix; width--; =09 if (flags & PRINTDOT) { d2 =3D ival%radix; ival /=3D radix; width -=3D 2; /* Se necesita al menos un digito para la parte = entera y otro para el punto */ } =09 t =3D 1; while (t <=3D ival) { t *=3D radix; width--; } =09 if (flags & (ISSIGNED | FORCESIGN)) { /* Ahora contamos el signo = */ width--; } =09 /* Imprimir espacios+signo o signo+ceros*/ if (!(flags & ZEROPAD)) { while(width-- > 0) putchar(' '); } =09 if (flags & (ISSIGNED | FORCESIGN)) { putchar((flags & ISSIGNED)? '-' : '+'); } =09 if (flags & ZEROPAD) while(width-- > 0) putchar('0'); =09 /* Imprimir cifras significativas */ while(t /=3D radix ) { c =3D (ival/t)%radix; putchar((c > 9)? (c+'A'-10) : (c+'0')); } =09 /* Imprimir la ultima o 2 ultimas cifras y el punto si es necesario = */ =09 if (flags & PRINTDOT) { putchar((d2 > 9)? (d2+'A'-10) : (d2+'0')); putchar('.'); } putchar((d1>9)? (d1+'A'-10) : (d1+'0')); =09 break; case 's': if (flags & FROMRAM) { sram =3D va_arg(ap, char *); width -=3D strlen_ram(sram); } else { str =3D va_arg(ap, const rom char*); width -=3D strlen_rom(str); } =09 rem =3D width/2; while(rem-- > 0) { putchar(' '); width--; } =09 if (flags & FROMRAM) { while(*sram) putchar(*sram++); } else { while(*str) putchar(*str++); } while(width-- > 0) putchar(' '); break; case 'c': ival =3D va_arg(ap, unsigned int); putchar((unsigned char)ival); break; case '+': flags |=3D FORCESIGN; goto loop;=09 case '@': flags |=3D PRINTDOT; goto loop; case '=3D': flags |=3D CENTERJUST; goto loop; case '~': flags |=3D FROMRAM; goto loop; default: if (c =3D=3D '0' && !(flags & WIDTH)) { flags |=3D ZEROPAD; flags |=3D WIDTH; goto loop; } else if (c >=3D '0' && c <=3D'9') { flags |=3D WIDTH; width =3D width*10 + c - '0'; goto loop; } else { /* Cadena de formato mal especificada. Algo va mal! */ putchar('?'); } break; } } } va_end(ap); } -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details. ------=_NextPart_000_00E1_01C27DC9.36B3D990 Content-Type: text/plain; name="stdio.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="stdio.h" /************************************************************************= ************************/ /* Nombre: stdio.h = */ /* Titulo: Algunas funciones presentes en la lib estandar de C stdio.c = -Hasta ahora solo printf*/ /* Rev. : ??.05.2003 - Quebraderos de cabeza varios = */ /* 09.06.2003 - Primera version, estable! */ /************************************************************************= ************************/ /* Autor : Ovidio V=E1zquez Jara = */ /************************************************************************= ************************/ #ifndef __STDIO_H #define __STDIO_H void printf(const rom char *fmt, ...); #endif -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details. ------=_NextPart_000_00E1_01C27DC9.36B3D990--