|
Портится старший бит при приёме через UART, atmega1281 |
|
|
|
Feb 29 2008, 07:10
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Используется бридж USB to UART СР2101 silabs. Запускаю передачу файла через гипиертерминал. Файл состоит из последовательности ASCII цифорок. На меге творится что-то странное. На 9600 иногда принимается нормально, иногда через байт то есть например передаю несколько раз 2. на приёме вижу 0х32 0хb2 0x32 0xb2 ... и т.д. со всеми цифрами. Ситауация исправилась, когда на гипертерминале ставлю два стоп бита. На скорости 38400 два стоп бита уже не спасают. Мега работаёт на внутреннем RC генераторе на 4 Мгц. При старте программы генератор калибруется по внешнему часовому кварцу, который для асинхронного таймера. бодрейт считается так. Код #define UART_DOUBLE_SPEED 1ul
enum { UART_BAUDRATE_9600 = (unsigned)((F_CPU * (UART_DOUBLE_SPEED + 1ul)) / (16ul * 9600ul) - 1ul), UART_BAUDRATE_38400 = (unsigned)((F_CPU * (UART_DOUBLE_SPEED + 1ul)) / (16ul * 38400ul) - 1ul) } Вообще что это такое может быть? З.Ы. Гоняю данные другой терминальной программой всё ок и на приём и на передачу.
|
|
|
|
|
 |
