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

Поразрядное редактирование десятичного числа


RIMUS1989i

Рекомендуемые сообщения

Добрый день. Прошу помощи в определении алгоритма для поразрядного изменения числа - переменной. Имеется дисплей, пусть будет 1602, выводим на него число (переменную) в десятичной системе счисления, например "uint16_t value = 32678", как его изменить поразрядно? 

 

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Для числа - отнять или прибавить сколько надо с соответствующей разряду степенью десяти. Например, 30678=32678-2000. И снова вывести на 1602. Или вывести нужный знак в нужную позицию командами HD44780.

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Набросал вот такой алгоритм, но мне не нравится, жрет очень много ресурсов. Он не допилен т.к. нет проверки максимума каждого разряда, при переполнении разряда происходит увеличение старшего разряда.

Функция редактирования bitwise_number_change, где val - редактируемое значение, n - номер разряда от младшего к старшему, diff - значения от энкодера +1 или -1, x,y куда рисовать.

#define DEFAULT_MAX 30000UL
uint8_t divide_number_into_digits(uint16_t value, uint8_t n_digit)
{
	int8_t out = 0;
	switch(n_digit)
	{
		case 0: out = (value/10000);break;
		case 1: out = (value/1000)%10;break;
		case 2: out = (value/100)%10;break;
		case 3: out = (value/10)%10;break;
		case 4: out = value%10;break;
	}
	return out;
}


uint16_t bitwise_number_change(uint16_t val, uint8_t n, int8_t diff, uint8_t x, uint8_t y)
{
	uint16_t vi = 1;

	for(uint8_t i = 0; i < n; i++)
	{
		vi *= 10;
	}

	val += vi * diff;

	ks0066SetXY(x,y);

	for(uint8_t d = 0; d < 5; d++)
	{
		ks0066WriteData('0' + divide_number_into_digits(val,d));
	}

	if(val > DEFAULT_MAX) val = DEFAULT_MAX;

	return val;
}

 

1 минуту назад, _abk_ сказал:

Для числа - отнять или прибавить сколько надо с соответствующей разряду степенью десяти. Например, 30678=32678-2000. И снова вывести на 1602. Или вывести нужный знак в нужную позицию командами HD44780.

Чуть опоздал я с сообщением. 

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

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

1 час назад, RIMUS1989i сказал:

жрет очень много ресурсов

Так пока будете комбинировать код из всяких "функций редактирования", эта проблема так и будет тянуться, как тянутся в код тела библиотек. :)

Простейшие действия с числами самому писать надо.

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

эту проверку

4 часа назад, RIMUS1989i сказал:

if(val > DEFAULT_MAX) val = DEFAULT_MAX;

нужно делать перед выводом числа, а не после.

а так, логически делано правильно.

Мудрость приходит вместе с импотенцией...

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

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

Литиевые аккумуляторы EVE Energy и решения для управления перезаряжаемыми источниками тока (материалы вебинара)

Опубликованы материалы вебинара Компэл, посвященного литиевым аккумуляторам EVE Energy и решениям для управления перезаряжаемыми источниками тока.

На вебинаре мы представили информацию не только по линейкам аккумуляторной продукции EVE, но и по решениям для управления ею, что поможет рассмотреть эти ХИТ в качестве дополнительной альтернативы для уже выпускающихся изделий. Также рассмотрели нюансы работы с производителем и сервисы, предоставляемые Компэл по данной продукции. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

2 часа назад, Lexter сказал:

Так пока будете комбинировать код из всяких "функций редактирования"

Эм... не понял, вы про какие библиотеки говорите?

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

  • 3 недели спустя...

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

С числами проще работать в шестнадцатеричном коде. Преобразование нужно делать только при выводе на дисплей. Действия с числами зависят от интерфейса. То, как вы работаете с числами и как вы их выводите. Поразрядное, более ресурсоемкое. В своих проектах я использую в параметрах шестнадцатеричные числа. И для вывода, редактирования приходится использовать двойное преобразование. В десятеричное, для вывода на дисплей, и обратно в шестнадцатеричные, чтобы в этом виде и сохранять в параметрах устройства. Поразрядное редактирование мне пришлось делать 1 раз, когда это было жесткое требование. Лично я старался работать напрямую с шестнадцатеричными числами. Преобразование делалось только для вывода на дисплей.

Мой пример, как это было сделано у меня. Может и не так оптимизированно, но тогда я решил так.

