STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: STM32 новичку в ARM что к чему

Сообщение ut1wpr »

menzoda писал(а):
k000858 писал(а):поэтому я бы предпочел внешнюю FRAM, ну или EEPROM.
Я тоже. :)
С уважением,
Виктор.
Реклама
Аватара пользователя
mial
Друг Кота
Сообщения: 3254
Зарегистрирован: Ср янв 06, 2010 23:31:56
Откуда: Боровичи, Новг. обл.

Re: STM32 новичку в ARM что к чему

Сообщение mial »

Привет всем. Мучаю потихоньку stm32f100c4.
Возник у меня вот такой вопрос по Си.
Почему так не понимаю.
Вот такой код

Код: Выделить всё

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
Реклама
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: STM32 новичку в ARM что к чему

Сообщение ut1wpr »

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 что к чему

Сообщение Foks »

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 »

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 разрядный семисегментник) и изменять значение каждого разряда по отдельности. По колхозному конечно, но работает без сбоев и ошибок. Причешу немного код, и спрошу ваших советов как сделал я, и как делать такое меню правильно. Спасибо за каменты и ответы на вопросы. :beer:
Прототипы печатных плат на заказ https://radiokot.ru/forum/viewtopic.php?f=54&t=122701
Реклама
Foks
Поставщик валерьянки для Кота
Сообщения: 2108
Зарегистрирован: Пт авг 29, 2008 16:28:19
Откуда: Киев

Re: STM32 новичку в ARM что к чему

Сообщение Foks »

Звиняюсь за грубость в первом ответе. :?
mial писал(а):Если в этот момент вызвать функцию GetPressedButton() то она вернет код нажатой кнопки key_1. Одновременно увеличив счетчик button_cnt_1 на единицу. Что не даст при повторном вызове функции пока кнопка еще не отпущена повторного возвращения кода кнопки. Вроде тут я все правильно понял? Из за этого и получается, если предположим была нажата key_2, а вызов GetPressedButton() был например из первого IF, то при повторном вызове из второго IF пока кнопка не была отпущена и повторно нажата GetPressedButton() вернет 0?
Да. :)
Giggity giggity goo!
Реклама
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: STM32 новичку в ARM что к чему

Сообщение menzoda »

Хорошо, что проблема решилась, но почему никто не заметил, что:

Код: Выделить всё

switch(...)
{
    case key1: ...
    case key2: ...
    case key3: ...
}

и

Код: Выделить всё

if(... & key1) ...
if(... & key2) ...
if(... & key3) ...

разные вещи. В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: STM32 новичку в ARM что к чему

Сообщение ut1wpr »

menzoda писал(а):В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
Мне показалось, что и во втором случае имеет место быть оператор сравнения. В неявном виде.

Код: Выделить всё

if( var & mask ) ...

эквивалентно

Код: Выделить всё

if( (var & mask) == TRUE ) ...

В любом случае результирующее действие будет зависеть от результата выполнения условия, а оно может быть только двух типов. TRUE or FALSE. Что бы мы там в условии не наворотили.
С уважением,
Виктор.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение urry »

Чуток поправлю

if( var & mask ) не эквивалентно
if( (var & mask) == TRUE ) ...

это эквивалентно
if( (var & mask) != false )

любое ненулевое значение, не только единица.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: STM32 новичку в ARM что к чему

Сообщение shads »

menzoda писал(а):Хорошо, что проблема решилась, но почему никто не заметил, что:

Код: Выделить всё

switch(...)
{
    case key1: ...
    case key2: ...
    case key3: ...
}

и

Код: Выделить всё

if(... & key1) ...
if(... & key2) ...
if(... & key3) ...

разные вещи. В первом куске кода мы сравниваем условие и флаги с помощью ==, а во втором &. Когда-нибудь так можно нарваться на ошибку.
А на какую именно ошибку можно нарватся?
Я например всегда использую второй способ. (первый способ иногда может не отработать... зато он исключает неоднозначности.....)

Можно подробнее, какую ошибочную ситуацию вы имеете ввиду?
Аватара пользователя
menzoda
Вымогатель припоя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Re: STM32 новичку в ARM что к чему

Сообщение menzoda »

Так, немного подробнее, а то не понимаем друг-друга.

Возьмем свитч:

Код: Выделить всё

switch(var)
{
    case 0x01:
        ...
        break;
}

Он эквивалентен следующему:

Код: Выделить всё

if (var == 0x01)
{
    ...
}

