Jump to content
parovoZZ

Философия аппаратного SPI - чем занять МК?

Recommended Posts

1 час назад, parovoZZ сказал:

В любом другом случае эффективнее самим опрашивать аппаратный флаг счетчика и самим же его сбрасывать.

Если в программе нет ничего, кроме опроса флага, то эффективнее. В противном случае нет.

 

1 час назад, parovoZZ сказал:

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

Что-то я не пойму, про какие дублирующие флаги идет речь. Есть у нас тот же UART. Временами по нему прилетают данные которые МК обрабатывает и как-то на них отвечает. Все остальное время он занят другой работой. По приходу данных МК вываливается в прерывание, забирает байт из регистра, кладет его в буфер, сбрасывает счетчик времени ожидания, запускает таймер который будет ждать окончание конца пакета и продолжает делать свою работу. Дальше, если таймер дотикал до определенного времени, значит пакет закончился и можно его обработать. Т.е. нам надо, как минимум, мониторить два флага наличие данных в буфере UART и событие от таймера, время срабатывания которого пара микросекунд. И как это делать без прерываний? Ну и надеяться в написании программ ни на что нельзя, все должно быть четко и структурировано.

Share this post


Link to post
Share on other sites
6 минут назад, BARS_ сказал:

И как это делать без прерываний?

Я где-то писал, что это надо делать без прерываний? Вопрос был про флаги.

Share this post


Link to post
Share on other sites
1 час назад, parovoZZ сказал:

Что мешает точно также опросить аппаратный флаг?

Например то, что в одном прерывании можно выставлять разные флаги. Есть, к примеру, таймер. Тикает пусть раз в 100мс. Прописываем ему счетчики, которые будут досчитывать в разное время. Пусть будет 500мс, 1с, 5с. По счетчикам выставляем флаги, которые будут мониториться в главном цикле и по которым будут выполняться операции некритичные к времени. Или если вернуться к UART, пусть МК принимает большой пакет данных, например от GPS приемника в NMEA формате. Затем он их парсит для получения требуемых параметров. Алгоритм приема будет примерно такой:

  1. Упали в прерывание
  2. Приняли байт
  3. Положили в буфер
  4. Обнулили счетчик времени
  5. Пнули таймер
  6. вышли из прерывания

В конце концов пакет закончится и будет иметь размер байт 100. Таймер дотикает, выставит программный флаг о готовности пакета и вырубится. Как только МК освободится, он увидит флаг и займется парсингом пакета. при этом все другие прерывания останутся активными. А вот если кинуться парсить пакет сразу в прерывании таймера, то прерывания будут заблокированы до конца парсинга (не все, только более с более низким приоритетом). 

Share this post


Link to post
Share on other sites

Вебинар STM32G0 – новый лидер бюджетных 32-битных микроконтроллеров от STMicroelectronics

Компания Компэл приглашает вас 25 сентября принять участие в вебинаре, который посвящен новому семейству микроконтроллеров STM32G0. Вебинар рассчитан на технических специалистов и тех, кто хорошо знаком с семейством STM32. На вебинаре будут освоены современные методы тестирования производительности микроконтроллеров на примере самых бюджетных 32-битных семейств общего назначения STM32G0 и STM32F0 и проведено их подробное сравнение.

Подробнее

да о чем речь) может быть ситуация когда флаг не нужен, может быть когда нужен) может быть когда флага вообще нет)

моет быть когда в схеме нет мк :)

Share this post


Link to post
Share on other sites
3 минуты назад, BARS_ сказал:

Есть, к примеру, таймер. Тикает пусть раз в 100мс. Прописываем ему счетчики, которые будут досчитывать в разное время. Пусть будет 500мс, 1с, 5с.

У счетчика же есть цифровые компараторы? Или есть МК, в которых их нет? К черту такой МК. Выставляем значение, которое нам нужно и всё. А дальше хоть флаг компаратора опрашивай, хоть в прерывание уходи. Зачем усложнять себе жизнь?

Вот у меня работает АЦП, а также есть PCINT прерывание. Когда я ничего не делаю, я либо в IDLE, либо ADC_NOISE. Вот тут мне без доп флагов никак, т.к. обработчики прерываний совершенно пустые. А без них никак - тупо по флангам МК не просыпается. Для флага я использую регистр GPIOR.

 

Share this post


Link to post
Share on other sites
                     

Литиевые батарейки Fanso в беспроводных датчиках пожарно-охранной сигнализации

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

Подробнее...

43 минуты назад, parovoZZ сказал:

