сколько задач одновременно может решать АТМЕГА УНО

Alexsandr
Offline
Зарегистрирован: 24.02.2019

У Атмега 328 Уно  есть три таймера.  два -8 битных  и один 16 битный. В установки первого таймера лучше не вмешиваться, он связан с тактами процессора. Установки (второго) 16 битного можно менять для оптимизации ШИМ.      Я на нем собрал ШИМ генератор  "Fast PWM mode14"      Третий таймер, как говорится, к вашим услугам...  

Вышесказанное мною - это мое мнение..и оно под сомнением. 

 Хочу узнать мнение Гуру ---я прав или заблуждаюсь?

Почему у меня возник сей вопрос?  Если я на 16 битном таймере сделал ШИМ-генератор, я им доволен,....и не хочу, чтоб какие-то "прерывания"  в другом процессе испортили красоту его работы,  могу ли я на оставшемся таймере  собрать устройство которое будет с помощью шагового двигателя двигать задвижку воздуховода в зависимости от температуры?

Наверное... в общем, вопрос такой:  позволят ли АТМЕГА УНО собрать: независимый Генератор ШИМ,    и производить управление шаговым двигателем  по показаниям аналоговых датчиков?

 

PRC
Offline
Зарегистрирован: 03.02.2019

После запуска таймера на генерацию он становится полностью автономен и программа никак ему мешать не будет. Если не полезет в его регистры конечно.

sadman41
Offline
Зарегистрирован: 19.10.2016

Одновременно MK ATMega328 умеет выполнять ОДНУ задачу, если речь идет об обслуживании вычислительных процессов пользователя. Но он так же умеет красиво лежать на столе, что можно считать поставленной перед ним задачей. В таком случае одновременно выполняется две задачи.

Ответ на вопрос: МК не препятствует созданию вышеозначенной задачи, успех которой в большей мере зависит от перифирии и талантов создателя прошивки.

b707
Offline
Зарегистрирован: 26.05.2017

Alexsandr пишет:

Наверное... в общем, вопрос такой:  позволят ли АТМЕГА УНО собрать: независимый Генератор ШИМ,    и производить управление шаговым двигателем  по показаниям аналоговых датчиков?

Каждый таймер генерит свое прерывание. Два прерывания не могут выполнятся одновременно. Так что когда в какой-то момент прерывания от обоих таймеров совпадут - одно из них будет выполненно с задержкой. При правильном программировании можно свести эту задержку к минимуму (микросекунды или даже наносекунды). Но полностью независимыми они быть не могут.

А уж насколько критичны такие взаимные влияния в конкретном алгоритме - решать только вам.

PRC
Offline
Зарегистрирован: 03.02.2019

Для работы ШИМ прерывания не нужны.

b707
Offline
Зарегистрирован: 26.05.2017

PRC пишет:

Для работы ШИМ прерывания не нужны.

ДА? - честно, не знал....

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, это, кстати, ещё вопрос - как этот ШИМ реализован ТС. Может он на ISR таймеру подвесился и за ноги дёргает врукопашную.

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Ну, это, кстати, ещё вопрос - как этот ШИМ реализован ТС. Может он на ISR таймеру подвесился и за ноги дёргает врукопашную.

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

Буду признателен, если кто-нибудь меня поправит.

 

PRC
Offline
Зарегистрирован: 03.02.2019

b707 пишет:

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

Буду признателен, если кто-нибудь меня поправит.

Код не мой и на просто С, но по нему хорошо видно, что для работы шим прерывания не нужны. В цикле меняют скважиность, если она постоянная, то основной цикл можно сделать пустым.

#include <avr/io.h>//библиотека ввода/вывода
 
//Програма задержки
void pause (unsigned int a)
{ 
unsigned int i;
for (i=a;i>0;i--);
}
 
//Програма инициализации ШИМ
void init_pwm (void)
{
  TCCR1A=(1<<COM1A1)|(1<<WGM10); //На выводе OC1A единица, когда OCR1A==TCNT1, восьмибитный ШИМ
  TCCR1B=(1<<CS10);		 //Делитель= /1
  OCR1A=0x00;			//Начальная яркость нулевая
}
 
