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

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


-=FISHER=-

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

28 минут назад, 100482 сказал:

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

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

Лехко.

//========================================================================
static u08 menu_flags;

static info_service_t _info_service;
static u08 _info_service_slave;

static soft_timer ST_INFO_SERVICE;

__flash FUNC info_service_func [INFO_SERVICE_STATES] =
{
#define STATE(name, func) func,
#include "_info_service.h"
#undef STATE
};

void info_service (void)
{
   proc_fsm_func (info_service_func, _info_service);
}
//========================================================================

//========================================================================
void info_service_out_menu_init (void)
{
   set_soft_timer (ST_INFO_SERVICE_OUT_MENU, 10000, 0);

   _info_service = INFO_SERVICE_OUT_MENU;
   _info_service_slave = 0;
}
//========================================================================

//========================================================================
void info_service_out_menu (void)
{
   if (handle_soft_timer (ST_INFO_SERVICE_OUT_I))
      info_service_menu_exit ();

   // bla-bla
}
//========================================================================

 

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

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

9 часов назад, 100482 сказал:

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

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

Это делается очень просто, @demiurg1978 показал примерно, как - при помощи таймера (программного): достаточно из обработчика этого таймера сымитировать нажатие кнопки "выход", т.е. заставить в нужный момент функцию опроса кнопок вернуть не 0 (отсутствие нажатий), а код этой кнопки (даже если она не существует - все равно код может существовать), а обработчик кнопок уже сделает все остальное.

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

вы забыли что я начинал на ассемблере

Нет, я об этом помню. Как помню и о вашей любви к конечным автоматам.

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

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

Не только у AVR. Но смысл ограничений в том, что о них надо помнить, а не в том, чтобы постоянно усложнять себе жизнь попытками избежать их. Ранее бытовало мнение (и сейчас еще некоторые в этом уверены), что для attiny13 программы писать на Си нельзя, т.к. памяти там очень мало - ограничения ужасные. Но на самом деле на Си для attiny13 можно писать достаточно сложные программы, почти ни в чем себе не отказывая! Аналогичное заблуждение и на счет float - да, минимум 2 килобайта поддержка float-математики отъест, но уже для atmega48 это не катастрофа, а для atmega8 практически незаметно. Зато насколько упрощается разработка (до поры до времени)! И на счет стандартных функций тоже - можно, конечно, как вы, написать мильён самописных функций для того, чтобы избежать применения printf, и получить код, который займет в atmega8 48% памяти. А можно подключить stdio.h и в 100500 раз проще решить задачу, заняв 89% памяти МК. 

Имхо, волков бояться - в лес не ходить. В любительской разработке стоит больше любить себя, чем микроконтроллер :) То есть освобождать от рутины свою голову, загружая его ядро. Что 1 мс на главный цикл, что 15 мс на его итерацию - не могу себе представить проект, где такая разница была бы критически важной...

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

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

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

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

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

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

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

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

Раз исчезла кнопка изменить сообщение, придется в лоб. Что-то не могу найти функцию прятать в спойлер.

/========================================================================
typedef enum _info_service
{
#define STATE(name, func) name,
#include "_info_service.h"
#undef STATE

INFO_SERVICE_STATES,
} info_service_t;
//========================================================================

//========================================================================
static u08 menu_flags;

static info_service_t _info_service;
static u08 _info_service_slave;

static soft_timer ST_INFO_SERVICE;

__flash FUNC info_service_func [INFO_SERVICE_STATES] =
{
#define STATE(name, func) func,
#include "_info_service.h"
#undef STATE
};

void info_service (void)
{
   proc_fsm_func (info_service_func, _info_service);
}
//========================================================================

#define MENU_TIMEOUT 10000

//========================================================================
void info_service_out_menu_init (void)
{
   set_soft_timer (ST_INFO_SERVICE, MENU_TIMEOUT, 0);

   _info_service = INFO_SERVICE_OUT_MENU;
   _info_service_slave = 0;
}
//========================================================================

//========================================================================
void info_service_out_menu (void)
{
   if (handle_soft_timer (ST_INFO_SERVICE))
      info_service_menu_exit ();

// Где-то в функции при каких либо действиях в меню ставится признак перезапуска таймера

   if (get_flag_menu_timeout ())
      set_soft_timer (ST_INFO_SERVICE, MENU_TIMEOUT, 0);

   // bla-bla
}
//========================================================================

