Свежие обсуждения
Микроконтроллеры

MSSP(IIC) и USART

1 8 13

Итак, публикую отрывки из первоначального варианта статьи:
.... Чтобы этого избежать, необходимо гарантировано делать выборку в середине битов. Для этого, в данной конструкции, временной интервал приёма одного бита разбит на три части. Возможны два "крайних" варианта распределения временных сигналов.
См. аттач
Все остальные варианты будут промежуточными. Так как выборка осуществляется по второму сигналу (t2), нестабильность скорости внешнего передатчика, при которой данные будут считаны правильно, составляет: +/- (1/3):10x100% = +/- (3.33)%. Коэффициент 10 появляется из-за того, что для правильного приёма, необходимо принять весь байт, а так же стартовый и стоповый биты. То есть, десять бит.

Программа работает следующим образом. ....

...... Блок приёма функционирует так. Наличие стартового бита проверяется каждое прерывание. Если бит обнаружен, то по второму прерыванию снова проверяется его наличие. В случае подтверждения, зажигается светодиод, и включается механизм приёма. Дальнейшее считывание информации также осуществляется по каждому второму прерыванию. Данные помещаются в специальный регистр. При приёме десятого бита, гасится светодиод, механизм приёма выключается, и проверяется соответствие значения принятого бита стоповому. В случае совпадения, данные из в/у регистра, переписываются в буфер передатчика аппаратного USART, для отправки в ком-порт. Таким образом, данные будут приняты только при наличии стопового бита (если быть точным, при значении десятого бита, равном единице). Третье прерывание последнего цикла в приёме данных не участвует, и, при его возникновении, происходит новая проверка наличия стартового бита. Этим достигается вышесказанная нестабильность, равная "-3,33%", так как, в противном случае, она была бы только "+3,33%".

 

GM:
делается три считывания на бит
Неправильно. Там используется три "тика", а считывание там всего одно (хотя, "по уму", надо делать несколько), и только стартовый бит проверяется дважды (см. выше).
Чем больше количество считываний, тем меньше вероятность ошибки. Требования же к скорости приёма-передачи зависят от интервала между первым тиком (по которому запускается "процесс приёма") и последним тиком считывания. Тут, соответственно, чем больше считываний, тем выше требования.

Теперь обратимся к эпюре.
Для первого случая, допустимо отклонение тактовой частоты от -2/3 до +1/3.
Для второго случая, от -1/3 до +2/3.
Из наихудших условий получаем: от -1/3 до +1/3.
Про остальное сказано в статье.
Теперь поясните, откуда беруться эти цифры:
±((1/2)/3)/8.5=±0.0196

 

Оффтоп.
Ув Gregory, реализовать 8 дуплексных UARTов на ATMELe вполне реально Я их тоже реализовывал, и именно в таком количестве. На 8 Мгц скорость 9600 бод обеспечивается без особых проблем. Наверное, можно и больше, и быстрее, просто необходимости в этом не было. Вычислительный процесс на ATMELах реализован достаточно эффективно.

 

Gregory: Теперь поясните, откуда берутся эти цифры: ±((1/2)/3)/8.5=±0.0196

Когда писал цифры, думал, что у вас 3 выборки на бит. Если их расположить симметрично, то расстояние от крайней выборки до границы бита будет То/3/2. В случае разности частот приёма-передачи эти То/6 должны быть равномерно "размазаны" (разумное предположение, но не всегда оно выполняется) на временном отрезке 8,5*То, там где вы принимаете последний бит байта. Отсюда выходит, что допускается нестабильность РАЗНОСТИ частот приёма-передачи ±(1/6)/8.5=±0.0196. Формула справедлива для разности, т.е. когда например, частота передатчика абсолютно точная, а частота приёмника гуляет. Но поскольку частота передачи и частота приёма абсолютно независимы, то общий допуск на нестабильность надо уменьшить вдвое, т.е. не 2%, а 1%.

Для одной выборки, которая в идеале должна быть в центре нестабильность равна ±(1/2)/8.5/2=±0.0294=±3%

Всё меня ждут, убегаю домой.

 

chav1961:
Вычислительный процесс на ATMELах реализован достаточно эффективно
Всем известно, что МЦ на Атмелах равен тактовой частоте (т.е., в четыре раза быстрее, чем на ПИКах), но вот об эффективности, мнения расходятся.
Не будем сейчас это обсуждать.
Но. Во-первых, 9600, это - не 31250.
А во-вторых, поясните, как Вы это делали? Есть Атмелы с восемью таймерами (и сколько они стОят)?