//Основная програма
int main(void)
{ unsigned char i;
 
 DDRB=0x02;   			//Инициализация PB1 (OC1A) как выход
 init_pwm();
 
 while (1)
  { 
    for (i=0;i<255;i++)		//Плавно повышаем яркость 
	 {OCR1A++; pause(1000);}
    for (i=0;i<255;i++)		//Плавно понижаем яркость
	 {OCR1A--; pause(1000);}
  } return 1;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

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

- если что, я не наезжаю, просто спрашиваю.

sadman41
Offline
Зарегистрирован: 19.10.2016

Это лучше димакс расскажет. Я помню, что вроде есть режим таймера, при котором МК сам ноги включает/выключает на переполнениях.

http://arduino.ru/forum/programmirovanie/pereklyuchenie-bitnosti-pwmshim...

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Это лучше димакс расскажет. Я помню, что вроде есть режим таймера, при котором МК сам ноги включает/выключает на переполнениях.

тут все упирается в вопрос - нужны для этого режима прерывания или нет.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

 

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

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

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

По-моему единственный независимый механизм в 328-м камне - это WTD, остальное всё так же выполняется на основном ядре. Так что хоть на такт, но стоит ожидать задержки. Другое дело, что для шаговика это вообще не будет заметно.

arduinec
Offline
Зарегистрирован: 01.09.2015

b707 пишет:

sadman41 пишет:

Я помню, что вроде есть режим таймера, при котором МК сам ноги включает/выключает на переполнениях.

тут все упирается в вопрос - нужны для этого режима прерывания или нет.

http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-bl...

PRC
Offline
Зарегистрирован: 03.02.2019

Залейте этот скетч и посмотрите осциллографом меандр на 9 ноге контроллера. И сразу будет ясно нужны прерывания или нет))

void setup() {
  pinMode(9, OUTPUT); 
  TCCR1A=(1<<COM1A1)|(1<<WGM10);
  TCCR1B=(1<<CS10);
  OCR1A=0x80; 
}
void loop() {
}

Уже опередили с ответом)))

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

b707 пишет:

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

Таймер устройство самодостаточное, ему не нужны прерывания что-бы что-то сравнить или поднять/опустить ногу. Эдакий контроллер в контроллере.  Собссно и прерывать МК в полном смысле слова он не может, просто поднимает бит в регистре TIFR при совпадении счётчиков и в конце счёта, причём поднимает вне зависимости нужно нам это было или не нужно, т.е. теребит этот регистр всегда.  А прерывание МК произведёт только если такой-же бит поднят в регистре TIMSK.  Словно МК производит логическую операцию "AND" между этими двумя регистрами. TIFR&TIMSK =  Если в результате "1" -то МК прыгает в нужный адрес.

nik182
Offline
Зарегистрирован: 04.05.2015

Вы мух от котлет отделяйте. Надо разделять выставление прерывания и генерация. При разрешённом прерывании будет генериться и вызываться. Даже если нет пользовательского. В этом случае просто будет срабатывать заглушка и время на прерывание будет тратиться по полной. Если прерывание запрещено будет выставлятся флаг в регистрах таймера и его даже можно прочитать и сбросить но прерывания не будет. 

b707
Offline
Зарегистрирован: 26.05.2017

dimax пишет:

Таймер устройство самодостаточное, ему не нужны прерывания что-бы что-то сравнить или поднять/опустить ногу. Эдакий контроллер в контроллере....

dimax

Спасибо огромное.

nik182 - и Вам тоже

Alexsandr
Offline
Зарегистрирован: 24.02.2019
dimax пишет: вот  универсальный PWM генератор.
1 void setup() {
2 pinMode(9,OUTPUT);
3 TCCR1A=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM11);
4 TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10); //mode14 FastPwm
5 ICR1=65535;
6 OCR1A=32767;
7 }
8  
9 void loop() {}

Регистром ICR задаёте до скольки считать(частота), регистром OCR1A задаёте на каком такте задирать лапу (скважность). Значения в скетче -частота 244 Герц,  разрядность ШИМ 16 бит, дьюти 50%.  

Здесь ведь нет прерываний?

Это же аппаратная генераця ШИМ?   Здесь ведь частота и скважнсть задаются апаратно - с помощью настроек регистров на определенные действия?

Подтвердите мои предположения  я и буду самым счастливым человком! 

 Ибо (я так думаю!) я смогу на  остальных ресурсах МК програмно замутить АЦП  для управления шаговым двигателем . Т.е у меня будет 1-процесс: генерация ШИМ на "регистрах",  и второй - программа управления шаговым двигателем от АЦП.  И они будут независимые.  И если в  программе управления шаговым двигателем  посрдством АЦП будут прерывания - они не будут влиять на мой "регистровый" генератор ШИМ.

С уважением!

Alexsandr
Offline
Зарегистрирован: 24.02.2019

