Плохо.rs39 писал(а):Рабочий образец кода:
Код: Выделить всё
unsigned char buffer[3]; // <---- Буфер на три символа
...
sprintf(buffer,"%3d",val); // <---- пишется три симола и завершающий 0 за ними, итого 4 !Я делаю без промежуточных буферов. avr-gcc (WinAVR) позволяет так:
Код: Выделить всё
#include <stdio.h>
#include <avr/pgmspace.h> // Размещать форматные строки в ОЗУ жаба давит
#include "lcd.h" // отсюда lcd_putchar да lcd_goxy
// Переходник от "файлового" putc к LCD-шному putchar
int lcd_file_putc(char ch, FILE * stream)
{
(void) stream;
lcd_putchar(ch);
return 0;
}
// Инициализация файлового объекта LCD
FILE lcd_file = FDEV_SETUP_STREAM(lcd_file_putc, 0, _FDEV_SETUP_WRITE);
// Для удобства
#define flcd (&lcd_file) Код: Выделить всё
// Символ градусов цельсия ° занесён в знакогенератор по адресу 0, он же 8
#define LCD_CELSIUS_STR "\x08" Код: Выделить всё
lcd_goxy(1,3);
fprintf_P( flcd, PSTR("t=%3d" LCD_CELSIUS_STR "C"), temperature); Код: Выделить всё
#include <stdrag.h>
void lcd_printf_P(uint8_t x, uint8_t y, const prog_char * fmt, ...)
{
lcd_goxy(x,y);
va_list va;
va_start(va, fmt);
vfprintf_P(flcd, fmt, va);
va_end(va);
} Код: Выделить всё
lcd_printf_P(1, 3, PSTR("t=%3d" LCD_CELSIUS_STR "C"), temperature); В языке C запись "t=%3d" LCD_CELSIUS_STR "C" даёт склеивание фрагментов строк в одну строку "t=%3d\x08C", но не нужно помнить, какой символ на каком номере и не будет проблем, если после \x08 идут опять цифры, в виде подстрок они точно не приклеятся к \x08
По поводу размера кода можно не беспокоиться, так как в библиотеке avr-libc функция sprintf сама сделана через порождение файлового объекта с флагами вывода в массив символов и с полнім набором va_start/vfprintf/va_end:
Код: Выделить всё
int sprintf(char *s, const char *fmt, ...)
{
va_list ap;
FILE f;
int i;
f.flags = __SWR | __SSTR;
f.buf = s;
f.size = INT_MAX;
va_start(ap, fmt);
i = vfprintf(&f, fmt, ap);
va_end(ap);
s[f.len] = 0;
return i;
}