1 - Никакой имитации, функция устанавливающая необходимое состояние автомата(ов) и все остального прочего.

2 - Никаких мук. Написал (отмучался один раз), потом просто используешь. Я ленивый человек (в хорошем плане). Делаю, когда целесообразно. Считаю, что целесообразно использовать самописную библиотеку, если тебе всего лишь нужно переводить переменные в системы счисления. Впрочем, здесь мы разошлись во мнениях. Это нормально.

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

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

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

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

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

Что-то не могу найти функцию прятать в спойлер

Пиктограмма глаза

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

достаточно из обработчика этого таймера сымитировать нажатие кнопки "выход", т.е. заставить в нужный момент функцию опроса кнопок вернуть не 0 (отсутствие нажатий), а код этой кнопки (даже если она не существует - все равно код может существовать), а обработчик кнопок уже сделает все остальное

В моём случае наверное после каждого нажатия кнопок навигации по меню нужно запускать таймер, а по истечению времени этого таймера просто нужно принудительно выставлять режим MODETIMEVIEW

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

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

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

void info_service (void) { proc_fsm_func (info_service_func, _info_service); }

Ну вот объясните мне тайный смысл вот такой обертки? Функция без параметров служит только для того, чтобы вызвать функцию с параметрами - зачем она нужна? Где ваша экономичная рациональность? Ведь ничего, кроме дополнительного call-ret это не дает?

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

В моём случае наверное после каждого нажатия кнопок навигации по меню нужно запускать таймер, а по истечению времени этого таймера просто нужно принудительно выставлять режим MODETIMEVIEW

В принципе - да, это фактически то же самое, что я и @demiurg1978 говорим.

Однако, традиционно для выхода из меню используется 2 функции: одна для выхода с запоминанием, другая - для выхода без запоминания и отката сделанных изменений. Т.е. одна выполняет функцию OK, а другая CANCEL (если рассуждать в категориях Windows-диалогов). Если вы все сделанные в меню изменения параметров сразу же применяете, у вас нет разницы между этими двумя "выходами", и просто изменить состояние по таймеру будет нормальным решением. Хотя, по идее, у вас должно быть какое-то сохранение настроек в EEPROM при "правильном" входе из меню...

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

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

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

Если вы все сделанные в меню изменения параметров сразу же применяете, у вас нет разницы между этими двумя "выходами", и просто изменить состояние по таймеру будет нормальным решением. Хотя, по идее, у вас должно быть какое-то сохранение настроек в EEPROM при "правильном" входе из меню...

У меня вход в меню - кнопка SET, затем + и - листаем пункты меню вправо, влево. И когда проходим всё меню то автоматически выходим и попадаем в MODETIMEVIEW.

А сохранение происходит после нажатия кнопки SET в подменю изменения выбранного параметра.

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

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

Ответ прост.

1 - Если автомат реализован с переходом по индексу и их несколько, я их пропускаю через эту функцию.

2 - Эта функция пока шаблон-заготовка. Есть некоторые мысли, но пока не реализовано. Все равно целесообразно. Не несколько мест разворачивающих переходы по индексу, а одно.

3 - Это идет еще со времен ассемблера. Я заепся на каждый автомат разворот делать, в итоге сделал функцию и макрос.

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

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

__flash FUNC info_service_func [INFO_SERVICE_STATES] = {

#define STATE(name, func) func,

#include "_info_service.h"

#undef STATE

};

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

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

Ответ прост

Целесообразность ради целесообразности? Перфекционизм без необходимости? Вы с кодом один работаете, или это у вас корпоративный стиль такой - нагромождение файлов, модулей, функций с подчеркиванием и без него, макросов с подчеркиваниями и без оного? Функций с вложенными макросами, макросов с вложенными функциями? Бесконечные инклюды... Все это, имхо, только путает.

Не, не мой вариант.

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

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

1 - Это ваше предпочтение и не более. Убирать лишнее с экрана. Остается только то, что касается алгоритма работы. Если алгоритм состоит из алгоритмов, значит другие алгоритмы будут в других местах. Всему свое место. Если я наизусть знаю, как работают вложенные алгоритмы, то они мне на экране мешают. Это называется мыслить блоками. Массивами. И вишенка на торт. Массивами массивов. Не торопитесь, услышьте меня.

