Если уж использовать в WinAVR printf, то тогда так:
Код
void lcd_putchar(char data); // то, что уже есть
int lcd_file_putc(char ch, FILE * stream)
{
(void) stream;
lcd_putchar(ch);
return 0;
}
// аналогично создаём и для UART
void uart_putchar(char ch); // он может вообще в кольцевой буфер помещать, ждать только если места нет
int uart_file_putc(char ch, FILE * stream)
{
(void) stream;
if(ch == '\n')
uart_putchar('\r');
uart_putchar(ch);
return 0;
}
FILE lcd_file = FDEV_SETUP_STREAM(lcd_file_putc, 0, _FDEV_SETUP_WRITE);
FILE uart_file = FDEV_SETUP_STREAM(uart_file_putc, uart_file_getc, _FDEV_SETUP_WRITE);
#define lcd_stream (&lcd_file);
#define uart_stream (&uart_file);
fprintf_P( lcd_stream, PSTR("Freq %6.3fMHz"), freq);
fputs_P( PSTR("Hello!\n"), uart_stream);
fprintf_P( uart_stream, PSTR("Freq %6.3fMHz"), freq);
А для ЖКИ можно и вообще так:
Код
void lcd_printf_P(uint8_t x, uint8_t y, prog_char *fmt, ...) __attribute__((format(printf, 3, 4)));
void lcd_printf_P(uint8_t x, uint8_t y, prog_char *fmt, ...)
{
lcd_gotoxy(x,y);
va_list vl;
va_start(vl, fmt);
vfprintf_P( lcd_stream, fmt, vl);
va_end(vl);
}
lcd_printf_P(1, 5, PSTR("%6.3MHz"), freq);
Раз уж платить увеличенным расходом кода, то хоть знать за что.
Цитата(GoodNews @ Feb 7 2010, 14:30)

Если раскомментить и вызвать через функцию - виснет. Почему?
Да так вроде всё нормально. Не вижу причины :-(
Определять переменные в .h нехорошо (это я про char buf[16]), но к зависанию это не имеет отношения.