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

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #1 от plis
plis создал эту тему: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Нисхо
Давно существующее желание получить минимальные навыки работы с микроконтроллерами совпали с практической необходимостью управлять двумя (в перспективе тремя или четырьмя) двигателями постоянного тока.
Вся эта красота будет реализовываться на микроконтроллере ATmega16a (потому что он уже есть) и на языке Си - как на самом низкоуровневом из высокоуровневых.)

Как выглядит задача с моей точки зрения:
1. Получить две независимых последовательности прямоугольных импульсов.
2. Иметь возможность независимого управления этими последовательностями.
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]


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

Вот один из вариантов который нравится мне самому
ВНИМАНИЕ: Спойлер! [ Нажмите, чтобы развернуть ]
Последнее редактирование: 3 года 6 мес. назад от plis.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #2 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Если позволите, слегка покритикую: ваш код просто пестрит "магическими числами" - это нехорошо. Числа по тексту программы допустимы, когда их смысловое назначение очевидно и значение принципиально неизменно. Например, строки в Си оканчиваются нулем, поэтому при поиске вполне допустимо сравнивать символ с нулем, а в остальных случаях применять макросы.

Конкретно у вас в коде есть, например, число 0b00000100 - очевидно, что это битовая маска для работы с портом. Но у вас есть так же и другие похожие числа, и назначение у них похожее - стоит ли говорить, что перепутать их довольно легко? Поэтому настоятельно рекомендую заменить все магические числа на соответствующим образом определенные константы-макросы примерно так:
#define BUTTON_1 0b00000100
#define BUTTON_2 0b00000010
// и т.д.
ну и, разумеется, в самом коде использовать уже не магические числа, а эти макросы:
if((!(port_state & BUTTON_2))&&(Tconst>=(ton0+d0))&&(!r))

Ну а дальше - задавайте вопросы :)

я не ленивый, я энергосберегающий...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #3 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Ещё неделю назад я бы стал возражать, что для меня 0b00000010 - гораздо нагляднее чем "#define".
Сейчас уже - соглашусь с вами.

Но, давайте код из первого сообщения останется как "... программа первая моя ..."©, чтобы можно было сравнить его с тем, что получится при применении подхода описанного в статье Нисходящее программирование на простом примере .

Обобщённую задачу я описал в первом сообщении.
Жаль, что в языке Си нет такого оператора, который бы выполнял пункт первый.
Да и для второго пункта операторов нет.

Придётся начинать "нисходить".
Пока, я не понимаю какого типа окажутся функции и пишу на удачу:
1. void PWM_SEQUENCE(void){//здесь должны быть сформированы две последовательности модулированных по ширине имульсов}

2. void PRESS_BUTTON(void){//здесь должно осуществляться само модулирование колебаний. Кнопками.}

Пока - так...
Последнее редактирование: 3 года 6 мес. назад от plis.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #4 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Не так.
"Нисходить" - это значит идти от общего к частностям, от крупного к мелкому, от задачи к реализации по шагам. Сразу функции - это восходящий принцип, от частного к общему. Так тоже можно проектировать программы, но, во-первых, это не наш стиль (не НИСХОДЯЩЕЕ программирование), а во-вторых, так легче работать с боьлшим опытом за плечами.

Начинать надо не с функций, а с обобщенного алгоритма, который в вашем случае должен выглядеть как-то так (согласно статье):
1. ШИМ получается периодическим выводом в порт таких значений, что на паре линий сформируются нужные нам последовательности импульсов.
2. Периодически - значит, в цикле.
3. Так как это основная задача, следовательно и цикл будет главным.
4. В том же главном цикле опрашиваем кнопки и реагируем на их нажатия, меняя параметры для п.1
5. При необходимости запоминаем на будущее параметры ШИМа
Теперь пробуем записать это на языке Си, используя русский язык там, где еще не ясно, что и как будет:
int main(void){
   while(1){
      // подготавливаем данные для порта
      // выводим  эти данные в порт
      // опрашиваем кнопки, для обработки кнопок лучше всего оператор switch
      switch(результат_опроса_кнопок){
      case КНОПКА_1 : // тут обработка кнопок по аналогии
      }
      // тут все готово к очередной итерации цикла и/или запоминанию в EEPROM
   }
}
вроде бы все понятно и в соответствии с духом статьи, не так ли?

Теперь попробуйте проделать итерацию замены комментариев на нечто более осмысленное в плане языка Си. Не надо торопиться и менять сразу все комменты - если не очень прониклись духом стиля нисходящего программирования, делайте постепенно, понемногу, до полного просветления :)
Подсказка: уже понятно, что нам потребуются макросы для кнопок, переменные для подготовки данных в порт, сам порт и т.п.

я не ленивый, я энергосберегающий...
Последнее редактирование: 3 года 6 мес. назад от ARV.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #5 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н

ARV пишет: <...> понятно, что нам потребуются макросы для кнопок, переменные для подготовки данных в порт, сам порт и т.п.

Пишу дифайны. Не знаю на чём остановиться. Написание дифайнов - это как ремонт. Закончить нельзя - только прекратить!
 #define BTN1_UP (!(PINB & 0b00000001))	//нажата кнопка "+" первого канала
#define BTN1_DWN (!(PINB & 0b00000010))	//нажата кнопка "-" первого канала	    
 #define BTN2_UP (!(PINB & 0b00000100))	//нажата кнопка "+" второго канала
#define BTN2_DWN (!(PINB & 0b00001000))	//нажата кнопка "-" второго канала
   #define ENABLE (PINB == 0b11111111)	//на всякий случай - "разрешение приращения"

  #define PWM1_ON (PORTD |= 0b00000001)	//первый канал включён
  #define PWM2_ON (PORTD |= 0b00000010)	//первый канал включён
Я же не знаю, каким будет код...
Последнее редактирование: 3 года 6 мес. назад от plis.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #6 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Буду не оригинален, повторю свой излюбленный лозунг: делай, как проще!

Я предлагаю вам не стремиться наделить макросы какой-то функциональностью, а пока что ограничиться минимумом - магическими числами. Попытайтесь осмысленно избавиться от них - и всё. Не надо делать макрос "нажата кнопка", сделайте макрос "кнопка". Потом, если потребуется, из этих простых макросов соберете более сложные... а может быть, станет понятно, что это лишнее.

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

я не ленивый, я энергосберегающий...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #7 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Заминка вышла.
По моему, я в дифайнах неправильно битовые операции написал.
Завтра после работы вопросы появятся...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #8 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Пытаюсь осознать проблему.

1. Организация бесконечного цикла "portOn-portOff.
2. Определение момента включения или выключения - это как нравится.
3. Организация управления моментом включения или выключения.

Правильно?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #9 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н

1. Организация бесконечного цикла "portOn-portOff.
2. Определение момента включения или выключения - это как нравится.
3. Организация управления моментом включения или выключения.

Насколько я понял, вы желаете формировать ШИМ не аппаратно, не по прерываниям, а в главном цикле. Ок, это можно при низких требованиях к качеству ШИМа (к стабильности периода и скважности импульсов).

Но почему вы решили, что ШИМ формируется путем включения и выключения портов? Формально это так, но получается не ДВУМЯ операциями, а ОДНОЙ: ОБНОВЛЕНИЕМ состояния портов!

Когда я набросал главный цикл вашей программы парой постов ранее, я не зря написал

// подготавливаем данные для порта
// выводим эти данные в порт

одна команда вывода, но до нее - подготовка. В момент обновления те линии порта, что должны упасть в 0 - упадут в него одновременно с тем, как поднимутся в 1 те, которые должны это сделать! Даже если у вас будет 8 каналов ШИМ - все они одновременно изменят свое состояние. Это решает и проблему с управлением моментом включения/выключения: он всегда будет в одном и том же месте главного цикла...

Улавливаете? ;)