Но ни в коем случае не такому:

Код: Выделить всё

if (var & 0x01)
{
    ....
}


Если переменная содержит набор битовых флагов, то первый if сработает тогда и только тогда, когда установлен только нулевой бит. Если в переменной будут установлены еще какие-нибудь биты, то условие не сработает. Скорей всего это не то, что хотелось бы при работе с битовыми флагами.

Если переменная содержит набор взаимоисключающих непересекающихся значений (к примеру, enum со списком цветов Red|White|Blue|Green), то второе условие будет срабатывать каждый раз, когда установлен нулевой бит. Это тоже, скорее всего, не то, что хотелось бы при работе с такими данными.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: STM32 новичку в ARM что к чему

Сообщение shads »

Ну это понятно, что если говорить о: вообще операции сравнения, то тут куча вариантов того что как будет работать.....
Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32 новичку в ARM что к чему

Сообщение dosikus »

shads писал(а):Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....

Угу а две и более кнопки одновременно нажаты не могут быть :)))
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: STM32 новичку в ARM что к чему

Сообщение ut1wpr »

dosikus писал(а):
shads писал(а):Но мы сейчас говорим о функции обработки регистра флагов нажатых кнопок....

Угу а две и более кнопки одновременно нажаты не могут быть :)))
Да хоть стопицот! Отработана будет только одна. :) Я ж писал люду, что это частное решение. :)))
С уважением,
Виктор.
Аватара пользователя
mial
Друг Кота
Сообщения: 3254
Зарегистрирован: Ср янв 06, 2010 23:31:56
Откуда: Боровичи, Новг. обл.

Re: STM32 новичку в ARM что к чему

Сообщение mial »

Тут единственно в данном решении нужно не забывать правильно дефайнить те же key_1 2 3... Так как я понимаю в if идет побитовое И. И если например 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 что к чему

Сообщение Foks »

Ну, я это заметил, но ведь там было 0x01, 0x02 и 0x04. Ошибка с трехкратным вызовом функции была более вопиющей, поэтому я уже и не стал об этом писать.

Хотя вообще использование == там действительно более правильное, т.к. две кнопки одновременно функцией всё-равно никогда не возвращаются, и возможное число кнопок возрастает экспоненциально.
Giggity giggity goo!
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: STM32 новичку в ARM что к чему

Сообщение HHIMERA »

menzoda писал(а): Это тоже, скорее всего, не то, что хотелось бы при работе с такими данными.

Т.е. выхода нет и всё неправильно??? :))
А для чего тогда прослойка между монитором и стулом???
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: STM32 новичку в ARM что к чему

Сообщение shads »

ut1wpr писал(а):Процедура обработки кнопок взята отсюда viewtopic.php?p=1704144#p1704144
А я себе давно уже такую библиотечку слепил, обрабатывает короткие и длинные нажатия 4-х кнопок.
Если чуть допилить то и на STM можно...

Вообще можно и == и & применять.....

Если в сравнении стоит ==, то например в ситуации когда в основном цикле обрабатывалась какая то тяжелая функция, и за это время успели последовательно нажать несколько разных кнопок, то потом в сравнении не отработается ни один путь... т.к. будут установлены несколько флагов, что не будет соответствовать ни одному сравнению.....

Если в сравнении стоит &, то в той же ситуации последовательно отработаются оба нажатия..... НО, есть одно НО.... последовательность вызова соответствующих функций будет определятся порядком сравнения в программе, а не порядком нажатия кнопок, что может привести к неправильной последовательности действий.....

Но, т.к. в простых задачах в основном цикле обычно нет таких тяжелых функций.... да и так быстро обычно кнопки не нажимают.... то по сути оба варианта будут нормально работать.
Foks
Поставщик валерьянки для Кота
Сообщения: 2108
Зарегистрирован: Пт авг 29, 2008 16:28:19
Откуда: Киев

Re: STM32 новичку в ARM что к чему

Сообщение Foks »

Блин, вы код читали? Там три отдельных счетчика, и функция всегда возвращает одну(!) кнопку. Следующую вернет уже при следующем вызове.
Giggity giggity goo!
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: STM32 новичку в ARM что к чему

Сообщение shads »

Foks писал(а):Блин, вы код читали? Там три отдельных счетчика, и функция всегда возвращает одну(!) кнопку. Следующую вернет уже при следующем вызове.

Ыыыы.... я вообще то про свою библиотечку рассуждал..... вы ее читали?.....
Ответить

Вернуться в «ARM»