2 - Проистекает из первого пункта. Загромождают экран.

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

//************************************************************************
//************************ Главный автомат *******************************
//************************************************************************

//========================================================================
STATE (PROC_EDS_MAIN_INIT,        Proc_Eds_Main_Init)
STATE (PROC_EDS_MAIN_STOP,        Proc_Eds_Main_Stop)
STATE (PROC_EDS_MAIN_MANUAL,      Proc_Eds_Main_Manual)
STATE (PROC_EDS_MAIN_AUTOMAT,     Proc_Eds_Main_Automat)
STATE (PROC_EDS_MAIN_EMERG_STOP,  Proc_Eds_Main_Emerg_Stop)
//========================================================================

//************************************************************************
//************************ Автомат "Автомат" *****************************
//************************************************************************

//========================================================================
STATE (PROC_EDS_AUTOMAT_IDLE,                empty_func)
STATE (PROC_EDS_AUTOMAT_WAIT_RUN,            Proc_Eds_Automat_Wait_Run)
STATE (PROC_EDS_AUTOMAT_RUN,                 Proc_Eds_Automat_Run)
STATE (PROC_EDS_AUTOMAT_WAIT_FORM_CLOSING_1, Proc_Eds_Automat_Wait_Form_Closing_1)
STATE (PROC_EDS_AUTOMAT_WAIT_FORM_CLOSING_2, Proc_Eds_Automat_Wait_Form_Closing_2)
STATE (PROC_EDS_AUTOMAT_WAIT_HEAT_END,       Proc_Eds_Automat_Wait_Heat_End)
STATE (PROC_EDS_AUTOMAT_WAIT_FORMOVKA_END,   Proc_Eds_Automat_Wait_Formovka_End)
STATE (PROC_EDS_AUTOMAT_WAIT_FORM_OPENING,   Proc_Eds_Automat_Wait_Form_Opening)
STATE (PROC_EDS_AUTOMAT_WAIT_PNEVMOSYEM_END, Proc_Eds_Automat_Wait_Pnevmosyem_End)
STATE (PROC_EDS_AUTOMAT_WAIT_SENS_4,         Proc_Eds_Automat_Wait_Sens_4)
//========================================================================

//========================================================================
EVENT (NO_EVENTS,                      empty_func)

EVENT (KEYS_WORK_PRESSED,              Proc_Ev_Keys_Work_Pressed)

EVENT (EMERG_STOP,                     Proc_Ev_Emerg_Stop)

EVENT (INCORRECT_VAL_TIMER_HEAT,       Proc_Ev_Incorrect_Val_Timer_Heat)
EVENT (INCORRECT_VAL_TIMER_FORMOVKA,   Proc_Ev_Incorrect_Val_Timer_Formovka)
EVENT (INCORRECT_VAL_TIMER_PNEVMOSYEM, Proc_Ev_Incorrect_Val_Timer_Pnevmosyem)

EVENT (INCORRECT_VAL_SETT_QUANT,       Proc_Ev_Incorrect_Val_Sett_Quant)
EVENT (INCORRECT_VAL_CURR_QUANT,       Proc_Ev_Incorrect_Val_Curr_Quant)

EVENT (INCORRECT_VAL_TIMEOUT_SENS_1,   Proc_Ev_Incorrect_Val_Timeout_Sens_1)
EVENT (INCORRECT_VAL_TIMEOUT_SENS_2,   Proc_Ev_Incorrect_Val_Timeout_Sens_2)
EVENT (INCORRECT_VAL_TIMEOUT_SENS_3,   Proc_Ev_Incorrect_Val_Timeout_Sens_3)
EVENT (INCORRECT_VAL_TIMEOUT_SENS_4,   Proc_Ev_Incorrect_Val_Timeout_Sens_4)

EVENT (TIMEOUT_SENS_1,                 Proc_Ev_Timeout_Sens_1)
EVENT (TIMEOUT_SENS_2,                 Proc_Ev_Timeout_Sens_2)
EVENT (TIMEOUT_SENS_3,                 Proc_Ev_Timeout_Sens_3)
EVENT (TIMEOUT_SENS_4,                 Proc_Ev_Timeout_Sens_4)