sadman41 пишет:

Ну, это, кстати, ещё вопрос - как этот ШИМ реализован ТС. Может он на ISR таймеру подвесился и за ноги дёргает врукопашную.

Да - да!

Alexsandr
Offline
Зарегистрирован: 24.02.2019

b707 пишет:

Alexsandr пишет:

Наверное... в общем, вопрос такой:  позволят ли АТМЕГА УНО собрать: независимый Генератор ШИМ,    и производить управление шаговым двигателем  по показаниям аналоговых датчиков?

Каждый таймер генерит свое прерывание. Два прерывания не могут выполнятся одновременно. Так что когда в какой-то момент прерывания от обоих таймеров совпадут - одно из них будет выполненно с задержкой. При правильном программировании можно свести эту задержку к минимуму (микросекунды или даже наносекунды). Но полностью независимыми они быть не могут.

А уж насколько критичны такие взаимные влияния в конкретном алгоритме - решать только вам.

(Горбачев-Ельцину):   Борис. ты не прав! Коммунисты думают не так!

С уважением!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

(Ельцын - Горбачеву): Панимаешь ли Alexsandr .. тут такое дело .. в общем, смотря что панимать пад задачей: Если это работа железяки (периферии) микроконтроллера, то в общем-та, оно могет работать вполне автономно, в частности таймеры. Задал режим в регистрах, он его и шпарит. В общем-та и Т0, с его millis() никуда не вперся. Его точно также можно пользовать, только "время" учитывать придется самостоятельно, опять же, ежели оно надо. Остальная часть периферии .. тоже способна работать в полуавтономном режиме по прерываниям: интерфейсы I2C, UART, SPI .. все это можно юзать в режиме "послал и забыл". Да даже и АЦП можна!

Тут ключевой вопрос: что считать "задачей". Можно даже на базе watchdog сваять вытесняющую многозадачность и имитировать "потоки" больших машин со всеми ихними симафорами, мутиксами и т.д. Главное чтобы .. не не памяти .. тяму хватало! 16Mips это практически IBM PC AT без сопроцессора.

Успехов. :)

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А что такое вообще одновременность? При расстоянии между ножками микропроцесоора 1мм это где-то 3.3*10**-12 секунды, но учитывая длину проводников можно принять 10**-11 секунды. Это, наверное, максимальная одновременность этого мира. А Вам какая нужна?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ему нужна другая. Более одновременная, чем 10вминус11-й

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

DetSimen пишет:

Ему нужна другая. Более одновременная, чем 10вминус11-й

Я стормозил где-то на порядок - в вакууме скорость света взял. 10 в минус 10

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Можно, канеш, и мьютексы с семафорами замутить, да стек ахудеет. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

DetSimen пишет:

Можно, канеш, и мьютексы с семафорами замутить, да стек ахудеет. 

Не, ему нада оптический процессор замутить на брульянтах

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Вопщем, задачи должны переключаться быстрее, чем эликтрон с s орбиты на p перескакивает. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Нада кварец пабольше. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

DetSimen пишет:

Нада кварец пабольше. 

Не - а , мы электрон на протон заменим и опаньки - все получится! Токма кварц от электронов защитить нада...

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

И, кстати:

- "Виртуальность этого мира не вызывает сомнения, поскольку есть люди (типа ТС), которые задаются вопросом одновременности процессов" - самоцитата.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

mykaida пишет:

Не - а , мы электрон на протон заменим и опаньки - все получится!

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

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Jeka_M пишет:

mykaida пишет:

Не - а , мы электрон на протон заменим и опаньки - все получится!

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

Да ладно - неуж-то в Сколково за нормальный откат нельзя пару милиардов штук зиметь?

Alexsandr
Offline
Зарегистрирован: 24.02.2019

Констатирую, с улыбкой от уха до уха:  с всязи с отсутствием в продаже сободных протонов и нейтрино -ТЕМА ЗАКРЫТА.

Всем большой спасибо и легкого кода!       С уважением!

Green
Offline
Зарегистрирован: 01.10.2015

nik182 пишет:

Вы мух от котлет отделяйте. Надо разделять выставление прерывания и генерация. При разрешённом прерывании будет генериться и вызываться. Даже если нет пользовательского. В этом случае просто будет срабатывать заглушка и время на прерывание будет тратиться по полной. Если прерывание запрещено будет выставлятся флаг в регистрах таймера и его даже можно прочитать и сбросить но прерывания не будет. 

Какого пользовательского, какая заглушка, какой по полной? Бредите или пятница?

