I have made the new function putchar for redirect the output to LCD already. But by default, I also want to use this as output to serial port on the same program. I do not understand how to use both output function in parallel or other way to switch between each other. Please tell me if possible. With my thanks.
to use both in parallel, you will need something like:
char putchar (char c) { lcd_putchar( c ); serial_putchar( c ); return c; }
To have the port runtime-selectable, you could add a paramter to choose the port:
typedef enum { NO_PORT = 0, LCD_PORT, SERIAL_PORT } T_port_id char putchar_to_port( T_port_id port, char c ) { switch( port ) { case LCD_PORT: lcd_putchar( c ); break; case SERIAL_PORT: serial_putchar( c ); break; default: /* Do nothing! */ break; } return c; }
Thanks for your replies However, the problem is not only int putchar function but also in printf function which uses putchar function. As I understood printf function use only one default name putchar on the same format for operating output. So I can not switch between output function (e.g. lcd_putchar and putchar) which I can do in PIC-C(C compiler for PIC Microcontroller) very flexible as: - printf("......",.....);//default serial port - printf(lcd_putc,"......",.....);//redirect to LCD If you know what I mean please help resolve this problem
Like I said before, "However, if you want the rest of the standard library functions to be able to use it, you cannot go adding parameters. You could use a global variable instead"
"So I can not switch between output function (e.g. lcd_putchar and putchar)" That's ANSI 'C' for you! "which I can do in PIC-C(C compiler for PIC Microcontroller) very flexible as: - printf("......",.....);//default serial port - printf(lcd_putc,"......",.....);//redirect to LCD" Well, who cares about standards anyway - let's just make up the rules as we go along! You could create an fprintf (or whatever) that sets up your port selection, then calls the standard printf. Maybe you could do it as a Macro?
"So I can not switch between output function (e.g. lcd_putchar and putchar) which I can do in PIC-C(C compiler for PIC Microcontroller) very flexible as: - printf("......",.....);//default serial port - printf(lcd_putc,"......",.....);//redirect to LCD"
char (* putchar_fp)(char c); char lcd_putchar(char c) { /* Your LCD output handler goes here */ } char ser_putchar(char c) { /* Body of Keil's putchar goes here */ } char putchar(char c) { /* Body of Keil's putchar moved to ser_putchar() * and replaced with... */ return putchar_fp(c); } int my_printf(char (* which_putchar_fp)(char), const char *format, ...) { int ret_val; va_list ap; putchar_fp = which_putchar_fp; va_start(ap, format); rtn = vprintf(format, ap); va_end(ap); return ret_val; } int main(void) { my_printf(lcd_putchar, "Hello world on %s\n", "LCD"); my_printf(ser_putchar, "Hello world on %s\n", "SER"); }
And for good measure, you'd probably want to 'reset' putchar_fp back to putchar so that any subsequent calls to normal printf() used ser_putchar() as originally indended. So make that...
int my_printf(char (* which_putchar_fp)(char), const char *format, ...) { int ret_val; va_list ap; putchar_fp = which_putchar_fp; va_start(ap, format); ret_val = vprintf(format, ap); va_end(ap); putchar_fp = ser_putchar; return ret_val; }
One more comment, should you choose to use function pointers, would be to have you take a look at Keil's function pointer appnote. http://www.keil.com/appnotes/docs/apnt_129.asp
Dear Dan Henry, Andy Neil Thank you very much for your guide and C51 module. After receiving your replies, I tested on two way successfully. The first one I simply use a global variable to switch functions and on the other one I write codes like your guide which used function pointer. Again thank you so much, see you next post.
That's ANSI 'C' for you! In all fairness, ANSI C has nothing to do with this. What we're seeing here is a direct consequence of a design decision made by Keil: they decided to support printf(), but not fprintf() and fopen(), which would be the brutally obvious way a job like this would be done in actual ANSI C. I.e. the code at hand should be writable like this:
FILE *lcdout = fopen("mylcd_pseudofile", "w"); fprintf(lcdout, "this goes to the screen"); FILE *serialout = fopen("serial_pseudofile", "w"); printf("this goes to default output device");