EVENT (FAULT_SENS_1,                   Proc_Ev_Fault_Sens_1)
EVENT (FAULT_SENS_2,                   Proc_Ev_Fault_Sens_2)
EVENT (FAULT_SENS_3,                   Proc_Ev_Fault_Sens_3)
EVENT (FAULT_SENS_4,                   Proc_Ev_Fault_Sens_4)
//========================================================================

 

А теперь скажите, на куа мне это на экране?

Вот еще:

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

//=======================================================================================================================================================================================================================================================
//    NAME                         PARENT          CHILD                        NEXT                         PREV                         PLUS                    MINUS                   ENTER_FUNC           NUM_FUNC              MENU_FUNC
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (NULL_MENU,                   0,              0,                           0,                           0,                           0,                      0,                      0,                   0,                    0)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L_OUT_MODE,                  0,              L2_I1_TENY,                  L1_I1_CHANGE_T_HEAT,         L1_I5_CHANGE_CURR_QUANT,     0,                      0,                      0,                   0,                    out_mode_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L1_I1_CHANGE_T_HEAT,         L_OUT_MODE,     0,                           L1_I2_CHANGE_T_FORM,         L1_I5_CHANGE_CURR_QUANT,     inc_tim_heat_val,       dec_tim_heat_val,       0,                   0,                    change_t_heat_init)
MENU (L1_I2_CHANGE_T_FORM,         L_OUT_MODE,     0,                           L1_I3_CHANGE_T_PNEV,         L1_I1_CHANGE_T_HEAT,         inc_tim_formovka_val,   dec_tim_formovka_val,   0,                   0,                    change_t_form_init)
MENU (L1_I3_CHANGE_T_PNEV,         L_OUT_MODE,     0,                           L1_I4_CHANGE_SETT_QUANT,     L1_I2_CHANGE_T_FORM,         inc_tim_pnevmosyem_val, dec_tim_pnevmosyem_val, 0,                   0,                    change_t_pnevmosyem_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L1_I4_CHANGE_SETT_QUANT,     L_OUT_MODE,     L1_I4_ENTER_SETT_QUANT,      L1_I5_CHANGE_CURR_QUANT,     L1_I3_CHANGE_T_PNEV,         0,                      0,                      0,                   0,                    change_sett_quant_init)
MENU (L1_I4_ENTER_SETT_QUANT,      L_OUT_MODE,     0,                           0,                           0,                           0,                      0,                      save_sett_quant,     enter_sett_quant_val, enter_sett_quant_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L1_I5_CHANGE_CURR_QUANT,     L_OUT_MODE,     0,                           L1_I1_CHANGE_T_HEAT,         L1_I4_CHANGE_SETT_QUANT,     add_curr_quant_init,    sub_curr_quant_init,    0,                   0,                    change_curr_quant_init)
MENU (L1_I5_ENTER_ADD_CURR_QUANT,  L_OUT_MODE,     0,                           0,                           0,                           0,                      0,                      add_save_curr_quant, enter_curr_quant_val, 0)
MENU (L1_I5_ENTER_SUB_CURR_QUANT,  L_OUT_MODE,     0,                           0,                           0,                           0,                      0,                      sub_save_curr_quant, enter_curr_quant_val, 0)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//MENU (L1_I6_CHANGE_PART,           L_OUT_MODE,     L1_I6_ENTER_PART,            L1_I1_CHANGE_T_HEAT,         L1_I5_CHANGE_CURR_QUANT,     0,                      0,                      0,                   0,                    change_part_init)
//MENU (L1_I6_ENTER_PART,            L_OUT_MODE,     0,                           0,                           0,                           0,                      0,                      save_quant_products, enter_quant_products, enter_quant_products_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L2_I1_TENY,                  L_OUT_MODE,     L2_I1_SUB_I1_TEN_1,          L2_I2_TIMEOUTS,              L2_I2_TIMEOUTS,              0,                      0,                      0,                   0,                    l2_i1_teny_init)
MENU (L2_I2_TIMEOUTS,              L_OUT_MODE,     L2_I2_SUB_I1_T_OUT_I_SENS_1, L2_I1_TENY,                  L2_I1_TENY,                  0,                      0,                      0,                   0,                    l2_i2_timeouts_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L2_I1_SUB_I1_TEN_1,          L2_I1_TENY,     0,                           L2_I1_SUB_I2_TEN_2,          L2_I1_SUB_I4_TEN_4,          0,                      0,                      switch_ten_1,        0,                    l2_i1_sub_i1_ten_1_init)
MENU (L2_I1_SUB_I2_TEN_2,          L2_I1_TENY,     0,                           L2_I1_SUB_I3_TEN_3,          L2_I1_SUB_I1_TEN_1,          0,                      0,                      switch_ten_2,        0,                    l2_i1_sub_i2_ten_2_init)
MENU (L2_I1_SUB_I3_TEN_3,          L2_I1_TENY,     0,                           L2_I1_SUB_I4_TEN_4,          L2_I1_SUB_I2_TEN_2,          0,                      0,                      switch_ten_3,        0,                    l2_i1_sub_i3_ten_3_init)
MENU (L2_I1_SUB_I4_TEN_4,          L2_I1_TENY,     0,                           L2_I1_SUB_I1_TEN_1,          L2_I1_SUB_I3_TEN_3,          0,                      0,                      switch_ten_4,        0,                    l2_i1_sub_i4_ten_4_init)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MENU (L2_I2_SUB_I1_T_OUT_I_SENS_1, L2_I1_TENY,     0,                           L2_I2_SUB_I2_T_OUT_I_SENS_2, L2_I2_SUB_I4_T_OUT_I_SENS_4, inc_timeout_sens_1_val, dec_timeout_sens_1_val, 0,                   0,                    menu_timeout_i_sens_1_init)
MENU (L2_I2_SUB_I2_T_OUT_I_SENS_2, L2_I1_TENY,     0,                           L2_I2_SUB_I3_T_OUT_I_SENS_3, L2_I2_SUB_I1_T_OUT_I_SENS_1, inc_timeout_sens_2_val, dec_timeout_sens_2_val, 0,                   0,                    menu_timeout_i_sens_2_init)
MENU (L2_I2_SUB_I3_T_OUT_I_SENS_3, L2_I1_TENY,     0,                           L2_I2_SUB_I4_T_OUT_I_SENS_4, L2_I2_SUB_I2_T_OUT_I_SENS_2, inc_timeout_sens_3_val, dec_timeout_sens_3_val, 0,                   0,                    menu_timeout_i_sens_3_init)
MENU (L2_I2_SUB_I4_T_OUT_I_SENS_4, L2_I1_TENY,     0,                           L2_I2_SUB_I1_T_OUT_I_SENS_1, L2_I2_SUB_I3_T_OUT_I_SENS_3, inc_timeout_sens_4_val, dec_timeout_sens_4_val, 0,                   0,                    menu_timeout_i_sens_4_init)
//=====================================================================================================================================================================================================

 