P.S.: Тема вовсе не оффтоп, а прямо по теме топика (программная реализация UART). Пускай и на Атмелах. Мы же про теорию говорим (естественно, если имеется ввиду специализированный МК с восемью аппаратными UART'ами, то это - оффтоп )

 

GM:
нестабильность РАЗНОСТИ частот
Естественно, речь идёт именно об этом. Точнее говоря, именно о РАЗНОСТИ, поскольку, в реальных условиях, частота генератора "плавает" (если вообще "плавает") довольно медленно во времени, и, для приёма-передачи одного байта, её можно считать постоянной. Поэтому, ничего делить на 2 не надо.

у вас 3 выборки на бит
Опять Вы что-то путаете с терминологией (поэтому я не очень понял, о чём речь). Мы здесь употребляем понятия "выборка" и "тик" (надеюсь, отличия пояснять не надо ). Так вот.
В моей конструкции, используются три тика и одна выборка (кроме старта, о чём сказано отдельно). Если использовать четыре тика (см. картинку, которую неплохо было бы перерисовать, добавив t4, на бумажке ), то можно делать уже две выборки (по t2 и t3). При этом, повысится вероятность правильного считывания, но и возрастут требования к разности частот. Которая, при этом (см. вновь нарисованную картинку), составит ±(1/4)/10*100%=±2,5%
Откуда, что берётся в Ваших формулах (и почему они так плодятся), я так и не понял.
Кстати, идею по устранению задержки я тоже так и не понял.
Поэтому, возвращайтесь быстрей, и проясняйте ситуацию.

 

Уже здесь .

Много надо чего сказать, ну, по очереди. По скорости обработки. Один миди-бит длится 32 мкс, что для 20-мегагерцовой АВР составит 640 машинных циклов, ну о-очень большое время. Вот вам примерный кусок кода приёма байт по миди и передачи их по ком на авр. Работает по прерываниям int0 (прерывание по перепаду 1-0) и по прерываниям ovf0 (по переполнению таймера0). Первое прерывание инициирует второе и запрещает себя, второе срабатывает точно в середине всех битов, побитно принимает байт и передаёт его по последовательному порту. Как вы сами можете посчитать, максимальное время реакции составляет 19+8=27МЦ. Для двух каналов будет 54. А у нас их 640.

;Приём миди-байта и передача его по ком(13/19МЦ)
tim1ovf:  in       temp,porta         ;читаем миди-порт
          in       save,sreg          ;сохраним статус
          bst      temp,mpin          ;сохраним
          bld      midi1,1            ;принятый
          ror      midi1              ;бит во временном
          ror      midi2              ;регистре
          brcc     tim2               ;все биты?
          sts      gimsk,mask1        ;разрешим int0
          sts      timsk,mask2        ;запретим ovf0
          ror      midi1              ;избавимся от
          ror      midi2              ;старт-бита
          out      udr,midi2          ;передадим байт
tim2:     out      sreg,save          ;восстановим статус
          reti                        ;сделано

 

Gregory, если коротко, суть следующая:

1. Передачи и прием организованы в обработчике прерываний от одного таймера. 8 линий Tx - это один порт. 8 линий Rx - второй порт. И ввод и вывод выполняется непрерывно, даже когда ни передачи, ни приема не требуется. На передачу и на прием одного бита требуется 8 тиков таймера, как я когда-то и писал.
2. Для обеспечения стабильности передачи в самом начале работы обработчика на выходной порт (Tx) выводятся заранее подготовленные 8 битов по всем UARTам, следом читается значение байта со входного порта (Rx), а затем формируются биты Tx для следующего "тика" передачи и обрабатываются биты Rx. Т.е. не подготовка/вывод, а вывод/подготовка. Благодаря этому дальнейшая обработка мало критична ко времени (в разумных пределах, естественно).
3. Передача по каждому каналу ведется путем сдвига двух байтов. В первом байте в бите 7 расположен старт-бит , далее - 7 битов данных, 8-й бит данных и 7 штук лог.1 расположены во втором байте. При сдвиге младший бит первого байта заполняется старшим битом второго байта, младший бит второго байта заполняется лог.1 (не лог.0!). Два байта в таком формате формируются не в обработчике прерываний, а в фоновом процессе. Подготовка очередного байта для передачи в таком формате превращается в цикл сдвигов 8 пар байтов данных с запихиванием старшего бита первого байта в формируемый для передачи байт. Передача по всем 8 каналам происходит синхронно, независимо от того, в какой момент времени фоновый процесс поместил байт для передачи, т.е. все передачи "выравнены" по границе бита (не байта!). Для асинхронного по своей сути протокола это совершенно непринципиально.
4. Обработка принятых данных ведется в обратном порядке, т.е. распихиванием считанного из порта Rx-ов байта по одному (не двум) байту принимаемых данных (их, естественно, 8 штук) в промежуточном буфере. Стоп-бит не обрабатывается.
5. Конец передачи определяется по исчерпанию счетчика переданных битов (счетчик устанавливается и анализируется фоновым процессом, а вычитается в обработчике). Никаких анализов счетчика передачи в обработчике не делается, там только обеспечивается защита от перехода его через ноль - передача, как я уже сказал, ведется непрерывно, независимо от того, надо ли что-то передавать.
6. Начало приема определяется по появлению лог.0 на входе соответствующего канала при счетчике принятых бит, меньшем нуля. После обнаружения такой ситуации счетчик устанавливается в 8*9, далее на значениях n % 8 == 4 ("серединах" битов), выполняется п.4. (т.е. прием по каналам ведется асинхронно), а по достижении счетчика равным нулю сформированный байт переписывается в область "принятого" байта и взводится флаг факта приема.

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

 

Gregory: ...речь идёт именно об этом. Точнее говоря, именно о РАЗНОСТИ, поскольку, в реальных условиях, частота генератора "плавает" (если вообще "плавает") довольно медленно во времени, и, для приёма-передачи одного байта, её можно считать постоянной. Поэтому ничего делить на 2 не надо

Всё не так. Действительно, кратковременную нестабильность генераторов можно не учитывать. Я и не учитывал. Речь идёт о другом, а именно о том, что во время обмена по последовательному каналу частоты генератора и приёмника не совпадают. Это неоспоримый факт. Теперь представьте себе, что у вас частота передатчика абсолютно точная, а частота приёмника отличается от него на некую величину. Давайте оценим допустимую величину рассогласования в данном случае.

Для одной выборки на бит допустимое временное рассогласование ∆Т=±0,5То на интервале от начала старт-бита до момента считывания последнего 8-го бита байта, т.е. до середины последнего битового интервала. Интервал этот в среднем равен Тп=8,5То, а не 10То, как вы считаете, потому что после записи последнего бита вы получили всю полезную информацию, содержащуюся в байте, и никакое последующее временное рассогласование не может изменить её ни на йоту.

Относительное рассогласование ∆Т/Тп=±0,5То/8,5То=±1/17=±0.0588 или ±5.9%. Теперь вспомните, что все рассуждения мы вели для абсолютно точной частоты передатчика и отличной от неё частоты приёмника. Крайние допустимые значения будут такие Fпрд=Fo, Fпрм=(Fo-6%) или Fпрд=Fo, Fпрм=(Fo+6%). Но реальная частота передатчика не идеальна, значит, возможны такие ситуации как Fпрд=(Fo-6%), Fпрм=(Fo+6%) или Fпрд=(Fo+6%), Fпрм=(Fo-6%). В обоих случаях рассогласование РАЗНОСТНОЙ частоты будет 12%, что неприемлемо. Если допустить, что вероятность распределения ошибок в установке частоты передатчика и приёмника одинакова, то нестабильность нужно уменьшить вдвое. Отсюда появляется двойка в знаменателе, и допустимое взаимное рассогласование двух частот равно ±3%.

А вообще, по теории измерений, чтобы получить оценку общей ошибки необходимо складывать МОДУЛИ всех ошибок.

 

Gregory: Кстати, идею по устранению задержки я тоже так и не понял.

Ну давайте ещё раз вернёмся к тому примеру. Вам нужно принять байт по миди 31250 бод и передать его по ком 38400. Вы принимаете его целиком и только потом отправляете. Задержка равна времени передачи байта по ком - 26 мкс/бит*10биг=260 мкс.

Теперь вы хотите уменьшить задержку, передавая побитно, как только бит для передачи готов. Когда начать передачу? Начать передачу нужно в такое время Тх, чтобы к середине ПРИЁМА последнего миди-бита закончить передачу предпоследнего ком-бита и начать передачу свежеполученного последнего миди-бита. Надеюсь, это ясно.

Время середины последнего миди-бита Тмиди=8,5*32=272 мкс, время начала последнего ком-бита Тком=8*26=208 мкс, следовательно время начала передачи по ком Тх=Тмиди-Тком=64 мкс (в предыдущем посте я немного приврал). Отсюда можно вывести удобное практическое правило для вашего случая: принять два бита, старт и первый, и начать передачу по ком.

От середины последнего бита передача миди закончится через 16+32=48 мкс, время передачи по ком закончится через 26+26=52, т.е. задержка в данном случае составит всего 4 мкс. Точно также нужно рассуждать при передаче в обратном направлении. Ну, это вам как домашнее задание(. Разумеется, необходим учёт рассогласования частот на приёмной стороне и на передающей.