nik182
Offline
Зарегистрирован: 04.05.2015

Может быть iret что сидит по адресам 0х0014-0х001А для первого таймера? 

anatoli_nik
Offline
Зарегистрирован: 17.01.2019

Цитата:
Какого пользовательского,

Разрешил прерывание, а обработчик написать забы(и)л.

Цитата:
какая заглушка,

Так называемый "BADISR_vect", который, если его не использовать (то есть не написать обработчик), будет перекидывать на нулевой адрес FLASH, т.е. на вектор RESET.

Цитата:
будет срабатывать заглушка и время на прерывание будет тратиться по полной.

Хрен там, будет переинициализация контроллера.

sadman41
Offline
Зарегистрирован: 19.10.2016

Считаю, что закрывать не стоит. Вопрос продолжил существовать вне зависимости от интереса топикстартера.

Green
Offline
Зарегистрирован: 01.10.2015

По неиспользованным векторам GCC ставит bad_interrupt (jmp 0), со всеми вытекающими.
Вот и включайте прерывания "по полной программе."

nik182
Offline
Зарегистрирован: 04.05.2015

А если так:General options->System->Initialize unused interrupts vectors with RETI= TRUE ?

Как настроим так и поедем. Но в изначальном случае вы правы. 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Я всегда предполагал, что вектор прерывания направлен в мою душу.  А тут я получил энтому полное подтверждение...

Green
Offline
Зарегистрирован: 01.10.2015

nik182 пишет:

А если так:General options->System->Initialize unused interrupts vectors with RETI= TRUE ?

Как настроим так и поедем. Но в изначальном случае вы правы. 

Это в IAR? Но он то здесь каким боком?

nik182
Offline
Зарегистрирован: 04.05.2015

Я начинал програмировать avr когда ардуины ещё не было. А iar был. Знания работы железа с тех пор. Всегда функция reti была включена чтобы не сбрасываться при отладке. Новые времена - новые нравы. 

Green
Offline
Зарегистрирован: 01.10.2015

Даже если вы умудритесь поставить заглушку в векторе (с GCC это не просто), все равно время исполнения будет совсем не по полной - вызов и сразу же возврат. Если же оформите даже пустой обработчик, тогда уже будет минимальный пролог/эпилог. А по полной будет когда в обработчик вставите функцию - получите приличную портянку кода.

anatoli_nik
Offline
Зарегистрирован: 17.01.2019

Цитата:
Если же оформите даже пустой обработчик, тогда уже будет минимальный пролог/эпилог.

А кто мешает так:

void setup()
{
  
}
void loop()
{
  
}
ISR(BADISR_vect, ISR_NAKED)
{
 reti(); 
}

 

Green
Offline
Зарегистрирован: 01.10.2015

Никто. Вот это и есть пустой обработчик. Там даже reti не нужен. Читайте то что процитировали. Но вы уже фишки GCC начали использовать. 

anatoli_nik
Offline
Зарегистрирован: 17.01.2019

Цитата:
Читайте то что процитировали.

Читаю:

Цитата:
Даже если вы умудритесь поставить заглушку в векторе (с GCC это не просто), 

Цитата:
Если же оформите даже пустой обработчик, тогда уже будет минимальный пролог/эпилог.

Для этого и есть параметр ISR_NAKED

Цитата:
Вот это и есть пустой обработчик. Там даже reti не нужен.

А вот фиг там, нужен. Цытата из справочника AVR-libc:

Цитата:
#define ISR_NAKED

ISR is created with no prologue or epilogue code. The user code is responsible for preservation of the machine state including the SREG register, as well as placing a reti() at the end of the interrupt routine.

К тому же не поленился дизассемблировать код с RETI(); и без. Если самому не написать RETI(); то после обработчика программа пойдет по следующему адресу за обработчиком.

Цитата:
Но вы уже фишки GCC начали использовать.

Так они же входят в стандартный комплект ArduinoIDE.

П.С. Вопрос стоял в том что же делать с "нежданчиком" (незапланированным прерыванием), чтобы не сбрасывался контроллер. Выше приведенное решение самое простое для arduinoIDE.

П.П.С. Забыл я чето, про еще более простое решение, всего одна строчка:

EMPTY_INTERRUPT(BADISR_vect);
Green
Offline
Зарегистрирован: 01.10.2015

Не, не, не. Я спорить с вами не буду. Потому что вы свегда правы. Кто захочет, тот почитает историю из за чего спор. И сделает выводы. Удачи!