До кучи:

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

//========================================================================
struct rc5_cod_type __flash tab_rc5_cod_type [] =
{
   {0,    RC5_TRIGGER}, // Цифры 0-9.
   {1,    RC5_TRIGGER},
   {2,    RC5_TRIGGER},
   {3,    RC5_TRIGGER},
   {4,    RC5_TRIGGER},
   {5,    RC5_TRIGGER},
   {6,    RC5_TRIGGER},
   {7,    RC5_TRIGGER},
   {8,    RC5_TRIGGER},
   {9,    RC5_TRIGGER},

   {10,   RC5_TRIGGER},
   {11,   RC5_TRIGGER},

   {12,   RC5_TRIGGER}, // STANDBY. POWER.
   {13,   RC5_TRIGGER}, // MUTE.

   {14,   RC5_TRIGGER},
   {15,   RC5_TRIGGER},

   {16,   RC5_REPEAT}, // Volume Up.
   {17,   RC5_REPEAT}, // Volume Down.

   {18,   RC5_TRIGGER},
   {19,   RC5_TRIGGER},
   {20,   RC5_TRIGGER},
   {21,   RC5_TRIGGER},
   {22,   RC5_TRIGGER},
   {23,   RC5_TRIGGER},
   {24,   RC5_TRIGGER},
   {25,   RC5_TRIGGER},
   {26,   RC5_TRIGGER},
   {27,   RC5_TRIGGER},
   {28,   RC5_TRIGGER},
   {29,   RC5_TRIGGER},
   {30,   RC5_TRIGGER},
   {31,   RC5_TRIGGER},
   {32,   RC5_TRIGGER},
   {33,   RC5_TRIGGER},
   {34,   RC5_TRIGGER},
   {35,   RC5_TRIGGER},
   {36,   RC5_TRIGGER},
   {37,   RC5_TRIGGER},
   {38,   RC5_TRIGGER},
   {39,   RC5_TRIGGER},
   {40,   RC5_TRIGGER},
   {41,   RC5_TRIGGER},
   {42,   RC5_TRIGGER},
   {43,   RC5_TRIGGER},
   {44,   RC5_TRIGGER},
   {45,   RC5_TRIGGER},
   {46,   RC5_TRIGGER},
   {47,   RC5_TRIGGER},
   {48,   RC5_TRIGGER},
   {49,   RC5_TRIGGER},
   {50,   RC5_TRIGGER},
   {51,   RC5_TRIGGER},
   {52,   RC5_TRIGGER},
   {53,   RC5_TRIGGER},
   {54,   RC5_TRIGGER},
   {55,   RC5_TRIGGER},
   {56,   RC5_TRIGGER},
   {57,   RC5_TRIGGER},
   {58,   RC5_TRIGGER},
   {59,   RC5_TRIGGER},
   {60,   RC5_TRIGGER},
   {61,   RC5_TRIGGER},
   {62,   RC5_TRIGGER},
   {63,   RC5_TRIGGER},

   {0xFF, 0xFF},
};
//------------------------------------------------------------------------

 

3 - Задача некоторых макросов изначально исключить ошибки. Код не раздувается. Свою задачу выполняет. Облегчить написание. Пример:

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

//------------------------------------------------------------------------
void _Print_Char (u08 x, u08 a);
#define Print_Char(y, x, a) _Print_Char(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//------------------------------------------------------------------------
void _Print_Buf (u08 x, char __flash *data);
#define Print_Buf(y, x, a) _Print_Buf(((y)-1)*POSITION_MAX_X+((x)-1), (a))
//------------------------------------------------------------------------

      case 4:
         if (handle_soft_timer (ST_INFO_SERVICE))
         {
            clr_dsp_buf ();

//------------------------------------------------------------------------
            Print_Buf (1, 1, "Status");
            show_addr (get_status (), 1, 2);
//------------------------------------------------------------------------
            Print_Buf (3, 1, "Mode");
            show_addr (get_mode_1 (), 1, 4);
            show_addr (get_mode_2 (), 3, 4);
//------------------------------------------------------------------------
            Print_Buf (1, 8, "Filter");
            show_addr (get_filter_1 (), 8, 2);
            show_addr (get_filter_2 (), 10, 2);
            show_addr (get_filter_3 (), 12, 2);
//------------------------------------------------------------------------
            Print_Buf (3, 8, "Offset");
            show_addr (get_offset_1 (), 8, 4);
            show_addr (get_offset_2 (), 10, 4);
            show_addr (get_offset_3 (), 12, 4);
//------------------------------------------------------------------------
            Print_Buf (1, 15, "Gain");
            show_addr (get_gain_1 (), 15, 2);
            show_addr (get_gain_2 (), 17, 2);
            show_addr (get_gain_3 (), 19, 2);
//------------------------------------------------------------------------
            Print_Buf (3, 15, "Data");
            show_addr (get_data_1 (), 15, 4);
            show_addr (get_data_2 (), 17, 4);
            show_addr (get_data_3 (), 19, 4);
//------------------------------------------------------------------------
         }
         break;

 

 

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

@demiurg1978 , что вы страдаете многословностью в коде,  понял давно, и вы могли не трудиться в публикации простыней ваших текстов. Проблема, с моей точки зрения, кроется в том, что раз вы пишите много, чтобы стало понятнее, значит, где-то вы пошли не тем путем - краткость должна быть понятной, а истина - немногословной. Похоже, вы перечитали книжек, которые были написаны просто ради гонорара и рассчитаны на наивных юношей, воспринимающих каждое книжное слово как руководство к действию. А ведь не зря говорят "краткость сестра таланта". Ну и бритва Оккама тоже вторит: не умножай сущности без необходимости :)))

