|
Прерывания UART, не работает |
|
|
|
Feb 13 2014, 18:10
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Всем категорически драсте. Пытаюсь реализовать небольшое устройство (назовём его A), которое должно управлять другим устройством (В) по интерфеёсу 485 (полудуплексный режим) с использованием протокола юарт. Система работает след. образом : с PC на устройство А отправляется пакет данных (по юарту, скорость 9600кБод/с). Устройство А принемает пакет и транзитом передаёт его на устройство Б но уже со скоростью 1Мбит/с (т.е. длительность импульса данных = 1 мкс). Далее устройство Б должно ответить (по тем же проводам). Решил не морочится, взял ниос прилепил к нему 2 UART контроллера один принемает с компа другой для работы с устройством Б. Сначало было всё нормально, с компа посылка принемалась и благополучно отправлялась с необходимой скоростью. Но вот когда устр. Б отвечает, прерывания UARTа (для 1 Мбита) говорящие о том, что очередной байт принят ведут себя каким то рандомным образом. Дело в том, что для преобразования интерфейсов используется микросхема MAX3485. Её работа такова, что ножка, с которой данные приходят уже на ПЛИС всё время, сидит в 0. Кода же устройство Б начинает передавать оно сначало поднимает линию (назовём этот момент предстартовым битом) и затем опускает (это уже стартовый бит). Этот самый предстартовый бит довольно короткий и я думал дело в этом. Но сдаётся мне дело в чём то другом. Ниос использею естественно самый простяцкий. Может кто подскажет чего. На осциллограмме жёлтым изображён ответ устройства Б, а синим моменты, в которые UART контроллер говорит, что мол байт принят, т.е. происходит прерывание.
Эскизы прикрепленных изображений
|
|
|
|
|
Feb 14 2014, 07:12
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
по спецификации UART сигнал должен быть в 1 в неактивном режиме, падение в ноль - стартовый символ. По окончанию приема сигнал должен подняться в 1 на величину не менее стопового символа и должен в нем же и остаться. Потому что следующее же падение будет воспринято как новый старт.
В RS-485 при переходе на передачу линия включается и на нее идет сигнал с передатчика, при переходе на прием, линию отпускают. Вы должны на этой линии создать правильное соотношение 2 сигналов, чтобы когда на ней нет ни одного передатчика, она была в 1, это позволит всем подключенным приемникам не начинать приемы в неурочное время....
сейчас вам очень повезло что оно так работает, потому что во многих реализация UART нет завершения приема по стоповым битам, и они сразу готовы принять новый символ, в таких уартах вы бы получали кучу нулей постоянно...
проверьте как должны быть линии А и Б, и подтяните их резисторами куда надо!
|
|
|
|
|
Feb 14 2014, 07:43
|
Гуру
     
Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804

