Я тоже.menzoda писал(а):k000858 писал(а):поэтому я бы предпочел внешнюю FRAM, ну или EEPROM.
STM32 новичку в ARM что к чему
Re: STM32 новичку в ARM что к чему
С уважением,
Виктор.
Виктор.
- Реклама
- mial
- Друг Кота
- Сообщения: 3254
- Зарегистрирован: Ср янв 06, 2010 23:31:56
- Откуда: Боровичи, Новг. обл.
Re: STM32 новичку в ARM что к чему
Привет всем. Мучаю потихоньку stm32f100c4.
Возник у меня вот такой вопрос по Си.
Почему так не понимаю.
Вот такой код
работает четко. Без нареканий. Все нажатия кнопок отрабатываются без задержек.
А код на основе if работает через раз
Причем первый if отрабатывает почти всегда, а вот последующие могут и через десять нажатий сработать.
если код переделать вот так
То тогда работает четко. Процедура обработки кнопок взята отсюда viewtopic.php?p=1704144#p1704144
Сам опрос крутится в 1мс таймере, TRESHOLD 20 мс. эта часть вопросов не вызывает. Кстати в самой функции GetPressedButton() небольшая неточность. else там лишние. Если их оставить то код кнопки возвращается всегда, независимо нажата или нет. У меня эта функция получилась вот такого вида.
Вопрос, почему не работают if если функцию GetPressedButton() вызывать непосредственно из if?
Возник у меня вот такой вопрос по Си.
Почему так не понимаю.
Вот такой код
Код: Выделить всё
switch (GetPressedButton())
{
case key_1:
time_s++; break;
case key_2:
time_s = time_s + 10; break;
case key_3:
time_s = time_s + 60; break;
default:
break;
}работает четко. Без нареканий. Все нажатия кнопок отрабатываются без задержек.
А код на основе if работает через раз
Код: Выделить всё
if(GetPressedButton() & key_1) time_s++;
if(GetPressedButton() & key_2) time_s = time_s + 10;
if(GetPressedButton() & key_3) time_s = time_s + 60;Причем первый if отрабатывает почти всегда, а вот последующие могут и через десять нажатий сработать.
если код переделать вот так
Код: Выделить всё
timer_1 = GetPressedButton();
if(timer_1 & key_1) time_s++;
if(timer_1 & key_2) time_s = time_s + 10;
if(timer_1 & key_3) time_s = time_s + 60;То тогда работает четко. Процедура обработки кнопок взята отсюда viewtopic.php?p=1704144#p1704144
Сам опрос крутится в 1мс таймере, TRESHOLD 20 мс. эта часть вопросов не вызывает. Кстати в самой функции GetPressedButton() небольшая неточность. else там лишние. Если их оставить то код кнопки возвращается всегда, независимо нажата или нет. У меня эта функция получилась вот такого вида.
Код: Выделить всё
#define key_1 0x01
#define key_2 0x02
#define key_3 0x04
int GetPressedButton( void )
{
if( button_cnt_1 == TRESHOLD ) {button_cnt_1 = TRESHOLD+1; return key_1;}
if( button_cnt_2 == TRESHOLD ) {button_cnt_2 = TRESHOLD+1; return key_2;}
if( button_cnt_3 == TRESHOLD ) {button_cnt_3 = TRESHOLD+1; return key_3;}
return ( 0 );
}Вопрос, почему не работают if если функцию GetPressedButton() вызывать непосредственно из if?
Прототипы печатных плат на заказ https://radiokot.ru/forum/viewtopic.php?f=54&t=122701
Re: STM32 новичку в ARM что к чему
mial писал(а):Привет всем. Мучаю потихоньку stm32f100c4.
Возник у меня вот такой вопрос по Си.
....
А код на основе if работает через разКод: Выделить всё
if(GetPressedButton() & key_1) time_s++;
if(GetPressedButton() & key_2) time_s = time_s + 10;
if(GetPressedButton() & key_3) time_s = time_s + 60;
Причем первый if отрабатывает почти всегда, а вот последующие могут и через десять нажатий сработать.
если код переделать вот такКод: Выделить всё
timer_1 = GetPressedButton();
if(timer_1 & key_1) time_s++;
if(timer_1 & key_2) time_s = time_s + 10;
if(timer_1 & key_3) time_s = time_s + 60;
То тогда работает четко. Процедура обработки кнопок взята отсюда viewtopic.php?p=1704144#p1704144
Сам опрос крутится в 1мс таймере, TRESHOLD 20 мс. эта часть вопросов не вызывает. Кстати в самой функции GetPressedButton() небольшая неточность. else там лишние. Если их оставить то код кнопки возвращается всегда, независимо нажата или нет.
Вопрос, почему не работают if если функцию GetPressedButton() вызывать непосредственно из if?
Вам нужно в момент времени Т определить, какая нажата кнопка. Вы ОДИН раз должны обратится в момент Т к этой функции, зафиксировать этот результат, а потом уже заняться его анализом. В вашем же примере вы вызываете функцию в ТРИ разных момента времени Т1, Т2 и Т3 (каждый if в свой момент времени). Состояние кнопок может быть непредсказуемым, особенно, если учесть, что работает прерывание 1 мсек.
Таким образом ваш вопрос совершенно не к языку Си. Захромало понимание алгоритма.
Насчет else сам не понимаю, почему их вписал. Текст набирал вручную, был бы копипаст из фрагмента, там бы этого не было.
Ну, лишний раз доказывает, что вы таки разобрались с этим вариантом решения. Наверняка увидели и то, что решение частное. Этот способ не отслеживает состояние кнопки. Варианты придумайте сами, там не сложно.
С уважением,
Виктор.
Виктор.
-
Foks
- Поставщик валерьянки для Кота
- Сообщения: 2108
- Зарегистрирован: Пт авг 29, 2008 16:28:19
- Откуда: Киев
Re: STM32 новичку в ARM что к чему
Я так полагаю, раз вы догадались до вот этогоmial писал(а):Вопрос, почему не работают if если функцию GetPressedButton() вызывать непосредственно из if?
Код: Выделить всё
timer_1 = GetPressedButton();Нет, серьезно, вопрос детский. Уровня средней школы, где алгоритмы только начинают изучать.
Кстати объяснение автора кода (я правильно понял?), как это ни парадоксально, тоже не совсем точное. Момент времени там почти один и тот же, и если бы там происходил именно опрос кнопок, всё бы работало. Но дело в счетчиках. Когда функция однажды вернула какую-либо кнопку, она уже второй раз её вернуть не может. Поэтому если в первом if'е была возвращена кнопка 2, к примеру, то повторный вызов функции в следующем if'е уже не вернет такое же значение.
Я сперва не всё посмотрел. Кривоватая реализация этих счетчиков, как по мне. Я всегда делал переменную с флагами, которые устанавливаются непосредственно там, где и происходит опрос кнопок (например, прерывание таймера). Счетчики обрабатываются у меня тоже обычно исключительно в том же прерывании. И надо не забывать про атомарность операций, к примеру блокировать прерывание, на время работы с этими переменными в главном цикле.
P.P.P.P.S. Более надежно проверять переполнение счетчика оператором >=,и только им. Использование == зачастую и приводит вот к таким последствиям.
Giggity giggity goo!
- mial
- Друг Кота
- Сообщения: 3254
- Зарегистрирован: Ср янв 06, 2010 23:31:56
- Откуда: Боровичи, Новг. обл.
Re: STM32 новичку в ARM что к чему
mial писал(а):Таким образом ваш вопрос совершенно не к языку Си. Захромало понимание алгоритма.
Это понятно, не совсем корректно задал вопрос. Но сам алгоритм работы этой функции не догоняю... В прерывании крутится счетчик. Если кнопка, предположим key_1 была нажата, то факт нажатия и до момента отпускания зафиксирован в счетчике button_cnt_1. Пока кнопка нажата значение button_cnt_1 равно TRESHOLD. Если в этот момент вызвать функцию GetPressedButton() то она вернет код нажатой кнопки key_1. Одновременно увеличив счетчик button_cnt_1 на единицу. Что не даст при повторном вызове функции пока кнопка еще не отпущена повторного возвращения кода кнопки. Вроде тут я все правильно понял? Из за этого и получается, если предположим была нажата key_2, а вызов GetPressedButton() был например из первого IF, то при повторном вызове из второго IF пока кнопка не была отпущена и повторно нажата GetPressedButton() вернет 0?
Foks писал(а):Нет, серьезно, вопрос детский. Уровня средней школы, где алгоритмы только начинают изучать.
Я в школе учился когда еще и калькуляторов не было
P.S. Вообщем разобрался я с обработкой нажатия используя эту функцию. Получилось с помощью нее сделать небольшую менюшку на 4 таймера и в каждом обрабатывать каждую цифру по отдельности. То есть бегать по разрядам (динамический вывод на 4 разрядный семисегментник) и изменять значение каждого разряда по отдельности. По колхозному конечно, но работает без сбоев и ошибок. Причешу немного код, и спрошу ваших советов как сделал я, и как делать такое меню правильно. Спасибо за каменты и ответы на вопросы.

