|
Как вывести на LCD большое число, Не могу вывести число, большее 32767 |
|
|
|
Aug 20 2008, 11:53
|
Участник

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817

|
Подскажите чайнику, как переехать такую проблему. Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12. Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему?
Сообщение отредактировал Tomade - Aug 20 2008, 11:55
|
|
|
|
|
Aug 20 2008, 12:04
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(Tomade @ Aug 20 2008, 15:53)  Подскажите чайнику, как переехать такую проблему. Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12. Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему? Потому что объявлено как int, старший бит трактуется как знак. Объявите unsigned int - получите 0 .. 65535. Читайте про представление чисел в Си.
|
|
|
|
|
Aug 20 2008, 12:18
|
Участник

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817

|
Цитата(=GM= @ Aug 20 2008, 16:10)  Всё равно не хватит до миллиона, надо объявить переменную как LONG. Так и делал: char lcd_buffer[33]; unsigned long int x = 32760; void main(void) { lcd_init(16); while(1){ sprintf(lcd_buffer,"%i",x); lcd_clear(); lcd_puts(lcd_buffer); x++; delay_ms(20);}} - эффекта никакого.
|
|
|
|
|
Aug 20 2008, 12:36
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Странно... есть же на данном форуме тема с чужим готовым кодом... Код void lcd_menu_value( unsigned long freq, unsigned char width, // full width unsigned char comma, // comma position (from right, inside width) unsigned char rj // right truncated ) { //PROGMEM static const unsigned long vals [] = { 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1, }; const unsigned char j = (sizeof vals /sizeof vals [0]) - rj; unsigned char i = (j - width); unsigned char z = 1; // only zeroes
ws1602_gotoxy(0, 0); // курсор в начало первой строки
for (; i < j; ++ i) { //ldiv_t res = ldiv(freq, pgm_read_dword(& vals [i])); ldiv_t res = ldiv(freq, vals [i]); if (comma == (j - i)) ws1602_wrdata('.');
if (z == 1 && (i + 1) < j && res.quot == 0) ws1602_wrdata(' '); // supress zero else { z = 0; ws1602_wrdata('0' + res.quot); } freq = res.rem;
} }
void ws1602_dispfreq(unsigned long freq) { lcd_menu_value(freq, 7, 2, 1); }
Сообщение отредактировал Genadi Zawidowski - Aug 20 2008, 12:39
|
|
|
|
|
Aug 20 2008, 12:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата sprintf(lcd_buffer,"%i",x); Цитата "%i" - это int, надо - "%l" или "%lu" (второе для unsigned long) Еще от компилятора зависит, какая там спринтф будет, в ИАРе, вроде поддержку ЛОНГ отдельно надо включать, в настройках проекта.
--------------------
|
|
|
|
|
Aug 20 2008, 13:08
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Tomade @ Aug 20 2008, 18:18)  Так и делал:
char lcd_buffer[33]; unsigned long int x = 32760; void main(void) { lcd_init(16); while(1){ sprintf(lcd_buffer,"%i",x); lcd_clear(); lcd_puts(lcd_buffer); x++; delay_ms(20);}}
- эффекта никакого. Обратите внимание на указанную функцию. В CodeVision в настройках надо указывать какую библиотеу вы будете тиспользовать: - Меню Project \ Confugire - В окне настроек вкладка C Compiler - На вкладке внизу слева настройки (s)printf Features
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Aug 21 2008, 05:49
|
Участник

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817

|
Спасибо всем откликнувшимся. Вот что получилось (компилятор - CVAVR 1.25.2). Если в строке sprintf(lcd_buffer,"%i",x) вместо i ставить I или Iu, то в симуляторе на табло LCD вообще ничего не выводится (и для int, и для long). После игры в метод тыка оказалось, что правильно выводятся числа до 65535, если вместо i ставить просто u, причём независимо от настроек, о которых говорил zhevak в последнем письме. Другие варианты, перечисленные в справке CVAVR для (s)printf features, ни к чему не привели. Как же вывести на экран LCD число, большее 65535?
|
|
|
|
|
Aug 21 2008, 06:36
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Tomade @ Aug 21 2008, 11:49)  Спасибо всем откликнувшимся. Вот что получилось (компилятор - CVAVR 1.25.2). Если в строке sprintf(lcd_buffer,"%i",x) вместо i ставить I или Iu, то в симуляторе на табло LCD вообще ничего не выводится (и для int, и для long). После игры в метод тыка оказалось, что правильно выводятся числа до 65535, если вместо i ставить просто u, причём независимо от настроек, о которых говорил zhevak в последнем письме. Другие варианты, перечисленные в справке CVAVR для (s)printf features, ни к чему не привели. Как же вывести на экран LCD число, большее 65535? Попробуйте сделать так: Код #include <stdio.h> ...
unsigned long x; x = 1000000; char s1[10];
...
sprintf(s1, "%li", x); // Библиотечная функция LCD_StringXY(0, 1, s1); // -- это моя функция, у Вас должно быть что-то свое Вы заставили-таки меня сделать это. Вы неправильно используете модефикаторы. Я попробовал и так sprintf(s1, "% li", x); и так sprintf(s1, "% ld", x); -- работает в обоих случаях. У меня CodeWizardAVR V1.25.3 Standard.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Aug 21 2008, 09:59
|
Участник

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817

|
АНТОХА: Надо не I, а L! (от long)В вашем предыдущем письме было I. Впрочем, ставил и I, и l, и L - не помогает. В этих случаях совсем ничего не высвечивается. bloodden: Как и в CVAVR впрочем тоже. В настройках проекта. По-умолчанию там стоит до инта.В предыдущем письме сообщал, что перепробовал разные настройки. Не помогло. zhevak: Вы неправильно используете модификаторы. Я попробовал и так sprintf(s1, "%li", x); и так sprintf(s1, "%ld", x); -- работает в обоих случаях.Проблема в том, что я не программист. Можно сказать, радиолюбитель, решивший самостоятельно изучить МК (и СИ) и что-то на них собирать. Потому то, что для программиста очевидно, для меня - далеко не так. А именно: sprintf(s1, "%li", x); // Библиотечная функция - где эта функция должна находиться? Как проверить, что она есть? И если нет, то где взять и куда вставить? LCD_StringXY(0, 1, s1); // -- это моя функция, у Вас должно быть что-то свое. Если бы знать, что своё должно быть... А просто поставить, к примеру, sprintf(s1, "%li", x); - ни к чему не приводит. Короче, пойду покупать пистолет.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|