Jump to content
-=FISHER=-

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

Recommended Posts

Вас подводит желание упихнуть все варианты в одну функцию... Изначально функция 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

 

Edited by ARV
Исправил опечатку в коде

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

 

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

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

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

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

 

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

switch (mode_out) {

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


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

Share this post


Link to post
Share on other sites

Вебинар «Параметры выше, цена ниже. Обновление в линейке AC/DC- и DC/DC-преобразователей MORNSUN» (26.01.2021)

Приглашаем 26 января на бесплатный вебинар, посвящённый преимуществам и отличиям новых источников питания и DC/DC-преобразователей Mornsun. На вебинаре будут рассмотрены изолированные и неизолированные DC/DC-преобразователи последнего, четвертого, поколения (R4) и компактные модульные источники питания второго и третьего поколений (семейства LS/R3 и LD/R2) на плату. Рассмотрим новую группу продукции – встраиваемые источники питания в кожухе.

Подробнее

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

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

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


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

Share this post


Link to post
Share on other sites

Вебинар "Новый BlueNRG-LP с Bluetooth 5.2 и Long Range — волшебная палочка разработчика IoT" (04/02/2021)

Приглашаем 4 февраля на бесплатный вебинар о BlueNRG-LP - новом программируемом чипе SoC STMicroelectronics. На вебинаре будут детально рассмотрены новые возможности, особенности подключения, аппаратные и программные средства для разработки, а также практические примеры работы с микросхемой.

Подробнее

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

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

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


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

Share this post


Link to post
Share on other sites

Плата STEVAL-IDB011V1 – тестируем идеи на новом BLE 5.2-чипе BlueNRG-LP

Новая система на кристалле BlueNRG-LP производства STMicroelectronics предназначена для устройств интернета вещей(IoT ) и не только, отвечает стандарту BLE 5.2 и поддерживает MESH-сети. Микросхема содержит малопотребляющий MCU Cortex-M0+. Отладка STEVAL-IDB011V1 позволит сэкономить время на разработку новых устройств.

Подробнее

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


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

Share this post


Link to post
Share on other sites
8 минут назад, -=FISHER=- сказал:

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

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

Share this post


Link to post
Share on other sites
2 минуты назад, ARV сказал:

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

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


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

Share this post


Link to post
Share on other sites

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


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

Share this post


Link to post
Share on other sites
14 минут назад, -=FISHER=- сказал:

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

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

Share this post


Link to post
Share on other sites
1 минуту назад, demiurg1978 сказал:

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

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

 

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

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

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


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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites
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 и принудительно вывести символ нуля на первое же знакоместо?

Edited by -=FISHER=-

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

Share this post


Link to post
Share on other sites
Только что, -=FISHER=- сказал:

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

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

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

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

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


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

Share this post


Link to post
Share on other sites
5 минут назад, ARV сказал:

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

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

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

 

Edited by -=FISHER=-

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

Share this post


Link to post
Share on other sites

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


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

Share this post


Link to post
Share on other sites

 

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);
		}	
}

 


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

Share this post


Link to post
Share on other sites
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;
}

 

Edited by demiurg1978

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

 

Edited by ARV

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
5 часов назад, demiurg1978 сказал:

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

634cd3537c1c1b3e939025066e4fa718.gif.0fa39aa6a45dd99d2983b3c1f9f5288f.gif

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

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

 

Share this post


Link to post
Share on other sites

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

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

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

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

...

 

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Для нормального режима стабилизации нужно обеспечить минимальный ток через стабилитрон хотя бы 3 мА. А лучше больше (чтобы можно было проверять средней мощности и мощные). Умножаем 300 В на 0,003...0,01 А и получаем 0,9...3 Вт. Не многовато ли? Может, стОит "урезать осетра"?
    • @sergey bolloev Тут дюже не любят смотреть ролики, кроме как анального, тем более такие здоровые. А вот чего на этот коротЕький ролик скажут? Оказывается наши спортсмены могут выступать под флагом СССР. Причём с них будут сняты допинговые грехи РФ. Новосибирский мэр заявил. Ведь ни для кого давно не секрет, что государства РФ нет, и не было, и весь мир это знает. Я, кстати, так в своих письмах в негосударственные коммерческие структуры и пишу, лицу, замещающему государственную должность прокурора, и т.д.  
    • R20 на плате сейчас не стоит - когда с 5,1 кОм напряжение не повысилось выпаял его, хотел поставить еще большего номинала. R25 62 Ом. 
    • Давайте не будем о грустном.
    • Новые вызовы требуют новых решений. Буду здесь постепенно выкладывать свои решения    
    • Я настолько не знаю  языка , что даже сам не догадался бы, что это дистанционное управление. А далее чисто логика - если проектов несколько - значит они чем то отличаются . И на tn2313 скорее всего уже подобный , так как такое управление востребовано .  Для перевода у меня стоит закладка "переводчик" в браузере , куда скидываю нужный текст .  Есть более продвинутые системы , но  мне и так нормально.  Кстати код чеха не позволяет параллельно включать кнопки местного управления . С транзисторами можно, у них открытый выход (коллектор) . Открытый выход можно сделать и на МК .  Или как костыль использовать последовательные резисторы 1-10к . И как костыль же поставить после резисторов конденсаторы , чтоб была интегрирующая RC цепь , подправляющая особенности кода .    
    • Я как бы тоже, штука полезная или даже кайфовая. Только посмотрите на этом и соседних форумах, сколько конструкций с лимитером и без. Даже если мощности несколько сот Вт и необходимость в нем как и в слежинии за ОБР не обсуждается. В середине нулевых ВП только и твердил:... защита,... лимитер,... "... гарантировано хуже - нет защиты". А популярность получил только "упрощенный" поскребыш без этого всего. Оказалось что всем "для дома не нужен". Прошло более 15и лет. Можете привести пример форумных конструкций кроме Натали (ещё к ланзару какую то светомузыку приладиладили, и д-класс какой то помнится) в которых был изначально был лимитер и его не норовили кастрировать? 

  • Ультразвуковой датчик расстояния HC-SR04

×
×
  • Create New...