Перейти к содержанию
    

Как вывести на LCD большое число

Подскажите чайнику, как переехать такую проблему.

Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12.

Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему?

Изменено пользователем Tomade

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ответа на Ваш вопрос, Вы указали мало данных.

Как минимум нужно видеть Ваш код.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите чайнику, как переехать такую проблему.

Микроконтроллер серии ATMega, нужно выводить на ЖКИ типа РС1602F (c контроллером) инкрементируемую переменную, которая может принимать значения, к примеру, от 0 до 1 000 000. Работу программы (см. вложение) симулирую на VMLAB3.12.

Что получается? До значания переменной, равного 32767, всё идёт нормально. А вот следующее индицируемое число равняется -32768 (со знаком минус), и все последующие начинают декрементироваться, то есть -32767, -32766, -32765 и т.д. Почему?

 

Потому что объявлено как int, старший бит трактуется как знак. Объявите unsigned int - получите 0 .. 65535. Читайте про представление чисел в Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потому что объявлено как int, старший бит трактуется как знак. Объявите unsigned int - получите 0 .. 65535

Всё равно не хватит до миллиона, надо объявить переменную как LONG.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё равно не хватит до миллиона, надо объявить переменную как 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);}}

 

- эффекта никакого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно... есть же на данном форуме тема с чужим готовым кодом...

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sprintf(lcd_buffer,"%i",x);

"%i" - это int, надо - "%l" или "%lu" (второе для unsigned 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);}}

 

- эффекта никакого.

 

Обратите внимание на указанную функцию. В CodeVision в настройках надо указывать какую библиотеу вы будете тиспользовать:

 

- Меню Project \ Confugire

- В окне настроек вкладка C Compiler

- На вкладке внизу слева настройки (s)printf Features

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем откликнувшимся. Вот что получилось (компилятор - 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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если в строке sprintf(lcd_buffer,"%i",x) вместо i ставить I или Iu, то в симуляторе на табло LCD вообще ничего не выводится (и для int, и для long).

 

Надо не I, а L! (от long)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем откликнувшимся. Вот что получилось (компилятор - 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще от компилятора зависит, какая там спринтф будет, в ИАРе, вроде поддержку ЛОНГ отдельно надо включать, в настройках проекта.

Истина. Как и в CVAVR впрочем тоже. В настройках проекта. По-умолчанию там стоит до инта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

АНТОХА: Надо не 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); - ни к чему не приводит.

Короче, пойду покупать пистолет. :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...