У счетчика же есть цифровые компараторы?

При чем тут компараторы (и не компаратор, а регистр сравнения)? Один таймер будет формировать только один клок, а с помощью флагов я могу получить с него хоть десяток. Смысл мне тупо для формирования временных интервалов крутить десяток таймеров?

Edited by BARS_

Share this post


Link to post
Share on other sites
26 минут назад, BARS_ сказал:

и не компаратор, а регистр сравнения

Output Compare Units, как гласит даташит для младших AVR.

26 минут назад, BARS_ сказал:

крутить десяток таймеров?

Зачем десять? Достаточно одного. Я так с вачдогом забавляюсь, когда надо выдерживать разные периоды времени.

Share this post


Link to post
Share on other sites
2 минуты назад, parovoZZ сказал:

Зачем десять? Достаточно одного. Я так с вачдогом забавляюсь, когда надо выдерживать разные периоды времени.

Менять регистр сравнения таймера не вариант. Все клоки должны идти все время.  И 100мс, и 500мс и любые другие.

Share this post


Link to post
Share on other sites
16 минут назад, BARS_ сказал:

Все клоки должны идти все время.  И 100мс, и 500мс и любые другие.

Тогда Attiny 861 в помощь =)

Share this post


Link to post
Share on other sites
57 минут назад, BARS_ сказал:

пусть МК принимает большой пакет данных, например от GPS приемника в NMEA формате. Затем он их парсит для получения требуемых параметров. Алгоритм приема будет примерно такой:

Для маломерок типа AVR ваш алгоритм в чистом виде не подойдет. GPS выпихивает слишком много данных, чтобы их все принять в буфер, а потом парсить. Великоват буфер будет, а ОЗУ мало. В конкретном случае с NMEA надо алгоритм модфицировать: в прерывании ждать начала того пакета, который нужен, и затем принимать в буфер уже только его - так буфер будет короче во много раз. Но  это нюансы, конечно.

Share this post


Link to post
Share on other sites

При чем тут тини вообще? Речь идет про любой МК. Таймеры работают +/- одинаково везде, по крайней мере базовые функции. Речь про то, что один таймер может выставлять флаги для десятка событий. Например:

  • Каждые 100 мс опрос кнопок
  • Каждые 200 мс обновление дисплея, если есть соответствующие данные
  • Каждые 500 мс мигать светодиодом (или толпой светодиодов)
  • Каждую 1с отсылать данные по тому же ЛАН
  • и т.д. и т.п.

Задействовать под каждое событие отдельный таймер как минимум нерационально, поэтому ставятся программные флаги и все. А таймер просто вываливается в прерывание каждые 100 мс и все.

4 минуты назад, ARV сказал:

Для маломерок типа AVR ваш алгоритм в чистом виде не подойдет

Верно, но с ними я уже давно завял в силу их убогости:crazy: Так да, можно ждать нужный пакет, но это не сильно удобно, т.к. начала пакетов очень похожи и проверку заголовка надо делать по 3-4 символам, следующим друг за другом. А на STM я спокойно могу принять пакет размером хоть 1024 байт без ущерба для ОЗУ. 

Share this post


Link to post
Share on other sites
10 часов назад, DrobyshevAlex сказал:

Разве в прерывании аппаратный не сбросится? ну точнее после прерывания?

Смотря о чем вы говорите. Флаг переполнения - НЕ СБРОСИТСЯ, но выставленный этим флагом флаг прерывания - он СБРОСИТСЯ при входе в обработчик прерывания, при этом флаг переполнения не будет тронут.

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

Share this post


Link to post
Share on other sites
1 час назад, Alexeyslav сказал:

флаг прерывания

естественно о нем, речь же была о том зачем ставить свой флаг по прерыванию если есть аппаратный флаг прерывания)

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
В 21.01.2019 в 19:51, ARV сказал:

// правильный подход - минимальное ожидание uint8_t spi(uint8_t d){ while(!(SPSR & (1<<UDRE)); uint8_t res = UDR; UDR = d; return res; }

Вот здесь косячокс - если в регистре ничего нет, то и работать не будет.

Share this post


Link to post
Share on other sites

Нет никакого косячка: кода UDR пуст, бит UDRE всегда установлен.

Share this post


Link to post
Share on other sites

На32u4 на этой проверке все и застряло почему-то. Пока разбираться некогда.

Share this post


Link to post
Share on other sites
В 10.02.2019 в 09:41, ARV сказал:

Нет никакого косячка: кода UDR пуст, бит UDRE всегда установлен.