Ответов
|
Mar 3 2008, 06:59
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
К стати баг проявляется только в гипертерминале, тестеры погоняли данные Zoc'ом и там всё ок. Мне кажется, что здесь скорее зависит всё от дров которые на писишке применяются. Потому что мелкосхемы UART'ов имеют множество дополнительной функциональности. А юзеру писишки предоставляется некий стандартный интерфейс, который обеспечивается виндовыми дровами и который множество функций просто не задействует. Сам с подобным сталкивался, когда писал софт на писишке для управления микросхемой расширения ISA шины в 4 UARTа. И когда решил применить свой код к UARTу, который стоял на материнке, то к удивлению аппаратные FIFO буферы, документированные для микросхемы, заработали и на материнке. Я думаю, что проблема комплексная гипертерминал кривой и калибровку генератора криво провожу. Посмотрел дизасм кода калибровки в раличных режимах оптимизации. В -O0 она действительно 7 тактов, а при -Os я так и не смог в процедуре понять где она эта калибровка начинается, а где заканчивается, но есть большое подозрение, что она уже не 7 тактов.
Сообщение отредактировал xelax - Mar 3 2008, 07:00
|
|
|
|
|
Mar 3 2008, 08:01
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(xelax @ Mar 3 2008, 08:59)  И когда решил применить свой код к UARTу, который стоял на материнке, то к удивлению аппаратные FIFO буферы, документированные для микросхемы, заработали и на материнке.  Насколько я помню, были чипы 16450 без FIFO, 16550 с глючным FIFO и 16550A с поправленным. И не помню - можна ли было определить разницу между 16550 и 16550А программно. В свойствах порта у винды можна было поставить/снять галку "использовать FIFO" и подвигать ползунки порога прерывания на приём и передачу - может, просто в Вашем случае драйвер сам не понял, стоит у него чип с нормальным FIFO или с глючным и галка по умолчанию была снята. Я сам иногда снимал, когда приходилось работать с чужим оборудованием с встроенной программой, которая захлёбывалась, если от компа валил "зафифошенный" поток без пауз. Цитата(xelax @ Mar 3 2008, 08:59)  Посмотрел дизасм кода калибровки в раличных режимах оптимизации. В -O0 она действительно 7 тактов, а при -Os я так и не смог в процедуре понять где она эта калибровка начинается, а где заканчивается, но есть большое подозрение, что она уже не 7 тактов. А зачем было вообще так делать? Сделайте так: Прерывание по таймеру2, когда он отсчитал нужное число циклов (причём это можно делать не только при старте, см. мой предыдущий пост), в этом прерывании чтение нового состояния таймера1, определение дельты с предыдущим состоянием таймера1 и подкоррекция OSCCAL прямо в прерывании. Разброс времени входа в прерывание чепуха по сравнению с периодом прерываний, RC-генератор всё равно грубее шаг имеет. Я метки времени от внешних часов даже не на ICP заводил а на обычное прерывание, смысла нет выжимать лучше нескольких сот микросекунд на фоне 0,5секунды (это 0,1%, куда тому RC). И никакой зависимости от оптимизатора (если работа программы зависит от установленного уровня оптимизации компилятора, то в 99.9% случаев это ляп или как минимум недоработка разработчика программы).
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Mar 3 2008, 11:48
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Цитата(ReAl @ Mar 3 2008, 11:01)  И никакой зависимости от оптимизатора (если работа программы зависит от установленного уровня оптимизации компилятора, то в 99.9% случаев это ляп или как минимум недоработка разработчика программы). Полностью согласен.  В свою защиту хочу сказать, что код достался мне по наследству, а посему досконально не проверялся. А по поводу таймеров идея хорошая, но в моих условиях нереализуемая. Так как поверх моих функций народ пишет свои приложения и запросто может так совпасть, что прерывание от таймера возникнет в момент длинной по времени критической секции. Тогда все тайминги уплывут и откалибруется неправильно. Надо существующий вариант доделывать до верного. Например переписать на асме, чтобы не зависеть от уровня оптимизации.
|
|
|
|
|
Mar 6 2008, 15:53
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(xelax @ Mar 3 2008, 13:48)   В свою защиту хочу сказать, что код достался мне по наследству, а посему досконально не проверялся. Такой код надо проверят в первую очередь  Цитата запросто может так совпасть, что прерывание от таймера возникнет в момент длинной по времени критической секции. Тогда все тайминги уплывут и откалибруется неправильно. Если "критическая секция" займёт аж милисекунду, то что-то очень неправильно в Датском королевстве. Но даже в этом случае ошибка будет на уровне 1мс/500мс = 0,2% - при шаге перестройке RC на единичку OSCCAL в несколько раз больше эта ошибка не повлияет на калибровку. Цитата Надо существующий вариант доделывать до верного. Например переписать на асме, чтобы не зависеть от уровня оптимизации. Существующий вариант - с однократной калибровкой в начале - до верного можно доделать только методом переписывания на прерывания, чтобы обеспечить постоянную подкалибровку. Пальца на микроконтроллер достаточно, чтобы RC поплыл и понадобилось OSCCAL изменить. На этом фоне даже такой ужас, как критическая секция на четыре-восемь тысяч циклов процессора при постоянной подкалибровке повлияет меньше, чем открытое окно зимой при однократной калибровке.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
xelax Портится старший бит при приёме через UART Feb 29 2008, 07:10 IJAR [удалил НЕНУЖНОЕ цитирование]
Может быть установ... Feb 29 2008, 07:23 GDI Может дело не в меге, раз с другой терминалкой раб... Feb 29 2008, 07:30 xelax Ну затактировать от кварца к сожалению не могу. Из... Feb 29 2008, 09:56 =GM= Цитата(xelax @ Feb 29 2008, 09:56) Калибр... Feb 29 2008, 11:27  Stas633 Попробуйте "сменить" ПО на РС. AVR, наве... Feb 29 2008, 23:44   zltigo Цитата(Stas633 @ Mar 1 2008, 02:44) Попро... Mar 1 2008, 10:11    Stas633 Цитата(zltigo @ Mar 1 2008, 13:11) Не вер... Mar 1 2008, 14:18 GDI ЦитатаНу затактировать от кварца к сожалению не мо... Feb 29 2008, 10:50 xelax Цитата(GDI @ Feb 29 2008, 13:50) А в чем ... Feb 29 2008, 11:25 ReAl Кроме отклонения RC от номинального значения есть ... Feb 29 2008, 12:09 alex1979 Цитата(xelax @ Feb 29 2008, 09:10) Исполь... Mar 7 2008, 10:13 Lexdaw А вот еще был случай...Короче опторазвязанный USAR... Mar 11 2008, 12:08 alux Цитата(alex1979 @ Mar 7 2008, 13:13) Реше... Oct 24 2008, 05:01 zltigo Цитата(alex1979 @ Mar 7 2008, 12:13) неда... Oct 24 2008, 20:37 xelax Реально наблюдаю на осцилографе картинку, с писишк... Mar 11 2008, 13:33 xelax Тема древняя...
Ну раз подняли снова, просто опиш... Oct 24 2008, 11:07
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|