stm32 cubeide два инкремента не совместимы.
- AlanDrakes
- Прорезались зубы
- Сообщения: 236
- Зарегистрирован: Пн июл 04, 2016 16:51:22
- Откуда: Россия, Омск
Re: stm32 cubeide два инкремента не совместимы.
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"][А чем писать код?[/uquote]
Не знаю, как кто, но я пишу руками. =]
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]И чем вас смущает эта строка.Нажимаю кнопку выставляется флаг.Когда выставляется флаг в обработчике прерываний по таймеру начинает счёт переменная.[/uquote]
Скорее всего компилятор должен жаловаться на логичнское И, между частью операндов в строке. И что он МОЖЕТ ошибиться, если нет скобок.
Жалоба на неоднозначную трактовку сравнений.
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]Покажите хоть пример.Кусочек кода моего .Так как нужно писать .[/uquote]
Хойку.
Извините, не сдержался.
Не знаю, как кто, но я пишу руками. =]
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]И чем вас смущает эта строка.Нажимаю кнопку выставляется флаг.Когда выставляется флаг в обработчике прерываний по таймеру начинает счёт переменная.[/uquote]
Скорее всего компилятор должен жаловаться на логичнское И, между частью операндов в строке. И что он МОЖЕТ ошибиться, если нет скобок.
Жалоба на неоднозначную трактовку сравнений.
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]Покажите хоть пример.Кусочек кода моего .Так как нужно писать .[/uquote]
Хойку.
Извините, не сдержался.
- Реклама
Re: stm32 cubeide два инкремента не совместимы.
ivan dimir, просто они тебе ни чего другого не могут предложить.
+2 страницы библиотека обработки кнопок
+6 страниц микроменю, это примерный подсчет
и в итоге >16 страниц "индусокода", в котором только автор может разобраться.
Конечно на конечных автоматах это все просто делается, а тут увы, всего 1 страница и абсолютно не читаемый код.
+2 страницы библиотека обработки кнопок
+6 страниц микроменю, это примерный подсчет
и в итоге >16 страниц "индусокода", в котором только автор может разобраться.
Конечно на конечных автоматах это все просто делается, а тут увы, всего 1 страница и абсолютно не читаемый код.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32 cubeide два инкремента не совместимы.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4164051#p4164051"]ivan dimir, просто они тебе ни чего другого не могут предложить.
+2 страницы библиотека обработки кнопок
+6 страниц микроменю, это примерный подсчет
и в итоге >16 страниц "индусокода", в котором только автор может разобраться.
Конечно на конечных автоматах это все просто делается, а тут увы, всего 1 страница и абсолютно не читаемый код.[/uquote]
Что такое конечный автомат? И как его создать.Обьясните нерусскому электрику.Принцып.Или алгоритм создания этого конечного автомата.Какой ?
+2 страницы библиотека обработки кнопок
+6 страниц микроменю, это примерный подсчет
и в итоге >16 страниц "индусокода", в котором только автор может разобраться.
Конечно на конечных автоматах это все просто делается, а тут увы, всего 1 страница и абсолютно не читаемый код.[/uquote]
Что такое конечный автомат? И как его создать.Обьясните нерусскому электрику.Принцып.Или алгоритм создания этого конечного автомата.Какой ?
Re: stm32 cubeide два инкремента не совместимы.
Это не ко мне вопрос.
Я не постиг этот >16 страничный высоко интеллектуальный код.
Я не постиг этот >16 страничный высоко интеллектуальный код.
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: stm32 cubeide два инкремента не совместимы.
ivan dimir, а слабо в гугле набить "finite state machine"?
Все очень просто: алгоритм разбивается на этапы, которые можно однозначно охарактеризовать конечным количеством состояний. Все, дальше ты в switch'е проверяешь текущее состояние и выполняешь в зависимости от него какие-то действия.
Например, работа с USB основана на конечном автомате, твои кнопки удобней будет конечным автоматом реализовать и т.д., и т.п.
Я ж тебе давал ссылку на обработку кнопок в конечном автомате:
(правда, этот пример неудачный. Нельзя так делать. Надо сначала выставить состояние и лишь потом ждать нужное время; а здесь выходит, что событие нажатия система получит лишь через PRESSTHRESHOLD мс, а это около 30 и выше!)
Бывают автоматы иерархические: когда в каждом состоянии есть какие-то подсостояния.
Все очень просто: алгоритм разбивается на этапы, которые можно однозначно охарактеризовать конечным количеством состояний. Все, дальше ты в switch'е проверяешь текущее состояние и выполняешь в зависимости от него какие-то действия.
Например, работа с USB основана на конечном автомате, твои кнопки удобней будет конечным автоматом реализовать и т.д., и т.п.
Я ж тебе давал ссылку на обработку кнопок в конечном автомате:
Код: Выделить всё
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;
}Бывают автоматы иерархические: когда в каждом состоянии есть какие-то подсостояния.
- Реклама
Re: stm32 cubeide два инкремента не совместимы.
Ни знаю в чем проблема, и не ужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
Спойлер
Код: Выделить всё
#include <stdbool.h>
bool flag_IDR5;
bool flag_IDR4;
bool flag_IDR8;
#define BTN_TIME 50
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
flag_IDR5=0; flag_IDR4=0; flag_IDR8=0;
if (GPIOB->IDR & GPIO_IDR_IDR5) {
// Отпущена, висит в воздухе, подтяжка к VCC
if (ButtonFilter[0]) { ButtonFilter[0] = 0; }
} else {
// Нажата (притянуто к 0)
if (ButtonFilter[0] == BTN_TIME) {
ButtonFilter[0] = (BTN_TIME+1);
flag_IDR5 = 1;
} else if (ButtonFilter[0] < BTN_TIME) {
ButtonFilter[0]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR4) {
if (ButtonFilter[1]) { ButtonFilter[1] = 0; }
} else {
if (ButtonFilter[1] == BTN_TIME) {
ButtonFilter[1] = (BTN_TIME+1);
flag_IDR4 = 1;
} else if (ButtonFilter[1] < BTN_TIME) {
ButtonFilter[1]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR8) {
if (ButtonFilter[2]) { ButtonFilter[2] = 0; }
} else {
if (ButtonFilter[2] == BTN_TIME) {
ButtonFilter[2] = (BTN_TIME+1);
flag_IDR8 = 1;
} else if (ButtonFilter[2] < BTN_TIME) {
ButtonFilter[2]++;
}
}
}
Код: Выделить всё
ScanButtons();
switch (nastroyki.menu_btn) {
case 0:
break;
case 1:
if (flag_IDR4) {
if (danie.a < 4095) danie.a++;
}
if (flag_IDR8) {
if (danie.a) danie.a--;
}
break;
Код: Выделить всё
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32 cubeide два инкремента не совместимы.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4164174#p4164174"]
а в цикле что-то вроде
первые можно в макрос обернуть типа такого [/uquote]
Код увеличится.И нет простоты кода.Для меня это сильно заумно.Слишком много событий.И операции.
Ни знаю в чем проблема, и не ужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
Спойлер
Код: Выделить всё
#include <stdbool.h>
bool flag_IDR5;
bool flag_IDR4;
bool flag_IDR8;
#define BTN_TIME 50
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
flag_IDR5=0; flag_IDR4=0; flag_IDR8=0;
if (GPIOB->IDR & GPIO_IDR_IDR5) {
// Отпущена, висит в воздухе, подтяжка к VCC
if (ButtonFilter[0]) { ButtonFilter[0] = 0; }
} else {
// Нажата (притянуто к 0)
if (ButtonFilter[0] == BTN_TIME) {
ButtonFilter[0] = (BTN_TIME+1);
flag_IDR5 = 1;
} else if (ButtonFilter[0] < BTN_TIME) {
ButtonFilter[0]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR4) {
if (ButtonFilter[1]) { ButtonFilter[1] = 0; }
} else {
if (ButtonFilter[1] == BTN_TIME) {
ButtonFilter[1] = (BTN_TIME+1);
flag_IDR4 = 1;
} else if (ButtonFilter[1] < BTN_TIME) {
ButtonFilter[1]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR8) {
if (ButtonFilter[2]) { ButtonFilter[2] = 0; }
} else {
if (ButtonFilter[2] == BTN_TIME) {
ButtonFilter[2] = (BTN_TIME+1);
flag_IDR8 = 1;
} else if (ButtonFilter[2] < BTN_TIME) {
ButtonFilter[2]++;
}
}
}
Код: Выделить всё
ScanButtons();
switch (nastroyki.menu_btn) {
case 0:
break;
case 1:
if (flag_IDR4) {
if (danie.a < 4095) danie.a++;
}
if (flag_IDR8) {
if (danie.a) danie.a--;
}
break;
Код: Выделить всё
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}Код увеличится.И нет простоты кода.Для меня это сильно заумно.Слишком много событий.И операции.
Re: stm32 cubeide два инкремента не совместимы.
В конечных автоматах точно будет сильно заумно, слишком много событий и операции.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?если их объединить, то код примет видScanButtons() можно объявить как inline функцию.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?
Код: Выделить всё
nastroyki.menu_btn
nastroyki.menu_lcdСпойлер
Код: Выделить всё
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: stm32 cubeide два инкремента не совместимы.
Ну так сравни объем одного и того же кода без КА и с ними!
Я уж молчу о простоте сопровождения кода. С КА воткнуть новое состояние намного проще, чем без оного!
Я уж молчу о простоте сопровождения кода. С КА воткнуть новое состояние намного проще, чем без оного!
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32 cubeide два инкремента не совместимы.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4164331#p4164331"]В конечных автоматах точно будет сильно заумно, слишком много событий и операции.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?если их объединить, то код примет видScanButtons() можно объявить как inline функцию.[/uquote]
Может можно.Но по памяти в avr .Не совсем работает.С глюком.Но вижу что эклипсе др среда.Ей пофиг атомарные операции.Нужно попробывать ваш вариант.Спасибо.Я кстати подумал об этом.И у меня один маленький вопрос.В каких случаях нужно применять указатели ?
Добавлено after 9 minutes 12 seconds:
Хотя по мне две переменные. Бараны на лево.Козлы на право.Вот принцып.Код увеличился.Ну и структуры тоже код увеличили.Когда слишком много переменных .То структуры в помощь.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?
Код: Выделить всё
nastroyki.menu_btn
nastroyki.menu_lcdСпойлер
Код: Выделить всё
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}Может можно.Но по памяти в avr .Не совсем работает.С глюком.Но вижу что эклипсе др среда.Ей пофиг атомарные операции.Нужно попробывать ваш вариант.Спасибо.Я кстати подумал об этом.И у меня один маленький вопрос.В каких случаях нужно применять указатели ?
Добавлено after 9 minutes 12 seconds:
Хотя по мне две переменные. Бараны на лево.Козлы на право.Вот принцып.Код увеличился.Ну и структуры тоже код увеличили.Когда слишком много переменных .То структуры в помощь.
Re: stm32 cubeide два инкремента не совместимы.
Конечные автоматы очень удобны, быстры при разборе сложных условий, а ещё их очень просто и удобно рисовать. Заметьте, сначала рисуем автомат, а потом его кодируем. Учитесь рисовать и работать с КА, ибо это очень эффективный способ создания ПО! Заумь начинается, когда у вас при анализе получается 100500 if-then-else, а в самой глубине goto.
- AlanDrakes
- Прорезались зубы
- Сообщения: 236
- Зарегистрирован: Пн июл 04, 2016 16:51:22
- Откуда: Россия, Омск
Re: stm32 cubeide два инкремента не совместимы.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4164174#p4164174"]
первые можно в макрос обернуть типа такого[/uquote]
Макрос интересный, согласен. Хотя писать такие не люблю - компилятор любит их разворачивать в inline-функции, а мне привычнее немного иначе оформить код - обработка ввода, фильтры, вызов события.
Когда-то писал функции обработки меню для графического экрана, с курсором (не указателем мыши, а виртуальным, прыгающим по кнопкам) и в какой-то момент понял, что дошёл до копии классического же меню. А потом понадобилось сделать "активную" кнопку, которая ловит хуки событий. Вот там всё стало странным, но решилось небольшой модификацией примитивов обработчиков. Ладно, это другая тема уже.
Не знаю в чем проблема, и неужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
Спойлер
<...>первые можно в макрос обернуть типа такого
Код: Выделить всё
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}Макрос интересный, согласен. Хотя писать такие не люблю - компилятор любит их разворачивать в inline-функции, а мне привычнее немного иначе оформить код - обработка ввода, фильтры, вызов события.
Когда-то писал функции обработки меню для графического экрана, с курсором (не указателем мыши, а виртуальным, прыгающим по кнопкам) и в какой-то момент понял, что дошёл до копии классического же меню. А потом понадобилось сделать "активную" кнопку, которая ловит хуки событий. Вот там всё стало странным, но решилось небольшой модификацией примитивов обработчиков. Ладно, это другая тема уже.
Re: stm32 cubeide два инкремента не совместимы.
я тебе даю свой рабочий проект, а ты из него делаешь КА, вот тогда и поговорим о размере кода.Eddy_Em писал(а):Ну так сравни объем одного и того же кода без КА и с ними!
Eddy_Em писал(а):С КА воткнуть новое состояние намного проще, чем без оного!
Код: Выделить всё
while (1) {
ScanButtons();
новое_состояние();под каждую задачу вы будете рисовать свой автомат, а потом его кодировать.tonyk писал(а):Заметьте, сначала рисуем автомат, а потом его кодируем.
Универсального ни чего нет, как с теми же микроменю.
tonyk писал(а):Учитесь рисовать и работать с КА, ибо это очень эффективный способ создания ПО!
Код: Выделить всё
КА++
switch (KA){
case 0 : опрос_кнопок(); break;
case 1 : действие(); break;
case 2 : вывод_лсд(); break;
default : КА=-1
}Код: Выделить всё
while(1){
опрос_кнопок();
действие();
вывод_лсд();
}пример в студию, с КА и без КА.tonyk писал(а):когда у вас при анализе получается 100500 if-then-else, а в самой глубине goto.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32 cubeide два инкремента не совместимы.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4164331#p4164331"]В конечных автоматах точно будет сильно заумно, слишком много событий и операции.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?если их объединить, то код примет видScanButtons() можно объявить как inline функцию.[/uquote]
Меня заинтересовал ваш код у вас флаги в качестве кнопок?И меня заинтерисовала функция ScanButtons()? Что это ? И с чем его едят.Код ваш похож на мой единственное что переход на ноль при ++ и переход с нуля на 1023 при --.И замедление показаний.Ну а так ваш код лучше.Правда я использовал число 4095 дискретность ацп.1023 у avr.Да и ещё при переключении меню сначала нажимаем кнопку я выставляю флаг потом при ожатии флаг сбрасываю и срабатывает меню.
Добавлено after 2 minutes 23 seconds:
[uquote="AlanDrakes",url="/forum/viewtopic.php?p=4164036#p4164036"][uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"][А чем писать код?[/uquote]
Не знаю, как кто, но я пишу руками. =]
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]И чем вас смущает эта строка.Нажимаю кнопку выставляется флаг.Когда выставляется флаг в обработчике прерываний по таймеру начинает счёт переменная.[/uquote]
Скорее всего компилятор должен жаловаться на логичнское И, между частью операндов в строке. И что он МОЖЕТ ошибиться, если нет скобок.
Жалоба на неоднозначную трактовку сравнений.
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]Покажите хоть пример.Кусочек кода моего .Так как нужно писать .[/uquote]
Хойку.
Извините, не сдержался.[/uquote]
Да код написан не правильно.Но работает.Исправлю.Спасибо за замечания.
Самое главное, событий, а операций там столько же будет.
Один вопрос: за чем две совершенно одинаковых переменные?
Код: Выделить всё
nastroyki.menu_btn
nastroyki.menu_lcdСпойлер
Код: Выделить всё
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}Меня заинтересовал ваш код у вас флаги в качестве кнопок?И меня заинтерисовала функция ScanButtons()? Что это ? И с чем его едят.Код ваш похож на мой единственное что переход на ноль при ++ и переход с нуля на 1023 при --.И замедление показаний.Ну а так ваш код лучше.Правда я использовал число 4095 дискретность ацп.1023 у avr.Да и ещё при переключении меню сначала нажимаем кнопку я выставляю флаг потом при ожатии флаг сбрасываю и срабатывает меню.
Добавлено after 2 minutes 23 seconds:
[uquote="AlanDrakes",url="/forum/viewtopic.php?p=4164036#p4164036"][uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"][А чем писать код?[/uquote]
Не знаю, как кто, но я пишу руками. =]
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]И чем вас смущает эта строка.Нажимаю кнопку выставляется флаг.Когда выставляется флаг в обработчике прерываний по таймеру начинает счёт переменная.[/uquote]
Скорее всего компилятор должен жаловаться на логичнское И, между частью операндов в строке. И что он МОЖЕТ ошибиться, если нет скобок.
Жалоба на неоднозначную трактовку сравнений.
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4163989#p4163989"]Покажите хоть пример.Кусочек кода моего .Так как нужно писать .[/uquote]
Хойку.
Извините, не сдержался.[/uquote]
Да код написан не правильно.Но работает.Исправлю.Спасибо за замечания.
Re: stm32 cubeide два инкремента не совместимы.
ivan dimir, код не мой, код опубликовал AlanDrakes в этой теме 2 сообщение, я просто взял и использовал.число 50 взято с потолка, в зависимости от тактовой частоты чипа это число будет меняться, это число больше определяет сколько надо времени держать нажатой кнопку до ее срабатывания, до установки флага.
Попробуйте поиграться от 5-250.
ivan dimir писал(а):И меня заинтерисовала функция ScanButtons()?
что и требовалось.AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
здесь мне не понятно было, а переспрашивать не стал, в качестве демонстрации.ivan dimir писал(а):что переход на ноль при ++ и переход с нуля на 1023 при --
опять не понятно, что значит замедление?ivan dimir писал(а):И замедление показаний.
Код: Выделить всё
#define BTN_TIME 50Попробуйте поиграться от 5-250.
Re: stm32 cubeide два инкремента не совместимы.
Dimon456 написал:
Вот сразу видно человека, который не понимает, что такое конечный автомат. Даже книжки не читал.
Код: Выделить всё
КА++
switch (KA){
case 0 : опрос_кнопок(); break;
case 1 : действие(); break;
case 2 : вывод_лсд(); break;
default : КА=-1
}Re: stm32 cubeide два инкремента не совместимы.
tonyk, я поторопился, надо было так
Код: Выделить всё
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
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: stm32 cubeide два инкремента не совместимы.
Dimon456, все равно неправильно. У тебя - не конечный автомат, а тупой последовательный код, написанный через жопу!
Re: stm32 cubeide два инкремента не совместимы.
Eddy_Em, мне что, твои куски коды сюда начать выкладывать?
В любой момент времени мы можем прерваться и прочитать состояние KA и узнать в каком состоянии находится последовательный код.
В своем проекте я хотел использовать совт_таймер, как бы не из ваших КАно из-за того что мне стало жалко лишние 300-400 байт флеша, обошелся такой конструкциейТак что, будешь дербанить мой код?
В любой момент времени мы можем прерваться и прочитать состояние KA и узнать в каком состоянии находится последовательный код.
В своем проекте я хотел использовать совт_таймер, как бы не из ваших КА
Спойлер
Код: Выделить всё
//==================
#ifndef SOFT_TIMERS_H
#define SOFT_TIMERS_H
#include "soft_timers.h"
#include "main.h"
#define SwTimerCount 8 //Количество программных таймеров
/*Режимы работы таймеров*/
typedef enum
{
SWTIMER_MODE_EMPTY,
SWTIMER_MODE_WAIT_ON,
SWTIMER_MODE_WAIT_OFF,
SWTIMER_MODE_CYCLE,
SWTIMER_MODE_SINGLE
} SwTimerMode;
/*Стурктура программного таймера*/
typedef struct
{
unsigned LocalCount:32; //Переменная для отсчета таймера
unsigned Count:24; //Переменная для хранения задержки
unsigned Mode:3; //Режим работы
unsigned On:1; //Разрешиющий бит
unsigned Reset:1; //Сброс счета таймера без его выключения
unsigned Off:1; //Останавливающий бит
unsigned Out:1; //Выход таймера
unsigned Status:1; //Состояние таймера
}SW_TIMER;
#if (SwTimerCount>0)
volatile SW_TIMER TIM[SwTimerCount]; //Объявление софтовых таймеров
#endif
void SwTimerWork(volatile SW_TIMER* TIM, unsigned char Count); //Сама функция для обработки таймеров
void OnSwTimer(volatile SW_TIMER* TIM, SwTimerMode Mode, unsigned int SwCount); //Подготовливает выбранный из массива таймер
unsigned char GetStatusSwTimer(volatile SW_TIMER* TIM); //Считывание статуса таймера
#endif
Спойлер
Код: Выделить всё
//==================
//--------------------- Пример использования -----------------------------
// set_soft_timer (ST_LED_2_BLINK, 50, 50); // Установка таймера.
// if (handle_soft_timer (ST_LED_2_BLINK)) // Проверка таймера.
//==================
//==================
#include "soft_timers.h"
//==================
//Подпрограмма программных таймеров
void SwTimerWork(volatile SW_TIMER* TIM, unsigned char Count){
unsigned short i=0;
for (i=0; i<Count; i++){
if (TIM->Mode==SWTIMER_MODE_EMPTY){
TIM++;
continue;
}
if (TIM->Mode==SWTIMER_MODE_WAIT_ON){ //Если таймер на задержку включения
if (TIM->On){
if (TIM->LocalCount>0) TIM->LocalCount--;
else {
TIM->Out=1;
TIM->Status=1;
}
}
else {
TIM->Out=0;
TIM->LocalCount=TIM->Count-1;
}
}
if (TIM->Mode==SWTIMER_MODE_WAIT_OFF){ //Если таймер на задержку выключения
if (TIM->On){
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
}
else {
if (TIM->LocalCount>0) TIM->LocalCount--;
else TIM->Out=0;
}
}
if (TIM->Mode==SWTIMER_MODE_CYCLE){
if (TIM->Off){
if (TIM->On){
TIM->Off=0;
if (TIM->LocalCount>0) TIM->LocalCount--;
}
}
else{
if (TIM->LocalCount>0) {
TIM->LocalCount--;
TIM->Out=0;
}
else {
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
}
}
if (TIM->Reset){
TIM->LocalCount=TIM->Count-1;
TIM->Out=0;
TIM->Status=0;
}
}
if (TIM->Mode==SWTIMER_MODE_SINGLE){
if (TIM->Off){
if (TIM->On){
TIM->Off=0;
if (TIM->LocalCount>0) TIM->LocalCount--;
}
}
else{
if (TIM->LocalCount>0) {
TIM->LocalCount--;
TIM->Out=0;
}
else {
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
TIM->Off=1;
TIM->On=0;
}
}
if (TIM->Reset){
TIM->LocalCount=TIM->Count-1;
TIM->Out=0;
TIM->Status=0;
}
}
TIM++;
}
}
void OnSwTimer(volatile SW_TIMER* TIM, SwTimerMode Mode, unsigned int SwCount){
TIM->Mode=Mode;
if (SwCount){
TIM->Count=SwCount;
TIM->LocalCount=SwCount-1;
}
if (TIM->Mode==SWTIMER_MODE_CYCLE || TIM->Mode==SWTIMER_MODE_SINGLE){
TIM->Off=1;
}
}
unsigned char GetStatusSwTimer(volatile SW_TIMER* TIM){
unsigned char status=0;
if (TIM->Mode==SWTIMER_MODE_EMPTY) return -1;
if (TIM->Status){
TIM->Status=0;
status=1;
}
else {
status=0;
}
return status;
}
Спойлер
Код: Выделить всё
volatile uint32_t currentMillis = 0;
void SysTick_Handler(void)
{ static uint8_t count=0;
currentMillis++;
}
uint32_t millis (void)
{
return currentMillis;
}
Код: Выделить всё
if((millis() - previousMillis) > 500){
previousMillis = millis();
blink = !blink;
}
LCDI2C_setCursor (10,0);
if (blink) LCDI2C_write(0x22); else LCDI2C_write(0x20);
LCDI2C_setCursor (11, 0);
sprintf (string_out,"%02dV",(uint8_t)table_u);
LCDI2C_write_String (string_out);
LCDI2C_setCursor (15,0);
if (blink) LCDI2C_write(0x22); else LCDI2C_write(0x20);- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: stm32 cubeide два инкремента не совместимы.
Dimon456, вот, ты как раз сделал то, о чем я ТСу уже давно пытаюсь вталдычить: SysTick нужно использовать для отсчета условного внутреннего времени. И в конечных автоматах для выставления длинных задержек именно его и использовать, а не как абдуринщики вызывать delay_ms(500)!
Скажем, надо тебе сделать переинициализацию дисплея в процессе работы. А там бывают приличные паузы. Ты процесс разбиваешь на несколько кусков. Как только нужна пауза, у тебя состояние, скажем, WAIT_FOR_SOMETH. В нем тупо проверяешь: если миллисекунды натикали достаточно, то переходишь в следующее состояние, если нет - остаешься в этом.
В общем, не понял ты вообще никак, что такое конечные автоматы и в чем их прелесть. А твой код "софтового таймера" - ад какой-то.
Скажем, надо тебе сделать переинициализацию дисплея в процессе работы. А там бывают приличные паузы. Ты процесс разбиваешь на несколько кусков. Как только нужна пауза, у тебя состояние, скажем, WAIT_FOR_SOMETH. В нем тупо проверяешь: если миллисекунды натикали достаточно, то переходишь в следующее состояние, если нет - остаешься в этом.
В общем, не понял ты вообще никак, что такое конечные автоматы и в чем их прелесть. А твой код "софтового таймера" - ад какой-то.