я не ленивый, я энергосберегающий...
Последнее редактирование: 3 года 6 мес. назад от ARV.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #10 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
После того, как вы намекнули открытым текстом - улавливаю.)))

Всё гениальное - просто.
Я обратил, конечно, внимание на необычное слово, но - "ниасилил".(
Последнее редактирование: 3 года 6 мес. назад от plis.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #11 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Это ничего, со временем пройдёт :)

я не ленивый, я энергосберегающий...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #12 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
int tmp=0;
		 
	while(1)
	{							
		
		
		if(cntr<=on0){				// подготавливаем данные для порта
			tmp |= (0b00000001); 	
		}
		if(cntr<=on1){
			tmp |= (0b00000010);	// подготавливаем данные для порта		
		}							
		if(cntr>on0){
			tmp &= (0b11111110);	// подготавливаем данные для порта
		}
		if(cntr>on1){
			tmp &= (0b11111101);	// подготавливаем данные для порта
		}
		PORTD = tmp;				// выводим  эти данные в порт

Понятно, что без магических чисел будет лучше, но направление верное?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад #13 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Направление верное, но все-таки вы торопитесь... Вы очень спешите превратить мысли в код, не применяя принцип нисходящего программирования... Возможно, из-за спешки вы и алгоритм продумать не успеваете. Код - последнее дело, сначала надо разобраться с алгоритмом.

Вот для чего у вас для каждого порта проверяется 2 условия - для включения и для выключения? ШИМ организуется так: в начале периода ШИМа все каналы выключены, а включаются они в какой-то другой момент. То есть выходит, что для выключения никаких проверок делать не надо, это безусловное действие в начале периода ШИМ. Остается только понять, как это начало отследить.

И вот что я предлагаю: воспользоваться тем, что если однобайтовую переменную на каждой итерации цикла увеличивать на 1, то после значения 255 она получит автоматически значение 0... И смотрите, какой финт ушами получается: мы сравниваем значение этой переменной с заданной скважностью канала... Если заданная скважность больше, чем значение переменной, включать канал еще рано... А если меньше - надо включать...

я не ленивый, я энергосберегающий...

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #14 от plis
plis ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Согласен. Тороплюсь.

Но и вы торопитесь подсказать.)
Я как-раз думал мысль про "одна за всех". Не скажу, что я её успел ясно сформулировать, но она была.)

P.S. Я со скважностью не очень.(
Сколько раз пытался запомнить что это - период/импульс или импульс/период, столько раз и забывал...
Последнее редактирование: 3 года 6 мес. назад от plis.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Больше
3 года 6 мес. назад - 3 года 6 мес. назад #15 от ARV
ARV ответил в теме Re: Разработка программной ШИМ для управления двумя ДПТ на основе статьи "Н
Извините за мою поспешность :blush:

Рассматривайте скважность, как процент "мощности" сигнала: если он постоянно 1 - это 100%, если постоянно 0 - 0%, ну при других значениях - пропорционально...

я не ленивый, я энергосберегающий...
Последнее редактирование: 3 года 6 мес. назад от ARV.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Работает на Kunena форум