Прототипы печатных плат на заказ https://radiokot.ru/forum/viewtopic.php?f=54&t=122701
- Реклама
-
Foks
- Поставщик валерьянки для Кота
- Сообщения: 2108
- Зарегистрирован: Пт авг 29, 2008 16:28:19
- Откуда: Киев
Re: STM32 новичку в ARM что к чему
Звиняюсь за грубость в первом ответе.

Да.mial писал(а):Если в этот момент вызвать функцию GetPressedButton() то она вернет код нажатой кнопки key_1. Одновременно увеличив счетчик button_cnt_1 на единицу. Что не даст при повторном вызове функции пока кнопка еще не отпущена повторного возвращения кода кнопки. Вроде тут я все правильно понял? Из за этого и получается, если предположим была нажата key_2, а вызов GetPressedButton() был например из первого IF, то при повторном вызове из второго IF пока кнопка не была отпущена и повторно нажата GetPressedButton() вернет 0?
Giggity giggity goo!
Re: STM32 новичку в ARM что к чему
Хорошо, что проблема решилась, но почему никто не заметил, что:
и
разные вещи. В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
Код: Выделить всё
switch(...)
{
case key1: ...
case key2: ...
case key3: ...
}
и
Код: Выделить всё
if(... & key1) ...
if(... & key2) ...
if(... & key3) ...
разные вещи. В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
Re: STM32 новичку в ARM что к чему
Мне показалось, что и во втором случае имеет место быть оператор сравнения. В неявном виде.menzoda писал(а):В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
Код: Выделить всё
if( var & mask ) ...эквивалентно
Код: Выделить всё
if( (var & mask) == TRUE ) ...В любом случае результирующее действие будет зависеть от результата выполнения условия, а оно может быть только двух типов. TRUE or FALSE. Что бы мы там в условии не наворотили.
С уважением,
Виктор.
Виктор.
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Чуток поправлю
if( var & mask ) не эквивалентно
if( (var & mask) == TRUE ) ...
это эквивалентно
if( (var & mask) != false )
любое ненулевое значение, не только единица.
if( var & mask ) не эквивалентно
if( (var & mask) == TRUE ) ...
это эквивалентно
if( (var & mask) != false )
любое ненулевое значение, не только единица.
Re: STM32 новичку в ARM что к чему
А на какую именно ошибку можно нарватся?menzoda писал(а):Хорошо, что проблема решилась, но почему никто не заметил, что:Код: Выделить всё
switch(...)
{
case key1: ...
case key2: ...
case key3: ...
}
иКод: Выделить всё
if(... & key1) ...
if(... & key2) ...
if(... & key3) ...
разные вещи. В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
Я например всегда использую второй способ. (первый способ иногда может не отработать... зато он исключает неоднозначности.....)
Можно подробнее, какую ошибочную ситуацию вы имеете ввиду?
Re: STM32 новичку в ARM что к чему
Так, немного подробнее, а то не понимаем друг-друга.
Возьмем свитч:
Он эквивалентен следующему:
Но ни в коем случае не такому:
Если переменная содержит набор битовых флагов, то первый if сработает тогда и только тогда, когда установлен только нулевой бит. Если в переменной будут установлены еще какие-нибудь биты, то условие не сработает. Скорей всего это не то, что хотелось бы при работе с битовыми флагами.
Если переменная содержит набор взаимоисключающих непересекающихся значений (к примеру, enum со списком цветов Red|White|Blue|Green), то второе условие будет срабатывать каждый раз, когда установлен нулевой бит. Это тоже, скорее всего, не то, что хотелось бы при работе с такими данными.
Возьмем свитч:
Код: Выделить всё
switch(var)
{
case 0x01:
...
break;
}
Он эквивалентен следующему:
Код: Выделить всё
if (var == 0x01)
{
...
}
Но ни в коем случае не такому:
Код: Выделить всё
if (var & 0x01)
{
....
}
Если переменная содержит набор битовых флагов, то первый if сработает тогда и только тогда, когда установлен только нулевой бит. Если в переменной будут установлены еще какие-нибудь биты, то условие не сработает. Скорей всего это не то, что хотелось бы при работе с битовыми флагами.
Если переменная содержит набор взаимоисключающих непересекающихся значений (к примеру, enum со списком цветов Red|White|Blue|Green), то второе условие будет срабатывать каждый раз, когда установлен нулевой бит. Это тоже, скорее всего, не то, что хотелось бы при работе с такими данными.
Re: STM32 новичку в ARM что к чему
Ну это понятно, что если говорить о: вообще операции сравнения, то тут куча вариантов того что как будет работать.....
Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....
Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....
Re: STM32 новичку в ARM что к чему
shads писал(а):Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....
Угу а две и более кнопки одновременно нажаты не могут быть
Re: STM32 новичку в ARM что к чему
Да хоть стопицот! Отработана будет только одна.dosikus писал(а):shads писал(а):Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....
Угу а две и более кнопки одновременно нажаты не могут быть
С уважением,
Виктор.
Виктор.
- mial
- Друг Кота
- Сообщения: 3254
- Зарегистрирован: Ср янв 06, 2010 23:31:56
- Откуда: Боровичи, Новг. обл.
Re: STM32 новичку в ARM что к чему
Тут единственно в данном решении нужно не забывать правильно дефайнить те же key_1 2 3... Так как я понимаю в if идет побитовое И. И если например key_3 задефайнить как
то в результате key_1 & key_3 даст не нулевой результат.
Если же задефайнить так
тогда результат в любом сочетании будет правильный. ИМХО
Код: Выделить всё
#define key_1 1
#define key_2 2
#define key_3 3то в результате key_1 & key_3 даст не нулевой результат.
Если же задефайнить так
Код: Выделить всё
#define key_1 1
#define key_2 2
#define key_3 4тогда результат в любом сочетании будет правильный. ИМХО
Прототипы печатных плат на заказ https://radiokot.ru/forum/viewtopic.php?f=54&t=122701
-
Foks
- Поставщик валерьянки для Кота
- Сообщения: 2108
- Зарегистрирован: Пт авг 29, 2008 16:28:19
- Откуда: Киев
Re: STM32 новичку в ARM что к чему
Ну, я это заметил, но ведь там было 0x01, 0x02 и 0x04. Ошибка с трехкратным вызовом функции была более вопиющей, поэтому я уже и не стал об этом писать.
Хотя вообще использование == там действительно более правильное, т.к. две кнопки одновременно функцией всё-равно никогда не возвращаются, и возможное число кнопок возрастает экспоненциально.
Хотя вообще использование == там действительно более правильное, т.к. две кнопки одновременно функцией всё-равно никогда не возвращаются, и возможное число кнопок возрастает экспоненциально.
Giggity giggity goo!
Re: STM32 новичку в ARM что к чему
menzoda писал(а): Это тоже, скорее всего, не то, что хотелось бы при работе с такими данными.
Т.е. выхода нет и всё неправильно???
А для чего тогда прослойка между монитором и стулом???
"Я не даю готовых решений, я заставляю думать!"(С)
Re: STM32 новичку в ARM что к чему
А я себе давно уже такую библиотечку слепил, обрабатывает короткие и длинные нажатия 4-х кнопок.ut1wpr писал(а):Процедура обработки кнопок взята отсюда viewtopic.php?p=1704144#p1704144
Если чуть допилить то и на STM можно...
Вообще можно и == и & применять.....
Если в сравнении стоит ==, то например в ситуации когда в основном цикле обрабатывалась какая то тяжелая функция, и за это время успели последовательно нажать несколько разных кнопок, то потом в сравнении не отработается ни один путь... т.к. будут установлены несколько флагов, что не будет соответствовать ни одному сравнению.....
Если в сравнении стоит &, то в той же ситуации последовательно отработаются оба нажатия..... НО, есть одно НО.... последовательность вызова соответствующих функций будет определятся порядком сравнения в программе, а не порядком нажатия кнопок, что может привести к неправильной последовательности действий.....
Но, т.к. в простых задачах в основном цикле обычно нет таких тяжелых функций.... да и так быстро обычно кнопки не нажимают.... то по сути оба варианта будут нормально работать.
-
Foks
- Поставщик валерьянки для Кота
- Сообщения: 2108
- Зарегистрирован: Пт авг 29, 2008 16:28:19
- Откуда: Киев
Re: STM32 новичку в ARM что к чему
Блин, вы код читали? Там три отдельных счетчика, и функция всегда возвращает одну(!) кнопку. Следующую вернет уже при следующем вызове.
Giggity giggity goo!
Re: STM32 новичку в ARM что к чему
Foks писал(а):Блин, вы код читали? Там три отдельных счетчика, и функция всегда возвращает одну(!) кнопку. Следующую вернет уже при следующем вызове.
Ыыыы.... я вообще то про свою библиотечку рассуждал..... вы ее читали?.....


