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

Управление меню с помощью трёх кнопок (Си)


-=FISHER=-

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

Вас подводит желание упихнуть все варианты в одну функцию... Изначально функция trim_convert работала только с целыми числами без всяких форматов. Она выводила и 0 в том числе. 

Форматированный вывод - это всего-навсего вывод в заданные позиции. По умолчанию эта функци всегда выводит число справа налево, начиная с крайней правой позиции. Если нумеровать позиции индикатора так же справа налево, то эта функция выводит число, начиная с позиции 0. Надо модифицировать эту функцию так, чтобы она получала в качестве параметра еще и номер позиции, начиная с которой число следует выводить.

Теперь вспоминаем, что есть еще функиция, которая вводит число вместе с незначащими нулями, у меня она называлась просто convert. Надо чуток дополнить ее, чтобы она могла получать второй параметр, определяющий позицию начала вывода числа, и третий - задающий общее количество позиций, которое должно содержать число, чтобы можно было ограничить количество нулей: для минут надо выводить 05, а не 0005 - верно? Справитесь с такой модификацией самостоятельно?

Итак, считаем, что у нас есть функции trim_convert и convert для вывода чисел. 

void trim_convert(int16_t n, uint8_t pos);
void convert(int16_t n, uint8_t pos, uint8_t len);

Ну а теперь решаем ваши задачи :)

1. Вывод времени с точкой:

setmem(scr, SPACE_CHAR, SCR_SIZE); // очистка экранной области - делается заранее до любого вывода

convert(minute, 0, 2); // вывод минут
trim_convert(hour, 2); // вывод часов
if(do_comma) scr[2] |= SEGMENT_H; // включение точки, если нужно

2. Температура:

scr[0] = CELSIUS_CHAR; // символ градуса
trim_convert(temperature * 10, 1); // температура в десятых долях
scr[1] |= COMMA_SEGMENT; // точка
// выведет, например, "0.0°" или "-3.7°"

3. Напряжение:

scr[0] = U_CHAR;
trim_convert(voltage, 1);

4. Строки.

Вот тут посложнее... т.к. кодировка "текста" не так уж и проста... Но, например, можно так:

// таблица кодировки букв
// макросы вида A_CHAR задают битовую комбинацию сегментов для соответствующего символа
const __flash uint8_t charset['Z'-'A'] = {
  A_CHAR, // A
  B_CHAR, // B
  ...
  Z_CHAR // Z
}

// вывод символа в указанную позицию
static void put_char(char c, uint8_t *pos){
  if((c >= 'A') && (c <= 'Z'))
    *pos = charset[c - 'A'];
}

// вывод строки всегда слева направо с крайней ЛЕВОЙ позиции
void put_str(char *s){
  uint8_t *pos = scr + SCR_SIZE; // указатель на позицию вывода
  while(*s && (pos > scr))
    put_char(*s++, pos--);
}

Тогда вывод слова "PAUSE" будет делаться так:

put_str("PAUSE"); // будет выведено PAUS

Аналогично можно сделать функцию, которая будет выводить строки из памяти программ (для экономии):

void put_pstr(const __flash char *s){
  uint8_t *pos = scr + SCR_SZ; // указатель на позицию вывода
  while(*s && (pos > scr))
    put_char(*s++, pos--);
}

И пользоваться ею:

put_pstr(PSTR("CLS")); // выведет CLS

 

Изменено пользователем ARV
Исправил опечатку в коде

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Я вам уже писал. Универсальность не всегда полезна. Опять же в чем универсальность. Вы должны сами провобовать, искать варианты, пробовать их. И тогда вам самим будет понятнее на своих проектах, где нужна универсальность, а где нет.

switch (mode_out)
{
   case MODE_OUT_TIME:
      // здесь функция вывода времени. Признак точки и ее знакоместо.
      break;

   case MODE_OUT_TEMPERATURE:
      // здесь функция вывода значения температуры. Признак точки и ее знакоместо.
      break;

case MODE_OUT_VOLTMETER:
      // здесь функция вывода значения напряжения. Признак точки и ее знакоместо.
      break;

case MODE_OUT_TEXT:
      // здесь функция вывода текста как есть.
      break;
}

 

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

