Tomade 0 20 августа, 2008 Опубликовано 20 августа, 2008 (изменено) · Жалоба Подскажите чайнику, как переехать такую проблему. Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12. Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему? Изменено 20 августа, 2008 пользователем Tomade Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба Для ответа на Ваш вопрос, Вы указали мало данных. Как минимум нужно видеть Ваш код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maik-vs 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба Подскажите чайнику, как переехать такую проблему. Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12. Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему? Потому что объявлено как int, старший бит трактуется как знак. Объявите unsigned int - получите 0 .. 65535. Читайте про представление чисел в Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба Потому что объявлено как int, старший бит трактуется как знак. Объявите unsigned int - получите 0 .. 65535 Всё равно не хватит до миллиона, надо объявить переменную как LONG. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tomade 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба Всё равно не хватит до миллиона, надо объявить переменную как 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);}} - эффекта никакого. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба "%i" - это int, надо - "%l" или "%lu" (второе для unsigned long) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 20 августа, 2008 Опубликовано 20 августа, 2008 (изменено) · Жалоба Странно... есть же на данном форуме тема с чужим готовым кодом... 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); } Изменено 20 августа, 2008 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба sprintf(lcd_buffer,"%i",x); "%i" - это int, надо - "%l" или "%lu" (второе для unsigned long) Еще от компилятора зависит, какая там спринтф будет, в ИАРе, вроде поддержку ЛОНГ отдельно надо включать, в настройках проекта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 20 августа, 2008 Опубликовано 20 августа, 2008 · Жалоба Так и делал: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tomade 0 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба Спасибо всем откликнувшимся. Вот что получилось (компилятор - 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба Если в строке sprintf(lcd_buffer,"%i",x) вместо i ставить I или Iu, то в симуляторе на табло LCD вообще ничего не выводится (и для int, и для long). Надо не I, а L! (от long) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба А через функцию char *ltoa(long value, char *string, int radix)? Или ее нет в библиотеке? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба Спасибо всем откликнувшимся. Вот что получилось (компилятор - 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bloodden 0 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба Еще от компилятора зависит, какая там спринтф будет, в ИАРе, вроде поддержку ЛОНГ отдельно надо включать, в настройках проекта. Истина. Как и в CVAVR впрочем тоже. В настройках проекта. По-умолчанию там стоит до инта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tomade 0 21 августа, 2008 Опубликовано 21 августа, 2008 · Жалоба АНТОХА: Надо не 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); - ни к чему не приводит. Короче, пойду покупать пистолет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться