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

demiurg1978

Members
  • Постов

    361
  • Зарегистрирован

  • Посещение

Весь контент demiurg1978

  1. Раз исчезла кнопка изменить сообщение, придется в лоб. Что-то не могу найти функцию прятать в спойлер. /======================================================================== 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 - Никаких мук. Написал (отмучался один раз), потом просто используешь. Я ленивый человек (в хорошем плане). Делаю, когда целесообразно. Считаю, что целесообразно использовать самописную библиотеку, если тебе всего лишь нужно переводить переменные в системы счисления. Впрочем, здесь мы разошлись во мнениях. Это нормально.
  2. Лехко. //======================================================================== 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 } //========================================================================
  3. ARV вы забыли что я начинал на ассемблере. Родные библиотеки раздувают код. В ряде случаев работают медленнее. А мой подход в большинстве случаев итерация основного цикла с запасом 1 мс. Это означает, что все задачи, которые работают в данный момент должны провернуться менее чем за 1 мс. Поэтому я свой код всегда проверяю в дизассемблере. Пока не добьюсь оптимальных результатов. И именно по этой причине использую IAR. Ограничения у AVR объем памяти и скорость. Вы по своему решаете свои задачи. Я по своему. У вас свой опыт свое направление в электронике. У меня свое. Это не хорошо не плохо. Известная картинка Не всегда памяти достаточно, чтобы формировать массивы для каждого чиха. Формировать массивы с той частотой, какая требуется. Частота обновления дисплея к этому никакого отношения не имеет.
  4. 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; }
  5. Да, Совершенный код. Вам тоже сенкс. Скачаю эти книги. В СССР все это перерабатывалось с учетом менталитета и условий. И все работало на ура. На крупных предприятиях внедрялись системы схожие с 5S. Я когда первый раз услышал про 5S, увидел в этом что-то знакомое. А потом-ептыть! В СССР все это было! Вот если бы найти подобные книги советских времен, методички... Когда я упомянул 5S я хотел довести более важное: оптимизацию собственного труда. Сделать его более эффективным. А это подразумевает системное мышление. Которое тоже нужно зарождать в себе и развивать.
  6. Я упомянул книгу, и решил ее себе на смартфон скопировать. Открыл, и сразу же наткнулся на очень важную вещь. Я забыл, просто откуда все идет. Так вот, в книге поднимается очень важный вопрос. Эффективность и оптимизация производства. Да-да, именно так. это как говорится, не письки на заборе рисовать... Так вот в книге в свою очередь упоминаются книги Система 5S. И я бы порекомендовал в первую очередь почитать книги по системе 5S. У меня родители всю жизнь на заводах работали. И так получилось, что в свое время интересовался промышленностью, технологиями. Что самое смешное, в СССР все это было бесплатно. Как сделать производство эффективным. А сейчас за какую-то сраную книжку почти ни о чем, или за тренинг выложи копейку... Порой немалую. Поэтому, мой настоятельный совет. Почитать сначала книги по системе 5S и около этих тем. Так вы поймете суть книги. Мало того, это поднимет ваше понимание на немаленький уровень. Притом не только в программировании. Вообще в жизни пригодится. И повторю, поднимет понимание на достойный уровень. А это уже управленческий уровень.
  7. Я не помнил названия книг. К примеру, Роберт Мартин. Чистый код. Создание, анализ и рефакторинг. Скажу так, ищите в магазинах, в интернете. К примеру, ключевые слова "эффективное программирование". И не обязательно книги, ищите статьи в интернете Цикл статей Татарчевского.
  8. Есть метод switch-case. Почитайте в интернете на тему структурированный код. Скачивайте чужие примеры. И на них учитесь. Ищите литературу по методам подходам по программированию. Не по языкам а именно приемам программирования.
  9. Иногда приходится писать как есть, пока не заработает. А когда заработает, уже разбираться что с этим делать.
  10. Я вам уже писал. Универсальность не всегда полезна. Опять же в чем универсальность. Вы должны сами провобовать, искать варианты, пробовать их. И тогда вам самим будет понятнее на своих проектах, где нужна универсальность, а где нет. switch (mode_out) { case MODE_OUT_TIME: // здесь функция вывода времени. Признак точки и ее знакоместо. break; case MODE_OUT_TEMPERATURE: // здесь функция вывода значения температуры. Признак точки и ее знакоместо. break; case MODE_OUT_VOLTMETER: // здесь функция вывода значения напряжения. Признак точки и ее знакоместо. break; case MODE_OUT_TEXT: // здесь функция вывода текста как есть. break; }
  11. Ваши претензии некорректны. Вы с самого начала пошли не по тому пути. И это вам урок на будущее. Не зацикливаться на изначально несбыточной нерабочей идее. А так как вы бизнесом занимаетесь, такие ошибки смертельно опасны. Как в переносном для бизнеса, так и для вас. Бизнес жесток. Не прощает ошибок.
  12. Правильно. Если только думать, то под лежачий камень вода не потечёт...
  13. Я вам сразу написал. Имитация. ДПТ или шаговый. Дарю идею. Купите приводы для моделей. Забыл как называется, управляет рулями и так далее. Разбираете, выбрасываете переменный резистор и ограничитель, чтобы делал полный оборот. Там редуктор. Вот вам и медленное вращение. Если на карту отблагодарите, буду не против.
  14. Я обещал сделать тестовый проект. Но, так как времени сейчас нет, и у меня ремонт в квартире, достать железо для проверки не получится, выкладываю начатый когда-то проект. Донором послужил прибор "Термодат". Картинка Видео SVP_INDIKATOR.rar
  15. Ромуальд 7. Это звучит. Гонору до ЕМ. Знаний xyz (на заборе написано). Книги для чайников. Электроника с нуля. В зубы. И не подходить к форумам. Пока не проштудировал книгу. Не спаял несколько схем по книге. Вручную. Без симуляторов.
  16. Выводить показания раз в 100 мс, 500 мс - подбирайте. Могу подсказать среднеарифметическое. Собираете показания в течении заданного времени. Скажем 100 раз. Суммируете, делите на 100. Результат выводите.
  17. Универсальность не всегда и не везде полезна. По поводу костыля. Если он решил вашу задачу, это уже не костыль. Уберите застенчивость по этому поводу. Если вас это смущает, можете порыться в интернете в примерах. Спросить. Не нашли универсального, более красивого решения. Значит ваше решение на данный момент единственное и верное. Гашение незначащего нуля не везде можно использовать. Значить ставьте на режим какой нибудь признак, надо не надо. Или свитч.
  18. Тогда вам нужно почитать как устроены двигатели переменного тока.
  19. Я так скажу. Сделал квест комнату, пусть понимает, что некоторые вещи придется делать. Теперь по вопросу. Если нужны именно вентиляторы, то должен понимать, что будут некоторые минимальные обороты. Если ему нужны сверхмалые обороты, значит ему нужны не вентиляторы а имитация. Задачу решат только ДПТ либо шаговые двигатели.
  20. Сделать имитацию вентиляторов. На двигателях постоянного тока или шаговиках.
  21. Для начала ознакомьтесь в поисковиках, что такое дребезг контактов. Затем, опрос кнопки, переключение светодиодов сделать отдельными функциями. В функции обработки кнопки выдавать события нажатия кнопки. В функции переключения светодиодов по событию нажатия кнопки переключать светодиоды. Ваша программа легко делается на конечных автоматах. Цикл статей Татарчевского
  22. 1 - Почитайте этот цикл. Цикл статей Татарчевского 2 - http://easyelectronics.ru/organizaciya-drevovidnogo-menyu.html Меню я сделал так: названия взял с easyelectronics, но за основу взял оригинал 1 версия. Есть 2 версия. Деталей уже не помню, потому как несколько лет назад наткнулся. Сейчас пользуюсь собственной переработкой этих проектов. Могу выложить проект-пример, но на это нужно время.
  23. В WINAVR не работал. Там где-то должно указываться, какой МК. Либо в программе, либо в библиотеках. Кто знает, скажет точно. Сначала проверить это. После проверки двигаться дальше.
×
×
  • Создать...