Что-то я тупанул. Это же речь про UART/ А тема вроде про SPI.

Ну раз такие дела, то придется UART в качестве SPI погонять)

Edited by parovoZZ

Share this post


Link to post
Share on other sites

С SPI то же самое. Вероятно, тупанул и я, назвав не тот регистр и флаг, но все идентично. Правда, с точностью до наоборот: если есть флаг - пусто, и можно писать.

	for(uint8_t i=0; i < CNT; i++){
		while(bit_is_clear(SPSR, SPIF));
		SPDR = *data++; 
	}

Вот таким кодом 100 лет пользуюсь - как видите, ждем флаг SPIF, и как встал - пихаем :) Прям по жизни все.

Share this post


Link to post
Share on other sites

Хочу вернуться к нашим баранам.

В 13.02.2019 в 13:54, ARV сказал:

ждем флаг SPIF, и как встал - пихаем

В новых тинях

в блоке SPI есть буферы на передачу и прием. То бишь данные вида "команда & байт данных" можно пропихнуть за один присест - команда попадает в буфер и сразу уходит в сдвиговый регистр (если он свободен). Её место на следующем такте занимает байт данных. Далее всё произойдет на автомате. Выходим из функции. И всё в этом алкоритме хорошо, если бы не одно НО! Пин выбора устройства. Есть два варианта - остановить проц и подождать прерывания, после чего "отпустить" устройство. Либо же пойти по своим делам и уже в прерывании поднять ногу. В последнем варианте иметь буферы в SPI не обязательно - можно организовать и в нормальном режиме. Но стоит ли? Уход на прерывание занимает 3 такта. Возврат из него тоже 3 такта. Итого - 6 тактов накладных расходов. Отправить данные, если блок SPI тактируется на максимуме - занимает 16 тактов или 32 в буферном режиме. Вариант с ожиданием в IDLE интересен энергопотреблением. Вариант с прерыванием - быстродействием. Стоит ли игра свеч, ведь вырастают грабли на ровном месте:

1. Необходим какой-то флаг занятости устройства (устройств может быть не одно). Если одно, то можно контролировать флаги SPI. Как правило, выбор устройства означает, что сейчас на линии будет выставлена команда. Если мы "просахатим" "передёр" устройства, то наступит катаклизм.

2. Код получается платформозависимым. Если сейчас у меня платформозависимый только SPI.h (сменил его и с драйверами высшего уровня можно работать на любой другой 8-ми битке), то с прерываниями под каждую платформу придется переписывать не только SPI.h.

3. И совсем не красивый код получается, если мы запрашиваем у устройства какие-то данные. 16 тактов на отправку, 6 тактов накладных расходов = 10 тактов свободных. Стоит ли оно того?

3а. Ну и получается, что аппаратный SPI перед USI каких-то преимуществ не дает. В здравом уме никто искусственно занижать скорости на интерфейсе не будет, а на предельных скоростях USI даёт то же быстродействие.

Share this post


Link to post
Share on other sites
Только что, parovoZZ сказал:

Но стоит ли?

Новые тиньки не изучал, по вашим статьям сложилось впечатление, что прерывание как было по окончанию передачи байта, так и осталось. Оттого и проблемы. А ведь по идее должно быть еще прерывание по опустошению буфера - оно более полезно в данном случае (кстати, для USART как и есть, хоть и буфер всего 1 байт, вроде). То есть напихали в буфер данных на передачу и пошли по делам. Если буфер хотя бы на 4 байта - это уже много тактов, и затраты на обработчик прерывания менее заметны.

Share this post


Link to post
Share on other sites
4 минуты назад, ARV сказал:

прерывание как было по окончанию передачи байта, так и осталось.

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

7 минут назад, ARV сказал:

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

увы, только 1 байт.

 

Сейчас переписал код под буферный режим и с ожиданием в IDLE до момента, когда можно отпустить устройство. Хоть и работает, но нет лаконичности в коде...

Share this post


Link to post
Share on other sites
Только что, parovoZZ сказал:

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

Чувствуется тлетворное влияние архитекторов Микрочипа :) У них с древних времен повелось источник прерывания поллингом выяснять (если не ошибаюсь). Или разработчикам платят за количество фич. Смысл такого "изобилия" для столь небыстрых микроконтроллеров вообще не понятен. Нет, когда мы SPI гоняем на скорости 100 бод (при тактовой 20 МГц) - вопросов нет :) Но разве кому-то надо работать медленно?!

Share this post


Link to post
Share on other sites
47 минут назад, ARV сказал:

Смысл такого "изобилия" для столь небыстрых микроконтроллеров вообще не понятен. Нет, когда мы SPI гоняем на скорости 100 бод (при тактовой 20 МГц) - вопросов нет :) Но разве кому-то надо работать медленно?!

Так вот умел бы SPI аппаратно заруливать пином выбора устройства - было бы вопросов меньше. А так или на таймер его вешать или же в прерывании с ним работать.

Share this post


Link to post
Share on other sites
Posted (edited)
Только что, parovoZZ сказал:

Так вот умел бы SPI аппаратно заруливать пином выбора устройства

Это надо, чтобы искусственный интеллект в нем был :) Как узнать, когда "заруливать" этим пином? Для SD-карты это может быть спустя сотни две байтов, а для какого-нибудь датчика спустя один байт, а дисплею надо шестнадцать... Это известно только программисту, и не является какой-то константой.

Edited by ARV

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By parovoZZ
      AREF  - внутренний ИОН 1.1в
      Вот такой код снятия результатов:
      temp = ADC; if (ADCH & (1<<ADCH1)) // Если значение отрицательное { temp |= 0xFC00; temp = (~temp) + 1; } Value_current_lsb = (uint8_t)(temp >> 2); Никак не пойму - на выбранные дифф. входы надо подать 85 мВ, чтобы АЦП выдал 0. Но это могу списать на внутренний ОУ в виде УГ. Если подаю  -1,1 в - то получаю 127.  Здесь все верно. Но при подаче положительного смещения те же 127 получаю уже при 0,72в. Что за ерунда? Неужели ОУ на столько УГ? Либо же где-то теряется разряд?
    • By parovoZZ
      Ну, собственно, сабж. Питание - от 2.4 и до 3.6. На сигнальном выводе необходима половина напряжения питания (по постоянке, разумеется).
    • By parovoZZ
      Не секрет, что адресация глобальных переменных прямая, а переменных в стеке - косвенная. Стек в AVR программный, то бишь откусывается от ОЗУ. Так вот вопрос - при передаче в функцию (и обратно) больших объемов данных (которые невозможно передать через РОН) все же что будет производительнее - через глобальные переменные или через параметры? Понятно, что в функцию вида
      uint8_t My_super_function (uint8_t data); переменные уйдут через РОН,  а вот в такую
      void My_super_function (uint8_t *data, uint8_t *ret); через стек? Так может ну его нафик, стек этот?
    • By parovoZZ
      Поставил LUFA, следом абсолютно не нужный мне ASF. Но в упор не понимаю - как создать проект на базе этой библиотеки из студии? Приходится вручную копировать папку с заголовочниками LUFA, прописывать пути в makefile, лишние телодвижения по добавлению папки в свойства проекта. Если я это делаю всё вручную, то тогда для чего это расширение? Примеры я могу и так покрутить. ЗЫ - не слишком высокий скилл в юзании Atmel Studio/
  • Сообщения

    • Никакого КЗ не будет, не надо народ пугать! Транзистор откроется ровно настолько, чтобы забрать только зарядный ток, ни грамма больше
    • Походу ерунду я написал, но удалить сообщение не получается)) Т.к при увеличении сопротивления нагрузки LC фильтр наоборот становится более громоздким
    • Который родился ближе к нулевым. Или у которых нет таких помоек. Не, cо стороны производителей телевизоров. Ток подсветки задран сильно, того и горят.
    • Встречалось такое решение. Как-то попадался такой БП FSP в ремонт. Производитель входной помехо-подавляющий конденсатор, который в основном включают между фазой и нулём разбил на две части и включил на заземляющий входной контакт как фазу, так и ноль. Вообще то, это самое правильное решение. Но оно будет эффективным, если в сетевой розетке присутствует заземление. Но как Вы знаете, в жилых домах оно не всегда присутствует, и приходится довольствоваться только фазой и нулём. Припаянные конденсаторы на входном разъёме встречались только один раз. Чаще всего, эти конденсаторы были установлены после сетевых проводов и предохранителя на основной плате. Убирать их я бы не рекомендовал! Ниже, приведу фрагменты для большей ясности.  ATX БЛОК ПИТАНИЯ.rar
    • Достался старенький ослик С1-137. Пару часов работал нормально, потом стал барахлить,  внезапно луч светил куда то за границу экрана. Помогало перевключение питания. Потом перестало помогать. В режиме X-Y работает, в нормальном режиме нет. Кто занимался аналоговой техникой, помогите советом, где копать, сам уже найду. В режиме X-Y:
×
×
  • Create New...