Добро пожаловать, Гость
Логин: Пароль: Запомнить меня

Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование"
(1 чел.) (1) гость
  • Страница:
  • 1
  • 2
  • 3
  • 4

ТЕМА: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование"

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 3 нед. назад #31

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
Творческий кризис у меня...

Вот по мне - результатом функции обработки кнопок должна быть новая (или остаться старой) величина, с которой сравнивается счётчик периода при формировании высокого уровня...

Как-то так:
on(0 или 1) = STT_BTTN(){обработка кнопок}//STATE_BUTTON(){}
...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 3 нед. назад #32

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Если кризис творческий - это ничего...

Главное - алгоритм. Микроконтроллер обрабатывает поступающие данные. Нажатие кнопки порождает какие-то данные, которые надо обработать. В результате обработки возникают другие данные - то, о чем вы написали: измененная величина скважности импульсов. Если с данными, которые надо получить, более-менее все понятно, то с данными, которые возникают из-за нажатия кнопки, пока кризис.

Итак, ранее я говорил, что любые воздействия на программу извне можно с некоторой степенью достоверности назвать командами, а реакцию программы на эти команды - обработкой команд. То есть надо привести это словесное описание в аналог на языке Си. Для начала введем понятие команды.

Так как извне поступают только нажатия кнопок, пусть все команды у нас так и будут называться - КНОПКА. То есть (сокращенно) BTN. Кнопок у нас 4, причем пара меняет значение одного параметра, а вторая пара - другого. Для простоты просто пронумеруем эти параметры, и тогда команды наши будут отличаться наименованием: BTN_1 и BTN_2 соответственно для первого и второго параметра. Изменение у нас в сторону увеличения и уменьшения (вверх и вниз), соответственно и наименования команд становятся такими:
BTN_1_UP - первый параметр вверх
BTN_1_DN - первый параметр вниз
BTN_2_UP - второй параметр вверх
BTN_2_DN - второй параметр вниз
Как видите, я стремлюсь к максимальному соответствию того, что получается тому, что ранее было "на пальцах" объяснено. Нажали кнопку - получили команду. Не вдаваясь в дебри, пусть команды наши будут однобайтовыми числами, но для приличия обозначим эти числа отдельным типом:

typedef unsigned char btn_command_t; - любая команда в этом случае будет иметь тип btn_command_t.

Итак, есть данные, которые мы хотим получать. Откуда? Да из функции опроса кнопок, ранее об этом речь шла. То есть:

btn_command_t get_button(void); - это функция, которая вернет команду в соответствии с нажатой кнопкой. Как она это сделает - пока не важно (см. принцип нисходящего программирования). Параметров ей не надо, т.к. она в них не нуждается. На данном этапе мы "спохватываемся", что совсем забыли про ситуацию, когда кнопки не нажимаются! Отсутствие нажатия по сути ничем не отличается от команды "не делать ничего". Это странно для человека (он и без команды ничего не делает), но логично для тупой железки, которая вообще в принципе без указания не в состоянии даже ничего не делать. Просто введем дополнительную команду BTN_NOTHING или BTN_NONE, которая и будет означать, что команд пока нет (кнопки не нажаты).

Теперь что мы имеем? функцию, которая даст команду, что надо делать. Остается обработать эту команду. Т.к. команд в принципе несколько, логично использовать для обработки оператор switch, который и предназначен для выполнения разных действий по значению какой-то переменной. получится нечто вроде такого
switch ( get_button() ){
   case BTN_1_UP: // обработка команды
                  break;
   case BTN_1_DN: 
                  break;
   case BTN_2_UP:
                  break;
   case BTN_2_DN:
                  break;
   case BTN_NONE:
   default:
                  break;
}
Как видите, мы, получив команду, раздельно каждую обрабатываем. Пока я не написал, как именно, но уже понятно, что по-разному. Метка default и метка BTN_NONE у нас обрабатываются одинаково, т.е. если вдруг мы получим какую-то странную команду (об этом позже), то не будем никак на нее реагировать.

Пора задуматься над тем, как реагировать на команды. Хоть параметров у нас два, но они по смыслу очень похожи, то есть обрабатываются они идентично, хоть и разные. Напрашивается обработку параметров поручить отдельной функции. пусть она называется change_pwm (изменить ШИМ). Функция должна менять данные, поэтому обязана получать в параметре ссылку на них. В языке Си для этого служит указатель. То есть у функции будет параметр типа "указатель на скважность ШИМ". Скважность у нас однобайтовая, то есть параметр будет обозначен unsigned char *. Однако, скважность должна меняться вверх или вниз, то есть функция должна как-то узнавать, в какую сторону менять этот параметр... то есть функции надо передать второй параметр, который укажет ей направление изменения скважности.

Вырисовывается нечто вроде