|
Цитата(Грендайзер @ Feb 14 2014, 09:44)  Дело а том, что при переключении из режима передачи в режим приёма на приёмной ноге уровень меняется. Поэтому подтягивай (я подтягивал и внутренним и внешним резистором) не подтягивай, а как только переключаюсь в режим приёма, уровень на этой ноге падает и его может задрать только передатчик устройства В. Впрочем к ноге плисины устройства В (правда там Xilinx стоит) приходит такой же сигнал, сформированный моим устройством (разве что только предстартовый бит немного пошире). Да и в устройстве В также использованы софтовые ядра (только от Xilinx'а конечно). Я некорректно дал ответ. Речь идет только о приемопередатчике rs-485. Как только передатчик отключается, у Вас приемник это состояние линии воспринимает как 0. А надо как 1. Если работой передатчика Вы занимаетесь, перед выдачей пакета при включенном передатчике можно подать 10 бит единиц, тогда автомат приемника должен выйти в начальное состояния для приема стартового бита пакета. Но чтобы этого не делать резисторы вешают на линию или берут приемопередатчики, в которых решена эта проблема
|
|
|
|
|
Feb 14 2014, 08:51
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Подтягивающие резисторы не помогают. Действительно, процесс передачи инициализирую я, и пока я передаю, линия RО (ножка микросхемы идущая к ПЛИС) задирается в 1. Когда я переключаюсь из режима передачи в режим приёма RО опускается в 0 и лежит в нём до тех пор, пока устройство В не переключится в режим передачи и его передатчик не поднимет линию. Т. о. происходит дополнительное срабатывание, но картину это всёравно не особо меняет. Это что касается резистора. Картина же без резистора представлена на осциллограммах (в самаом верху рисунка видно, что до прихода предстартового бита, линия сидит в 0, и никаких прерываний нет). P.S. Каждый кстати раз прерывания расставляются как то рандомно... Цитата проверьте как должны быть линии А и Б, и подтяните их резисторами куда надо! В том то и дело, что ароде всё правильно ссоединено. Ведь как я писал, на устройство Б приходит от пеня сигнал, который то же сначала сидит в 0. Единственное , то, что мой предстартовый бит по длительности как раз не менее стопового. Более того, я напрямую ссоединял ножки плис (в обход линии 485). В этом случае линя приёмника по умолчанию была в 1 а потом проваливалась (т.е. всё как надо) но... ниос зараза всёравно косячит с прерываниями... быть может для нормальной работы на скоростях отличных от стандартных нужно другое ядро, а не бесплатное... блин неделю уже мучаюсь...
Сообщение отредактировал Грендайзер - Feb 14 2014, 08:38
|
|
|
|
|
Feb 14 2014, 08:56
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
ЕПРСТ! Что ядра менять, если на осцилографе НЕ ПРАВИЛЬНАЯ!!!! картина.
не может линия сидеть в нуле, должна быть в 1 между сообщениями, тогда на любом ядре будет работать.
когда у вас к шине никто не подключен и вы в режиме приема шина в 1 или в 0? Если в 0, то значит надо А Б местами поменять, резисторы проверить, и так далее, сделать чтобы была в 1.
Потом подключаете ваше устройство другое, в режиме приема, оно должно выключать передатчик и отпускать шину, и на шине с вашей стороны должен быть 1. При переключении в передачу, оно должно сначала на шине выставлять 1, то есть с вашей стороны шина не должна меняться.
Если во время бездействия ваш передатчик почему то на шину выдает 1, то надо править передающий UART, чтобы заканчивая передачу он заканчивал ее 1 и дальше ее и держал!
|
|
|
|
|
Feb 14 2014, 11:46
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Я ж написал, что ссоединял плисы напрямую, в обход 485. В этом случае всё было именно так как Вы и говорите. Но ниос один хрен косячил. Вот осциллограмма при непосредственной связи 2-х устройств (в обход RS485)
Эскизы прикрепленных изображений
|
|
|
|
|
Feb 14 2014, 13:02
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
UART надо писать к ниосу, У всех этих процов шина выведена наружу, и все делают свои корки.
так это че устройство Б такую диаграмму выдает? во лажа... это не UART ни разу. Тогда вариантов нет, надо работать с этой фигней. Чтобы ниос не ошибался в такой задаче, надо сделать маленький переходник, который отсчитав 8 бит данных, выключает вход и выдает на выход 1, до следующего падения в 0 входа. Поставить заплатку, и все будет хорошо, ниос начнет давать прерывание
|
|
|
|
|
Mar 12 2014, 08:27
|
Местный
  
Группа: Участник
Сообщений: 368
Регистрация: 18-04-11
Из: Город-герой Москва
Пользователь №: 64 451

|
Появилось времечко, и вновь взялся за разборки с ниосом (точнее с его уартовскими прерывниями). Подключил платы в обход интерфейса RS-485, хорошенько ссоединив земли обеих плат. Прерывания всё ещё не работали... Из 5 бай, процессор прервался лишь 2 раза. После этого поднял тактовую частоту с 50 до 100 МГц. И вот картинка. На 5 пришедших байт, ниос приервался 5 раз. Та же картина, если придёт 12 байт - 12 прерываний (т.е. кол-во прерываний равно количеству байт). Во время длительности синего импульса происходит следующее: 1) Чтение статусного регистра (для определения из за чего собственно произошло прерывание); 2) Выставление '1' на порте (если верить моделсиму и осциллографу 26 такт. импульсов); 3) Далее считываюся данные из приёмного буффера; 4) Окончание подпрограммы и установка '0' на порт (уже в основной программе). Т.о. видно, что процессор просто не успевает обработать прерывание должным образом (при данном временном промежутке межу принемаемыми байтами). Получается, что с басяцким ниосом или скорость предачи уменьшать или зазоры между байтами вводить (что лично я сделать не могу, т.к. внешнее устройство не моё), либо самому дописывать неую доп. "обвязочку".
Сообщение отредактировал Грендайзер - Mar 12 2014, 08:32
Эскизы прикрепленных изображений
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|