Кстати, где-то читал такое правило хороших программистов: если ваша функция не умещается на экране целиком - это плохая функция, и алгоритм деления на функции надо поменять :) но это уже совсем не в тему...

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

Я заепся на каждый автомат разворот делать, в итоге сделал

Вот, обнаружил при внимательном чтении ваше высказывание, которое косвенно подтверждает мои догадки... Только выводы вы сделали опять не те: вместо изменения СТРАТЕГИИ добавили еще немного ТАКТИКИ. Т.е. не уменьшили проблему, а усугубили.

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

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

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

1 - Долго подготавливаемся, быстро едем. Писанины, может где-то и много, зато потом быстро едем.

2 - Книжки всего лишь дают общее представление. Направление. Не всегда авторы правы, не всегда и не везде их рекомендации работают.

3 - Стратегия, тактика.

4 - пишите много, чтобы стало понятнее - П.1 и чтобы, открыв проект на следующий день, неделю, через годы, ты понял, что ты понаписал в своем проекте. Краткость не всегда благо или то, что о ней думают. За краткостью могут прятаться пласты, и не мне вам это объяснять... Бритва Оккама тоже не везде работает.

5 - В некоторых вещах мы остаемся при своем мнении. Это нормально. Мы исходим из своих потребностей.

6 - Шаблон для автоматов. Задумка, считайте диспетчером автоматов. Забудьте, так как это задумки, я вам не смогу сейчас объяснить. Да, пример RTOS, диспетчеры. У них же проход задач процессов в одном месте. Почему это вас не смущает? Надеюсь сейчас ответил на ваш вопрос.

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

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

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

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

Мой опыт, мое понимание архитектуры AVR и мои подходы позволяют сделать устройства быстрее, чем при обычном подходе.

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

Резюме: писанины да, много, но зато потом не паришься. Это тактика. Стратегия - оптимизация труда.

И да, хотел бы, чтобы вы свои слова подкрепляли примерами. Для лучшего понимания, и для участников полезно. Я свои утверждения подкрепляю.

original.jpg

FISHKA.rar

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

Вы бы хоть сообщили, что а МК у вас там в поклёвке этой. Судя по вашему описанию, устройство крайне примитивное, зачем там высокочастотные прерывания - не понятно.

МК пробуждается контактом вашей кнопки. Запускается таймер, генерирующий аппаратно меандр на двух выходах в противофазе, эти выходы подаются на пьезопищалку (при питании даже от 3 вольт на пищалке будет 6, чего вполне достаточно для относительно громкого звука). Одновременно на прерываниях от этого таймера делается "модулятор", чтобы трилинькало. В главном цикле после запуска таймера ставится _delay_ms(4000); после чего МК снова уводится в сон. Максимум 50 строк программы, все на "стандартных либах". Уместится даже в attiny13. Время потребуется только на подбор резонансной частоты, чотбы раскочегарить пьезопищалку на пределе. Дроссель не потребуется наверняка. Лично для меня будет бедой только сделать "трилиньканье", т.к. музыкальным слухом не обладаю и понятия не имею, как надо модулировать сигнал, чтобы вышло "прилично".

Кстати, в вашем коде разобраться НЕ ВАМ попросту невозможно, в отличие от. Уже это говорит о его качестве.

Ах да, светодиодом мигать я забыл! Ну так это можно в прервании от таймерного "модулятора" сделать :) плюс еще 4 строки кода.

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

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

Вы не поняли, о чем я вам пишу все это время.

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

2 - Уже по вашим словам я вижу, вам проблематично повторить. Я не призываю повторить в реале. Просто вы написали, что как два пальца. А я вижу обратное.

3 - Последнему вашему утверждению я не верю. Но согласен, для ПУБЛИЧНОГО выкладывания не хватает описания алгоритма и комментариев.

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

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

И да, хотел бы, чтобы вы свои слова подкрепляли примерами.

Ладно, мои примеры, конечно, не так красивы, как ваши... Но их есть и у меня :)

1. Алгоритм приема и дешифрации кодов ДУ любых стандартов (почти любых, более 90% имеющихся на современном рынке): http://arv.radioliga.com/content/view/219/43/ 

Статья большая, но в ней есть несколько врезок кода - строк этак 50. Код рабочий 100%. Использован в нескольких проектах.