void change_pwm(unsigned char *pwm, signed char direction); - функция ничего не возвращает, но зато получает указатель pwm на изменяемые данные и направление direction этого изменения. Для направления я решил взять знаковую переменную, но можно заменить и на беззнаковую - это уже как вам понравится, сути это не меняет. Например, можно было ввести константы DIR_UP и DIR_DN и передавать в функцию их... Чем это лучше простых -1 и +1? Ничем абсолютно!

Итак, вот готовая обработка команд:
switch ( get_button() ){
   case BTN_1_UP: change_pwm( &pwm1, +1 ); 
                  break;
   case BTN_1_DN: change_pwm( &pwm1, -1 );
                  break;
   case BTN_2_UP: change_pwm( &pwm2, +1 );
                  break;
   case BTN_2_DN: change_pwm( &pwm2, -1 );
                  break;
   case BTN_NONE:
   default:
                  break;
}
Как видите, без единого комментария написан код, при чтении вслух которого не остается сомнений в том, что он делает. Только читать надо раскрывая принятые сокращения. Плюсы перед единичкой я поставил умышленно, чтобы было ну совсем понятно

Пока все понятно?

Теперь остается разобраться с тем, как мы будем менять скважность... А потом - как будем из опроса физических портов микроконтроллера получать команды... И все!

Попробуйте самостоятельно так же постепенно, неторопливо рассуждая, расписать содержимое функции изменения скважности, рассматривая её как полностью независимую программу, получающую и обрабатывающую данные.
я не ленивый, я энергосберегающий...
Последнее редактирование: 7 мес., 3 нед. назад от ARV.

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 3 нед. назад #33

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
ARV написал:
<...>Как видите, без единого комментария написан код, при чтении вслух которого не остается сомнений в том, что он делает. Только читать надо раскрывая принятые сокращения. Плюсы перед единичкой я поставил умышленно, чтобы было ну совсем понятно

Пока все понятно?

<...>

Ну, как сказать...
Пока читаю - понятно.
Copy-past, если сделаю - тоже буду думать, что понятно...
Но сам я такое повторить пока не могу...
Если с лексикой у меня ещё более или менее, то вот с грамматикой языка - проблемы...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #34

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Если с синтаксисом Си есть проблемы - их надо устранять в первую очередь. Без знания "азбуки" поэму не напишешь...
я не ленивый, я энергосберегающий...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #35

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
ARV написал:
<...> Функция должна менять данные, поэтому обязана получать в параметре ссылку на них. В языке Си для этого служит указатель. То есть у функции будет параметр типа "указатель на скважность ШИМ".<...>

Ну, мне вот для общего развития...
В данном случае, указатель вводится чтобы не вводить дополнительную переменную?
Так?

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #36

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Что значит "дополнительную"? Вам надо "ту самую", а не "еще одну".
Мы завели переменную, которая задает скважность. Эта переменная используется в главном цикле. Теперь мы хотим функцию, которая могла бы ЭТУ переменную менять - как функция узнает, что это за переменная?
Многие скажут: ну так переменные глобальные, и любая функция их "видит".
Это так. НО!!!
У нас РАЗНЫЕ переменные есть, а методы работы над ними ОДИНАКОВЫЕ. То есть функция одна, но должна уметь менять разные данные. Вот для того, чтобы функция могла работать с разными данными, ей и нужен параметр, который УКАЖЕТ, какие именно данные надо обрабатывать. Указатель.

Опять же, кто-то скажет, а зачем указатель, если можно использовать РЕЗУЛЬТАТ обработки переданных данных без указателя? И да, так тоже можно. Сравните сами:
// пример с указателями (абстрактный)
int var1, var2, var3; // это какие-то данные

void modification_one(int *data); // это прототип функции, которая работает через указатель

int modification_two(int data); // а это - прототип функции без указателя

// пример изменения данных вышеперечисленными функциями

modification_one(&var1);
modification_one(&var2);

var1 = modofocation_two(var1);
var2 = modification_two(var2);

Примеры делают одно и то же, но действия эти оформляются по-разному. В первом случае через указатель функция узнает значение переменной и сохраняет в этой же переменной новое значение. Во втором значение функция узнает через параметр, а новое значение - возвращает.

Оба подхода имеют право на жизнь, у каждого свои плюсы и минусы... И однозначно сказать, что какой-то вариант безоговорочно лучше, нельзя. Надо знать оба способа и использовать их в удобных случаях.
я не ленивый, я энергосберегающий...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #37

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
Рискну...
Откуда получать данные.

Кнопки подключены к порту ввода-вывода.
Значит, они меняют состояние порта.
Значит, данные о кнопках можно получить, узнав в каком состоянии находится порт, к которому подключены кнопки...