void change_recipe_parameters (void)
{
   u16 a = 0;

   switch (cnt_blink_char)
   {
      case 1:
         change_num_recipe ();
         break;

      case 2:
         change_num_component ();
         break;

      case 3:
         if (++tmp_num_str_buf [6] > 0x39) // Тысячи.
            tmp_num_str_buf [6] = 0x30;

         a = weight_to_int ();

         if (a > 5000)
         {
            tmp_num_str_buf [6] = 0x30;
            a = weight_to_int ();
         }

         info_parameters. tmp_components [info_parameters. tmp_num_component] = a;
         break;

      case 4:
         if (++tmp_num_str_buf [7] > 0x39) // Сотни.
            tmp_num_str_buf [7] = 0x30;

         a = weight_to_int ();

         if (a > 5000)
         {
            tmp_num_str_buf [7] = 0x30;
            a = weight_to_int ();
         }

         info_parameters. tmp_components [info_parameters. tmp_num_component] = a;
         break;

      case 5:
         if (++tmp_num_str_buf [8] > 0x39) // Десятки.
            tmp_num_str_buf [8] = 0x30;

         a = weight_to_int ();

         if (a > 5000)
         {
            tmp_num_str_buf [8] = 0x30;
            a = weight_to_int ();
         }

         info_parameters. tmp_components [info_parameters. tmp_num_component] = a;
         break;

      case 6:
         if (++tmp_num_str_buf [9] > 0x39) // Единицы.
            tmp_num_str_buf [9] = 0x30;

         a = weight_to_int ();

         if (a > 5000)
         {
            tmp_num_str_buf [9] = 0x30;
            a = weight_to_int ();
         }

         info_parameters. tmp_components [info_parameters. tmp_num_component] = a;
         break;
   }

   rerun_blink_noblank_char ();
   rst_out_mode_work ();
}

В том проекте у меня было так:

ХХ ХХХХ где первый х - это номер рецепта, второй х это номер компонента, и последние четыре икса это значение веса от 0 до 9999.

Вывод я делал сразу в ASCII кодах, поэтому несколько заморочно. Также в том проекте было только кольцевое приращение числа. И если 9, то сброс в 0. В вашем случае еще придется проверять, в какую сторону идет редактирование. Инкремент или декремент.

После каждой операции сразу идет преобразование числа в шестнадцатеричное.

Комментарии какие есть, я сейчас занят. Небольшое пояснение могу показать только на видео. Если найду.

Изменено пользователем demiurg1978
Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Добрый день. Давно не подходил к этому проекту, но решил к нему вернуться.

Окончательная функция получилась в таком виде (см. ниже). Она работает для 16ти битного числа, кто ее захочет использовать, обратите внимание, нет проверки на максимально допустимое число для 16бит - 65535. Мне достаточно до 25000. 

#define	DEFAULT_MAX	25000
static const uint16_t mas[5] PROGMEM =  {1,10,100,1000,10000};

uint16_t bitwise_number_change(uint16_t val, uint8_t n, int8_t diff, uint8_t x, uint8_t y)
{
	if(n > 4) return val;
	uint8_t iv = 0;

	iv = (val/pgm_read_word(&mas[n]))%10;		// Выбираем нужный разряд в десятичной системе
	val = val - iv * pgm_read_word(&mas[n]);	// Обнуляем выбраный разряд
	
	iv = iv + diff; 			// Производим изменение нужного разряда +-1
	
	// Проверяем разряд на правильность введеного значения
	if((iv & 0x0f) == 15) iv = 9;
	if(iv > 9) iv = 0;
	

	val = val + iv * pgm_read_word(&mas[n]);	// Записываем новое значение разряда
	
	if(val > DEFAULT_MAX) val = DEFAULT_MAX; // Проверяем значение на максимально доступное

	ks0066SetXY(x, y);			// Координаты выводимого числа
	for(uint8_t i = 0; i < 5; i++)// Выводим число
		ks0066WriteData('0' + (val/pgm_read_word(&mas[4-i]))%10); 

	if(level > LEVEL_MENU_CHILD && level <= LEVEL_MENU_DIGIT_5) // Если уровень меню в редакторе, рисуем курсор
	{
		ks0066SetXY(x + 4 - n, y);
		ks0066WriteCommand(0x0E);
	}else{
		ks0066WriteCommand(0x0C); // Удаляем курсор
	}
	return val;
}

 

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...