2. Пульт дистанционного управления RC-5: https://simple-devices.ru/attachments/article/85/RC_source.rar

Схема: 

remote_sch.jpg

Конструкция:

remote.jpg

Подробности: https://simple-devices.ru/prj/9-electr/85-rgb-light-with-remote-control

3. Последний проект: DIGISCRIPT: https://sites.google.com/view/digiscript/

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

Засим прения в ЭТОЙ теме предлагаю прекратить, чтобы не засирать её. Если есть желание - можем продолжить в отдельной теме.

 

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

Вы не поняли, о чем я вам пишу все это время

Вы бы лучше написали, на каком МК сделали свою поклёвку, и какой объем памяти занял ваш проект.

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

вам в каждом проекте нужно заново все продумывать. Каждый свой шаг.

При этом я потрачу времени не больше вашего, и результат будет прост и понятен даже начинающему. А заготовок для копипастинга у меня тоже много - это сути дела не меняет.

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

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

Так как прошивку я дописал и отладил на отладочной плате, дело подошло к схемотехнике. Если Вас не затруднит, проверьте пожалуйста схему, которую я начертил. В основном я все данные по подключению МС брал из даташитов, так что ошибки, думаю, могут быть только из-за невнимательности.

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

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

1299990346_.JPG.ff2aa13f1abc301a9e96f06fa986ad10.JPG

А так же перед делителем напряжения ещё находится подстроечный резистор R10 для более точной настройки делителя напряжения. В общем проверьте пожалуйста, и укажите на ошибки, или может быть будут какие-то дополнительные рекомендации. Заранее спасибо!

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

1745828591_.jpg.458d9c56e93af6f3cd7aa037825f7e58.jpg

 

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

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

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

Греются

Если ток нагрузки не превышать, ничего не греется.

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

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

Переменный резистор у вас для "подстройки" не сможет использоваться... Для подстройки его надо включать последовательно с R9 или R8. R9 (или R8) при этом должны быть меньшего сопротивления так, чтобы примерно в среднем положении подстроечника обеспечивалось расчетное значение сопротивления делителя. Например, R8=8,2К и последовательно R10=4,7К. Как-то так.

Ну и настоятельно рекомендую при измерении постоянных напряжений всегда ставить конденсатор на входе АЦП, можно даже электролит "приличной" ёмкости (порядка 10 мкФ).

Лично меня всегда смущает использование в качестве опорного напряжения АЦП напряжения питания... По идее, это самый худший источник опоры - он очень нестабильный, шумный... Такой вариант пригоден только для весьма "приблизительных" измерений.

Во всех автомобильных схемах рекомендую обязательно на входе питания ставить элементы защиты от переполюсовки. Для схем, потребляющих неболшой ток, вроде вашей, самое простое - диодный мост :) Только в этом случае надо гарантировать отсутствие соприкосновений схемной "земли" с "массой" авто. Варинтов такой защиты много.

В старых авто так же по цепям +12В гуляют импульсные перенапряжения, в очень старых - аж до нескольких сотен вольт. Так что и защита от перенапряжений тоже не помешала бы на входе питания.

Наконец, я бы для страховки зашунтировал бы вход и выход стабилизаторов обратными диодами...

И последнее: питание часовой микросхемы не лучше ли сделать при помощи low-drop стабилизатора, запитанного от цепи +5В? 

 

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

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

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

10 минут назад, optima сказал:

На кой там нужны 3,3 вольта?

У DS3231максимальное напряжение питания 5,5 В, думаю что лучше перестраховаться.

 

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

И последнее: питание часовой микросхемы не лучше ли сделать при помощи low-drop стабилизатора, запитанного от цепи +5В? 

Например какого?

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

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

Если чип может быть запитан от 5В, не вижу смысла в отдельном питании 3,3 вольта - это было разумное замечание @optima

На счет low-drop стабилизатора - их море. Я недавно применял XC6206P332

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

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

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

Переменный резистор у вас для "подстройки" не сможет использоваться... Для подстройки его надо включать последовательно с R9 или R8.

Подождите, а разве сейчас он не включен последовательно с R9 ? Осталось уменьшить номинал R9?

 

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

На счет low-drop стабилизатора - их море.

Low-drop это импульсный стабилизатор имеется в виду?

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

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

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

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

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

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

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

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

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

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

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

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

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