P.s. Может в форме тепло-холодно я смогу осилить...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #38

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Направление верное, очевидное.
Кнопки - это одно из базовых понятий, как таблица умножения, разобравшись один раз, в последствии пользуешься автоматически не задумываясь.
Важно осознать тот факт, что кнопка "по-человечески" и кнопка "по-микроконтроллерски" это разные вещи: человеку удобно, когда кнопка имеет осмысленное значение (то ли название, то ли числовой эквивалент), а микроконтролеру совершенно безразлично это, единственное, что важно, что разные кнопки имеют разный смысл. И все.
Это я к тому, что (возвращаясь чуть выше) мы уже определили "человеческое" значение кнопок - BTN_1_UP и так далее, и теперь надо назначить этим символам какое-то практически удобное значение. Вовсе не важно, что "кнопка номер 1" будет соответствовать числу 1. Понимаете? И самое удобное в этом случае - выбрать в качестве значения именно состояние порта в момент опроса. Ну или что-то очень к тому близкое. Улавдиваете идею?
я не ленивый, я энергосберегающий...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #39

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
ARV написал:
<•••>самое удобное в этом случае - выбрать в качестве значения именно состояние порта в момент опроса.<•••>

Если состояние порта - это число, я бы использовал именно его, сохранив его в момент опроса в переменной...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #40

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Во-во. Остается только теперь записать это намерение в виде конкретных #define.
я не ленивый, я энергосберегающий...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #41

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
ARV написал:
<...>У нас РАЗНЫЕ переменные есть, а методы работы над ними ОДИНАКОВЫЕ. То есть функция одна, но должна уметь менять разные данные. Вот для того, чтобы функция могла работать с разными данными, ей и нужен параметр, который УКАЖЕТ, какие именно данные надо обрабатывать. Указатель.<...>
<...>

modification_one(&var1);
modification_one(&var2);

var1 = modofocation_two(var1);
var2 = modification_two(var2);

Примеры делают одно и то же, но действия эти оформляются по-разному. В первом случае через указатель функция узнает значение переменной и сохраняет в этой же переменной новое значение. Во втором значение функция узнает через параметр, а новое значение - возвращает.<...>


Спасибо, в общих чертах понятно...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #42

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
ARV написал:
<...>записать это намерение в виде конкретных #define.

#define BTN_1_UP (0b11111110)		//можно просто "254" нажата кнопка "+" второго канала
#define BTN_1_DWN (0b11111101)		//нажата кнопка "253" "-" второго канала	    
 #define BTN_2_UP (0b11111011)		//нажата кнопка "251" "+" второго канала
#define BTN_2_DWN (0b11110111)		//нажата кнопка "247" "-" второго канала


Если по верному пути иду, то get_button() должна вернуть одно из этих чисел в виде BTN_X_Y...
Что-то запутался, ещё подумаю...

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #43

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
По верному, по верному. Есть только небольшой советик.
Все-таки для понимания проще оперировать с номером линии порта. Т.е. первая кнопка занимает первую линию, вторая - вторую и т.д. И вот тут получается такое: положение бита в байте связано с номером этого бита очевидной операцией сдвига: 1<<5 - 5-й бит (нумерация в Си начинается с нуля, т.е. "по-людски" это будет 6-й бит). То есть 1<<5 это 0b00100000. А вот положение нуля сдвигом не обозначить, т.к. сколько ноль не двигай, ноль и будет. Для операции определения положения бита в байте по его номеру в avr-gcc даже специальный макрос предусмотрен, _BV(x) - от слов Bit Value.
#define _BV(x)   (1 << (x))

Вот и получается, что задавать константы кнопок через номер линии порта удобнее, чем путем написания вручную каких-то двоичных чисел.

Если вам нравится работать с "инверсными" битами, то ранее указанная вами запись будет выглядеть так:
#define BTN_1_UP    ~_BV(0)
#define BTN_1_DWN   ~_BV(1) и т.д.

Нет лишних, загромождающих поле зрения единичек, и сразу понятно, о каком именно бите идет речь. Да и в случае чего изменить проще, если номера пинов захочется поменять.
я не ленивый, я энергосберегающий...
Последнее редактирование: 7 мес., 2 нед. назад от ARV.

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #44

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Да, вот еще что: очень рекомендую не вводить лишние сущности! У вас в комментарии написано "можно просто XXX" - так вот, не можно! и не нужно! Тем более что в числе 253 никаким способом невозможно узнать ничего осмысленного про кнопку. Даже в комментарии не стоит давать намеки на какие-то альтернативы, чтобы не вводить себя в соблазн запутаться.
я не ленивый, я энергосберегающий...
Последнее редактирование: 7 мес., 2 нед. назад от ARV.

Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисходящее программирование" 7 мес., 2 нед. назад #45

  • plis
  • Вне сайта
  • Захожу иногда
  • Постов: 47
  • Репутация: 0
Ну, это я чтобы окончательно убедить себя, что комбинация кнопок - это просто некоторое число, существующее в некоторый момент, в некоторой области памяти...

Отсюда следующее предположение - если это "некоторый момент"- то надо убедиться, что это не случайное состояние (число)?..
  • Страница:
  • 1
  • 2
  • 3
  • 4
Время создания страницы: 0.18 секунд