6 минут назад, demiurg1978 сказал:

Вы должны сами провобовать, искать варианты, пробовать их.

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

 

7 минут назад, demiurg1978 сказал:

switch (mode_out) {

И в каждом кейсе функция типа trim_convert? Мне кажется это так же займет очень много места и будет не эргономично.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

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

1 минуту назад, -=FISHER=- сказал:

И в каждом кейсе функция типа trim_convert?

Типа кусочков кода, что я вам привел ранее.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

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

Только что, ARV сказал:

Типа кусочков кода

Я Ваше сообщение позже заметил чем это(( сейчас разбираю , спасибо!

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

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

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

При выводе отрицательной температуры код придется усложнить, т.к. с десятыми долями и символом градуса выводить температуру ниже -9,9° не получится - минус не поместится. Поэтому надо проверять значение темперауры и для более низких значений не выводить доли градуса.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

8 минут назад, -=FISHER=- сказал:

И в каждом кейсе функция типа trim_convert? Мне кажется это так же займет очень много места и будет не эргономично.

Иногда приходится писать как есть, пока не заработает. А когда заработает, уже разбираться что с этим делать.

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

2 минуты назад, ARV сказал:

При выводе отрицательной температуры код придется усложнить

Я использую 9-битный, и поэтому температура измеряется с точностью 0.5 градуса и я решил что выводить десятые доли не буду.

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Тогда все равно код можно усложнить, чтобы для небольших (по модулю) температур выводить еще и символ цельсия :) Типа так -3°С или 12°С

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

14 минут назад, -=FISHER=- сказал:

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

Есть метод switch-case. Почитайте в интернете на тему структурированный код. Скачивайте чужие примеры. И на них учитесь. Ищите литературу по методам подходам по программированию. Не по языкам а именно приемам программирования.

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

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

Скачивайте чужие примеры.

Сейчас в основном так и делаю, потом уже пишу свой на их основе.

 

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

Не по языкам а именно приемам программирования.

Хорошо, может быть что-то конкретное посоветуете?

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Я не помнил названия книг. К примеру,  Роберт Мартин. Чистый код. Создание, анализ и рефакторинг.

Скажу так, ищите в магазинах, в интернете. К примеру, ключевые слова "эффективное программирование". И не обязательно книги, ищите статьи в интернете

Цикл статей Татарчевского.

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

Я упомянул книгу, и решил ее себе на смартфон скопировать. Открыл, и сразу же наткнулся на очень важную вещь. Я забыл, просто откуда все идет. Так вот, в книге поднимается очень важный вопрос. Эффективность и оптимизация производства. Да-да, именно так. это как говорится, не письки на заборе рисовать... Так вот в книге в свою очередь упоминаются книги Система 5S. И я бы порекомендовал в первую очередь почитать книги по системе 5S. У меня родители всю жизнь на заводах работали. И так получилось, что в свое время интересовался промышленностью, технологиями. Что самое смешное, в СССР все это было бесплатно. Как сделать производство эффективным. А сейчас за какую-то сраную книжку почти ни о чем, или за тренинг выложи копейку... Порой немалую.

Поэтому, мой настоятельный совет. Почитать сначала книги по системе 5S и около этих тем. Так вы поймете суть книги. Мало того, это поднимет ваше понимание на немаленький уровень. Притом не только в программировании. Вообще в жизни пригодится. И повторю, поднимет понимание на достойный уровень. А это уже управленческий уровень.

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

Книги есть и наверно они хорошие, но они в основном направлены на создание правильной архитектуры приложения с использованием объектно-ориентированного программирования (т.е. C++ и другие). Для микроконтроллеров используется в основном только структурное программирование (Си), которое практически не развивается. В основном всё сводится к оптимизации кода.

Книги:
- Совершенный код (2010,Макконнелл);
- Правила программирования на Си и C++ (2001,Голуб).

По поводу 5С. У нас на предприятии внедрена и вызывает только отвращение. К тому же сами "учителя" говорят, что в России эта система не работает. На предприятиях существует формально, потому что так надо. Может задумка внедрения была и хорошая, но опять что то пошло не так. Когда устроился на предприятие и мне стали рассказывать что и как надо делать по системе 5С, у меня был первый вопрос: "А до того как вы узнали про 5С вы сами не понимали, что нужно делать именно так?". Мы и раньше и не зная 5С так работали, потому что это подсказывал здравый смысл. Реально внедрять 5С не даёт само руководство, хоть и говорит всем что у нас внедрена система 5С. (видимо накипело).

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

Да, Совершенный код. Вам тоже сенкс. Скачаю эти книги.

В СССР все это перерабатывалось с учетом менталитета и условий. И все работало на ура. На крупных предприятиях внедрялись системы схожие с 5S. Я когда первый раз услышал про 5S, увидел в этом что-то знакомое. А потом-ептыть! В СССР все это было! Вот если бы найти подобные книги советских времен, методички...

Когда я упомянул 5S я хотел довести более важное: оптимизацию собственного труда. Сделать его более эффективным. А это подразумевает системное мышление. Которое тоже нужно зарождать в себе и развивать.

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

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

Справитесь с такой модификацией самостоятельно?

Да. Вот такие функции вышли из Ваших первоначальных после доработок:

Скрытый текст

 


void convert(uint16_t NUM, uint8_t pos, uint8_t len)
{
	int i, m;
	for(i=pos; i<=len; i++) // цикл заполнения выходного массива СПРАВА НАЛЕВО
	{
		m = NUM % DIG_BASE; // находим остаток от деления числа на основание
		scr[i] = zgen[m]; // этот остаток есть ВЫВОДИМАЯ ЦИФРА
		NUM /= DIG_BASE;  // уменьшаем число в DIG_BASE раз
	}
}
			

void trim_convert(unsigned int NUM, uint8_t pos)
{
	int i=0, m;
	for(i=pos; i<=MAX_SIZE; i++) // цикл заполнения выходного массива СПРАВА НАЛЕВО
	{
		m = NUM % DIG_BASE; // находим остаток от деления числа на основание
		if((NUM==0)&&(i!=MAX_SIZE-1))
		break; // если наше число - ноль и вывод НЕ в правую позицию закончим цикл вывода числа
		else
		{
			scr[i] = zgen[m]; // иначе выводим символ нужной ЦИФРЫ
			NUM /= DIG_BASE;  // уменьшаем число в DIG_BASE раз			
		}
	}	// число выведено, проверяем свободное место и выводим при необходимости знак	
	if (Cminus){scr[i++] = NEG_CHAR;} // выводим знак, если нужно
	for(; i<MAX_SIZE; i++) scr[i] = SPACE_CHAR; // очищаем незначащие позиции
}	

 

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

1. Вывод времени с точкой:


setmem(scr, SPACE_CHAR, SCR_SIZE); // очистка экранной области - делается заранее до любого вывода

convert(minute, 0, 2); // вывод минут
trim_convert(hour, 2); // вывод часов
if(do_comma) scr[2] |= SEGMENT_H; // включение точки, если нужно

Подождите, но в таком случае, если время будет 0.01, то на дисплее отобразится только _.01 ?.. Значит нужно отловить входящий 0 в функцию trim_convert и принудительно вывести символ нуля на первое же знакоместо?

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Только что, -=FISHER=- сказал:

Подождите, но в таком случае, если время будет 0.01, то на дислпее отобразится только _.01 ?

Вот смотрите в это место:

if((NUM==0)&&(i!=MAX_SIZE-1))
		break; // если наше число - ноль и вывод НЕ в правую позицию закончим цикл вывода числа

Если результат 0, и при этом позиция не "крайняя", тогда цикл должен кончиться. Крайняя позиция - это та правая позиция, с которой начинается вывод. Надо подкорректировать, и все будет нормально.

Мои функции всегда выводят минимум 1 позицию, поэтому ситуации, когда просто 0 не выводится, быть не может. Видимо, раньше у вас не работало из-за того, что пропущены скобки (MAX_SIZE-1), и единица отнималась от результата сравнения...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

5 минут назад, ARV сказал:

Если результат 0, и при этом позиция не "крайняя", тогда цикл должен кончиться. Крайняя позиция - это та правая позиция, с которой начинается вывод. Надо подкорректировать, и все будет нормально.

До меня дошло. Значение крайней позиции будет как раз таки в переменной pos. Поправил, заработало! Спасибо!

if((NUM==0)&&(i!=pos)
		break; // если наше число - ноль и вывод НЕ в правую позицию закончим цикл вывода числа

 

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Надеюсь, вы догадались, что do_comma - это переменная, которая по таймеру должна меняться, чтобы обеспечить мигание точки? ;) 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

 

2 минуты назад, ARV сказал:

Надеюсь, вы догадались

Да :thank_you2:я прямо вот так проверяю точку:

if(PIN_SWQ&(1<<SQW)){scr[2]|=COMMA_CHAR;} //подмешаем точку во время

 

Я в итоге выбрал анимацию смены отображаемой информации - бегущую строку. Что скажете на счет моего метода её реализации?.. Я решил что будет логично записать массив экранной области в середину временного массив из 12 элементов, а затем если нужно "уехать" из кадра, то просто перезаписываю временный массив в scr со смещением, а если нужно "въехать" в кадр, то тоже просто перезаписываю, только начинаю с другой позиции.

void running_string(uint8_t screen[], uint8_t step, uint8_t dir) //
{
		for(int j=0; j<MAX_SIZE; j++){out[j+4] = screen[j];} //заполнили временный массив
		
		memset (scr, SPACE_CHAR, MAX_SIZE); //очистим экранную область
		
		for(int j=0; j<MAX_SIZE; j++)
		{
			for(int k=0; k<MAX_SIZE; k++)
			{
				scr[k] = out[k+step];
				
			}
			if(dir==LEFT) step--; //если едем влево, то отнимаем смещение
			if(dir==RIGHT) step++; //если едем вправо, то прибавляем смещение
          
			refresh_scr();
			_delay_ms(80);
		}	
}

 

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

m = NUM % DIG_BASE; // находим остаток от деления числа на основание

Мне не нравятся подобные места. У AVR все-таки свои ограничения. Поэтому совет, избавляться от дробных чисел. Переводить все в целочисленное.

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

Пример для семисегментных дисплеев.

//========================================================================
extern void _Print_Char (u08 x, u08 a);
#define Print_Char(x, a) _Print_Char(((x)-1), (a)) // Вывод символа.

// Пример использования: Print_Char (1, 'A'); Вывести A на 1 знакоместо.
//========================================================================

//========================================================================
extern void _Print_Buf (u08 x, char __flash *data);
#define Print_Buf(x, data) _Print_Buf(((x)-1), (data)) // Вывод строки.

// Пример использования: Print_Buf (1, "PETYA"); Вывести PETYA.
// Первый символ на 1 знакоместе.
//========================================================================

//========================================================================
void _print_i_ph_x (u08 x, u32 a);
#define print_i_ph_x(x, a) _print_i_ph_x(((x)-1), (a)) // Вывести значение
// тока. Значение конвертированное из float в u32
//------------------------------------------------------------------------

//========================================================================
void _Print_Char (u08 x, u08 a)
{
   dsp_buf [x] = a;
}
//========================================================================

//========================================================================
void _Print_Buf (u08 x, char __flash *data)
{
   for (u08 i = 0; data [i] != 0;)
   {
      dsp_buf [x++] = data [i++];
   }
}
//========================================================================

//========================================================================
void _print_i_ph_x (u08 x, u32 a)
{
   val_to_str (a, VAL_32_BIT);

   char *ptr = num_str_buf + 5;

   for (u08 i = 3; i > 0; i--)
   {
      if (i < 3)
      {
         if (*ptr == ' ') // Гашение незначащего нуля.
         {
            dsp_buf[x] = '0';
         }
         else
            dsp_buf[x] = *ptr;
      }
      else
         dsp_buf[x] = *ptr;

      x++;
      ptr++;
   }

Библиотечка перевода систем счисления.

#ifndef BCD_H
#define BCD_H

#include "bcd.h"

#include "main_def_func.h"

//========================================================================
extern char num_str_buf [];
extern char tmp_num_str_buf [];
//========================================================================

//========================================================================
typedef enum
{
   VAL_08_BIT = 0,
   VAL_16_BIT,
   VAL_32_BIT,
} type_val_t;

void val_to_str (u32 value, type_val_t type_val);

u16 str_to_int (void);
u32 str_to_long (void);
//========================================================================

//========================================================================
void clr_tmp_num_str_buf (void);
void clr_num_str_buf (void);
//========================================================================

#endif //BCD_H

//========================================================================
#include "bcd.h"
//========================================================================

//========================================================================
char num_str_buf [11];
char tmp_num_str_buf [11];
//========================================================================

//========================================================================
void clr_tmp_num_str_buf (void)
{
   char *ptr = tmp_num_str_buf;
   u08 cnt = 10;

   while (cnt)
   {
      *ptr++ = ' ';
      cnt--;
   }
   *ptr = 0;
}
//========================================================================

//========================================================================
void clr_num_str_buf (void)
{
   char *ptr = num_str_buf;
   u08 cnt = 10;

   while (cnt)
   {
      *ptr++ = ' ';
      cnt--;
   }
   *ptr = 0;
}
//========================================================================

//========================================================================
u32 __flash tab_hex_dec [] =
{
   1000000000U,
   100000000U,
   10000000U,
   1000000U,
   100000U,
   10000U,
   1000U,
   100U,
   10U,
};
//========================================================================

//========================================================================
void val_to_str (u32 value, type_val_t type_val)
{
   u32 a;

   bool flag = false;

   u08 cnt_1;
   u08 cnt_2;

   u08 displace;

   clr_num_str_buf ();

   switch (type_val)
   {
      case VAL_08_BIT:
         displace = 7;
         cnt_1 = 2;
         break;

      case VAL_16_BIT:
         displace = 5;
         cnt_1 = 4;
         break;

      case VAL_32_BIT:
         displace = 0;
         cnt_1 = 9;
         break;
   }

   char *ptr = num_str_buf + displace;

   u32 __flash *ptr_f = tab_hex_dec + displace;

   while (cnt_1)
   {
      a = *ptr_f;
      cnt_2 = 0;

      while (value >= a)
      {
         value -= a;
         cnt_2++;
      }

      if (flag == false)
      {
         if (cnt_2 == 0)
         {
            *ptr++ = ' '; // Гашение незначащих нулей.
         }
         else
         {
            *ptr++ = (cnt_2 | 0x30);
            flag = true;
         }
      }
      else
      {
         *ptr++ = (cnt_2 | 0x30);
      }

      ptr_f++;
      cnt_1--;
   }
   *ptr++ = (value | 0x30);
   *ptr = 0;
}
//========================================================================



//========================================================================
u16 str_to_int (void)
{
   char *ptr_num = tmp_num_str_buf + 5;
   u32 __flash *ptr_f = tab_hex_dec + 5;
   u16 a;
   u08 cnt = 0;
   u16 tmp_value = 0;

   while (cnt < 4)
   {
      if ((*ptr_num > 0x30) && (*ptr_num < 0x3A))
      {
         a = (*ptr_num - 0x30);

         while (a)
         {
            tmp_value += *ptr_f;
            a--;
         }
      }
      *ptr_num++;
      ptr_f++;
      cnt++;
   }
      return tmp_value += (*ptr_num - 0x30);
}
//========================================================================

//========================================================================
u32 str_to_long (void)
{
   char *ptr_num = tmp_num_str_buf;
   u32 __flash *ptr_tab_10 = tab_hex_dec;
   u32 a;
   u08 cnt = 0;
   u32 tmp_value = 0;

   while (cnt < 9)
   {
      if ((*ptr_num > 0x30) && (*ptr_num < 0x3A))
      {
         a = (*ptr_num - 0x30);

         while (a)
         {
            tmp_value += *ptr_tab_10;
            a--;
         }
      }
      *ptr_num++;
      ptr_tab_10++;
      cnt++;
   }
      return tmp_value += (*ptr_num - 0x30);
}
//========================================================================

 

Пример перевода 8-битного числа в десятичное. Алгоритм работы такой: Есть буфер, который выводится на дисплей. Сначала преобразование числа, потом перекидывание в буфер дисплея.

void _print_u08_00X (u08 x, u08 a);
#define Print_Num_Recipe() _print_u08_00X(((2)-1), (get_num_recipe() + 1))
#define Print_Num_Component() _print_u08_00X(((3)-1), (get_num_component() + 1))

void _print_u08_00X (u08 x, u08 a)
{
   val_to_str (a, VAL_08_BIT);

   char *ptr_1 = dsp_buf + x;
   char *ptr_2 = num_str_buf + 9;

   *ptr_1 = *ptr_2;
}

 

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

Когда  вижу подобные "примеры", мне почему-то хочетс плакать...

43 минуты назад, demiurg1978 сказал:

Мне не нравятся подобные места. У AVR все-таки свои ограничения. Поэтому совет, избавляться от дробных чисел.

Где же вы увидели дробные числа?

43 минуты назад, demiurg1978 сказал:

m = NUM % DIG_BASE; // находим остаток от деления числа на основание

Какие у AVR есть ограничения? Кто ограничивает? Откуда эти стереотипы, что нельзя применять float? 

 

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

Не увидел в теме, наверное нужно в программу "МЕНЮ" добавить функцию автоматического выхода по истечении определённого времени,

при отсутствии нажатий кнопок и сохранением  изменений настроек.

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

5 часов назад, demiurg1978 сказал:

Иногда приходится писать как есть, пока не заработает. А когда заработает, уже разбираться что с этим делать.

634cd3537c1c1b3e939025066e4fa718.gif.0fa39aa6a45dd99d2983b3c1f9f5288f.gif

Расслабьтесь немного!

ИМХО Сделали массив из четырех строк (скорее набора символов) в нужном формате вывода, напряжение, время, температура, hello. По командам кнопок выводить нужный уже сформированный с необходимыми символами U, T и др. С необходимой частотой обновления дисплея. А формирование массива производить по соответствующему событию. Потому как каждый раз перед выводом формировать строку неэффективно.

 

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

ARV вы забыли что я начинал на ассемблере. Родные библиотеки раздувают код. В ряде случаев работают медленнее. А мой подход в большинстве случаев итерация основного цикла с запасом 1 мс. Это означает, что все задачи, которые работают в данный момент должны провернуться менее чем за 1 мс. Поэтому я свой код всегда проверяю в дизассемблере. Пока не добьюсь оптимальных результатов. И именно по этой причине использую IAR.

Ограничения у AVR объем памяти и скорость.

Вы по своему решаете свои задачи. Я по своему.  У вас свой опыт свое направление в электронике. У меня свое. Это не хорошо не плохо.

8 минут назад, AL_smeu сказал:

...

 

Известная картинка :)

Не всегда памяти достаточно, чтобы формировать массивы для каждого чиха.

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

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

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

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

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

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

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

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

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

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

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

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

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