Опять мне присваивают чужое. Этот код взять отсюда. Значит так, друзья, вы уж сами определитесь что такое КА, а то вы, по ходу дела, каждый по своему видите реализацию этих КА.
KA = 0; while (1) { switch (KA) { case 0: инит_всего(); KA = 1; break; case 1: опрос_кнопок(); KA = 2; break; case 2: действие(); KA = 3; break; case 3: вывод_лсд(); KA = 1; break; default: в пиииии.....(); } }
И всё равно неправильно! Я же говорю, теорию изучи. У тебя тут ни Мили, ни Мур.
Eddy_Em, и tonyk, мне это, КА, без надобности. И так что-то и без КА могу сляпать, а читается код, не читается, мне до балды. Другой реализации я пока не видел, будем придерживаться этой.
Добавлено after 3 hours 24 minutes 46 seconds: Конечный автоматСпойлер
Код:
#define BTN_LOCK_TIME 50 // время обработки дребезга в папугаях #define BTN_LONG_TIME 150 // время фиксации длинного нажатия в папугаях
//настройка портов и линий #define BTN_PIN GPIOB->IDR // порт кнопок #define BTN_LINE1 GPIO_Pin_5 // линии кнопок #define BTN_LINE2 GPIO_Pin_0 #define BTN_LINE3 GPIO_Pin_1 #define BTN_LINE3 GPIO_Pin_2
//функция инициализации портов void BtnInit (void) { лень писать }
//функция циклического опроса кнопок (вызывать с частотой хГц, например в прерывании) void BtnExe (void) { static uint8_t BtnLockBit; //защелка (защита от дребезга) static uint16_t BtnLockCoun; //счетчик защелки (защита от дребезга) static uint16_t BtnLongCoun; //счетчик длинного нажатия static uint8_t BtnMascLast; //запомнить маску нажатой кнопки для анализа после отжатия кнопки
unsigned uint8_t BtnMask = 0; if (~BTN_PIN & BTN_LINE1) BtnMask = BTN_SHRT1;//формирование маски нажатых кнопок if (~BTN_PIN & BTN_LINE2) BtnMask = BTN_SHRT2; if (~BTN_PIN & BTN_LINE3) BtnMask = BTN_SHRT3; if (~BTN_PIN & BTN_LINE4) BtnMask = BTN_SHRT4;
//основной алгоритм обработки событий кнопки if (BtnMask){ //клавиша нажата BtnMascLast = BtnMask; //запоминаем для использования после отпускания кнопки
if (BtnLockCoun < (BTN_LOCK_TIME)){ BtnLockCoun++; //обработка дребезга return; }
BtnLockBit=1; //нажатие зафиксировано if (BtnLongCoun >= (BTN_LONG_TIME)) return;
if (button == BTN_SHRT1) {} if (button == BTN_SHRT2) {} if (button == BTN_SHRT3) {} if (button == BTN_SHRT4) {}
if (button == BTN_LONG1) {} if (button == BTN_LONG2) {} if (button == BTN_LONG3) {} if (button == BTN_LONG4) {}
Энкодер прикрутитьСпойлер
Код:
// Посмотреть относительное перемещение (по сравнению с прошлым вызовом) int16_t enc_GetRelativeMove(void) { // Для хранения предыдущего значения счетчика static uint16_t CNT_last = 0; // Текущее значение, чтоб только один раз было запрошено uint16_t CNT_now = TIM3->CNT; // Посчитаем перемещение int16_t CNT_diff = (int16_t)(CNT_now - CNT_last); // Сохраним текущее значение как предыдущее CNT_last = CNT_now; // Вернем перемещение return CNT_diff; }
Dimon456, ну кто ж пишет комментарии на русском? Это же вообще ниже плинтуса!
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
MENU_ITEM() - может оказаться макросом, результатом которого будет константа, которая хранится во Flash памяти как статический массив. Удобно. У себя я сделал через структуры:
Код:
typedef struct ScreenItem { SCREEN_OBJECT obj_type; // Element type char *menu_text; // Menu text link void (*exec_func)(uint8_t v); // Menu callback or null uint16_t Left, Top, Width, Height; // Coordinates of menu item int TextColor, BGColor; // Colors const uint8_t *Pictogramm; // Pointer to pictogramm, or NULLPTR } ScreenItem_t;
Опять же, это для графического меню с указателями и красивостями. После этого элементы объединяются в массивы указателей на кнопки, а на массивы указателей ссылаются экраны.
Ну это так, к слову.
ScanButtons(); - удобная абстракция, чтобы основной цикл не раздувался, был компактнее и проще в отладке. В моём коде эта функция проходится по пинам, проверяет их состояние, работает с таймерами и вызывает обработчики событий нажатия кнопки. Так же может вызывать событие удержания кнопки (но это в другом устройстве было сделано). И получаем следующее: main -> while(1) -> Scanuttons() -> OnButtonPress(n) -> SomeFunc[n](); В другом проекте всё происходит не столь тривиально, но это другая история.
Аlex, уважающий себя человек не будет в коде писать комментарии на языке, отличном от английского! Ведь это будет означать, что 99.9% населения Шарика комментарии не поймут.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Заголовок сообщения: Re: stm32 cubeide два инкремента не совместимы.
Добавлено: Пт янв 21, 2022 15:15:12
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Eddy_Em, смотря для чего эти комментарии пишутся. Если я пишу для себя, то я буду их писать на своём родном языке. И мне пофиг, поймёт там кто их, или нет.
Аlex, но тогда не выкладывай это на всеобщее обозрение! Некошерно же!!! И вообще, идеал - когда в исходниках нет символов выше 127 символов ASCII.
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Аlex, уважающий себя человек не будет в коде писать комментарии на языке, отличном от английского! Ведь это будет означать, что 99.9% населения Шарика комментарии не поймут.
Дядя Эдик в своём репертуаре: пятничное обострение максимализма и перфекционизма вкупе с заносами на поворотах. Не обращайте внимание, воспаление пройдёт вместе с пятницей. Пора уже привыкнуть и не реагировать, а то вы своими комментами только возбуждаете у него приступ.
Нафлудили-то аж на пять страниц, при это самое главное пропустили - Иван начал осваивать логику. Это уже прогресс, хотя и кривой как всё что он пишет. От детских болезней так и не избавился. Я пытался разговорить его, где он брал ресурсы для обучения - с целью заблокировать заразу, но Иван молчит как партизан. Вот сейчас опять уйдёт в анабиоз на пару месяцев, а потом выкатит очередной шедевр, от которого мозги плавятся.
Аlex, но тогда не выкладывай это на всеобщее обозрение! Некошерно же!!! И вообще, идеал - когда в исходниках нет символов выше 127 символов ASCII.
И тут у меня пошли флэшбеки китайских исходников с индусскими корнями. Для себя пишу от настроения - на русском и на английском. Перемежая их время от времени. По большей части никому мой код не нужен, а сам разберусь потом.
В чем то "Дядя Эдик" прав, рано или поздно IDE сломает этот коммент, да так сломает, что потом не возможно будет восстановить. Это факт.
AVI-crak писал(а):
а потом выкатит очередной шедевр, от которого мозги плавятся.
Вот так вот не надо говорить, чего стоит только вот этот шедеврСпойлер
Код:
// threshold in ms for press/hold #define PRESSTHRESHOLD (9) #define HOLDTHRESHOLD (199)
// events typedef enum{ EVT_NONE, // no events with given key EVT_PRESS, // pressed EVT_HOLD, // hold more than KEY_HOLDTIME ms EVT_RELEASE // released } keyevent;
uint16_t d = (uint16_t)(Tms - lastT); keybase *k = &allkeys[i]; keyevent e = k->event;
switch(e){ case EVT_NONE: // just pressed case EVT_RELEASE: if((k->counter += d) > PRESSTHRESHOLD) k->event = EVT_PRESS; break; case EVT_PRESS: // hold if((k->counter += d)> HOLDTHRESHOLD) k->event = EVT_HOLD; break; default: break; }
вот от него точно будут не только мозги плавиться, но и еще кое что за плавится. Или может вы считаете что у других интеллект равносильный вашему? А с чего вы начинали? Ответьте мне на вопрос. Случайно не с такого же шедевра, как у ТС? Или может сразу начали с методов эффективного программирования?
Ни кто не ответил на его вопрос
ivan dimir писал(а):
А через указатель как сделать меню?
Там везде указатели используются, куда не плюнь. ivan dimir существует много разновидностей этих микро-меню, инет кишит ими, даже на asm есть, правда для avr. По степени управления различаются от одной кнопки. две кнопки, три кнопки, до целых клавиатур. Но либо так не подходит, либо эдак, либо слишком заумно сделано, хотя подробная инструкция имеется.
В моем меню Спойлер
Код:
typedef const struct Menu_Item { const struct Menu_Item *Next; /**< указатель на следующий пункт меню этого пункта меню */ const struct Menu_Item *Previous; /**< указатель на предыдущий пункт меню этого пункта меню */ const struct Menu_Item *Parent; /**< указатель на родительский пункт меню этого пункта меню */ const struct Menu_Item *Child; /**< указатель на дочерний пункт меню этого пункта меню */ void (*SelectCallback)(void); /**< указатель на функцию */ } Menu_Item_t;
А с чего вы начинали? Ответьте мне на вопрос. Случайно не с такого же шедевра, как у ТС? Или может сразу начали с методов эффективного программирования?
Да так-же как все, с моргалки светодиодом. Разница в том что мне были интересны внутренности мк, отчего пришлось изучать документацию и множество примеров. К тому-же выбранная IDE сразу демонстрировала код в асме при пошаговом режиме - это дало стимул писать не так как в примерах, а после - вообще не так. Мериться мозгами желания не имею, тут без меня желающих навалом - у каждого второго и длинше и ширше, и вообще иного цвета.
Иван, научись не использовать условия, ну или максимально сокращать их до простейшей математики. Ну и с форматированием текста немного поработать нужно. Почти все IDE имеют кнопку "сделать красиво" - форматируют код. Пришлось твой код в кучу собирать, а то так и косоглазие получить можно. Спойлер
/// чем-то выполнять каждую 1мс uint32_t tmp; tmp = (GPIOB->IDR >> 5) & 1; // масса кнопки Vcc tmp = 1 - tmp; // масса кнопки Gnd pauza = pauza * tmp + tmp; // 255 раз подряд единица tmp = pauza >> 5; // > 255 tmp = 1 - tmp; pauza *= tmp; // условие обнуляет pauza if (tmp == 0) { menu_lcd++; menu_btn++; };
Умножения, сдвиги, сложения и вычитания - все эти команды выполняются за один такт. Один условный оператор тормозит выполнение программы на 1-12 тактов. Вообще-то антидребезг выполняется гораздо проще, но если уж хочется...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 37
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения