srg_co 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба MAX487 подключен к UART1-LPC2138, скорость 38400, VPB_CLOCK= 14745600. Передатчик передает 16 байт (пакет) 5501160800000000000000000000E0AA(HEX) на приемник LPC2138 приходит 55408B0800000000000000000000E0AA00, последний байт (00) левый, в лучшем случае из 20 отправленный пакетов приходит 6 правильных. В сети несколько различных устройств на AVR, везде установлена MAX487, они обмениваются с передатчиком нормально. Инициализация UART1: //UART1 - 38400 - RS485 PINSEL0 |= 0x00050000; //Enable RxD and TxD pins U1LCR = 0x83; //8 bits, no Parity, 1 Stop bit U1DLL = (VPB_CLOCK/16/BAUD_RATE1) & 0xFF; //Setup Baudrate U1DLM = ((VPB_CLOCK/16/BAUD_RATE1) >> 8) & 0xFF; U1LCR = 0x03; //DLAB = 0 U1FCR = 0x07; // Разрешение работы и сброс TX and RX FIFO, граница - 1 байт //настройка прерывания UART1 VICVectAddr7 = (unsigned long)uart1_interrupt; //прерывание на 7 векторе VICVectCntl7 = 0x20 | 0x07; VICIntEnable |= 0x00000080; //включить прерывание от UART1 U1IER = IER_RBR | IER_THRE; Обработка прерываний: IIRValue = U1IIR; IIRValue = (IIRValue & 0x0E) >> 1; // Выделяем информацию об источнике прерывания if ( IIRValue == 0x03 ) { //Изменился статус приемной линии //сбросим времени счетчик последнего обмена LSRValue = U1LSR; if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) { //Пустое чтения для сброса флага прерывания Dummy = U1RBR; VICVectAddr = 0; return; } if ( LSRValue & LSR_RDR ) { // В FIFO остаются не прочитанные данные RBRValue = U1RBR; RecvByte( RBRValue ); if ( DebugMode == 2 ) PutStr( PrintNumb( HEX, 2, FALSE, '0', RBRValue ) ); if ( RBRValue == 0xaa ) PutStr( CrLf ); } } if ( IIRValue == IIR_RDA ) { //Принят новый байт данных и достигнута граница тригера //количества принятых байт в FIFO //сбросим времени счетчик последнего обмена //данные приняты FlgRecv = 1; RBRValue = U1RBR; RecvByte( RBRValue ); if ( DebugMode == 2 ) PutStr( PrintNumb( HEX, 2, FALSE, '0', RBRValue ) ); if ( RBRValue == 0xaa ) PutStr( CrLf ); } if ( IIRValue == IIR_THRE ) { //Прочитаем статус и убедимся, что действительно THR пуст LSRValue = U1LSR; if ( LSRValue & LSR_THRE ) { //буфер передачи пуст if ( SendByte( &ch ) ) U1THR = ch; } } //сброс прерывания VICVectAddr = 0; Мозг кипит, смотрел анализатором принимаемые данные, все правильно :( причем кривится только первые байты в пакете, если передать что-то типа 5501160801234567890… данные придут правильно начиная с «01234567890» такое ощущение, что нарушается синхронизация при приеме первых байтов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sensor_ua 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Неясно где и как идёт переключение, есть/нужны ли "растяжки" по RS485. Почему бы не попробовать передавать 0x55. И что за дебажные вставки? может, они могут мешать? Рекомендую взглянуть http://electronix.ru/forum/index.php?showtopic=42125 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 26 мая, 2008 Опубликовано 26 мая, 2008 (изменено) · Жалоба У меня работа по RS485 на UART1 реализована так: #define RX_DATA 0x04 #define TX_DATA 0x02 //Обработчик прерывания UART1 (RS485) void Uart1_Int(void) { dwIntSrc=U1IIR; dwIntSrc&=0x0F; switch (dwIntSrc) { case RX_DATA: rs485.Rs485Rx(); break; case TX_DATA: rs485.Rs485Tx(); break; } } //Обработчик прерывания от передатчика void Crs485::Rs485Tx() { if (btTx_index++ < btTxPacketLen) { U1THR = pTxBuffer[btTx_index]; } else { bTxBlocking=false; rx_en; //макрос переключения драйвера на приём } } //Обработчик прерывания от приёмника void Crs485::Rs485Rx() { BYTE btData=U1RBR; ... //процедуры обработки преамбул, ID, пакета, CRC } Есть подозрение, что вы перемудрили с FIFO или в "IIRValue == 0x03". У меня настроено прерывание по наличию/передаче одного байта, дополнительного и принудительного высасывания из FIFO не делал. Обмен полудуплексный, потому необходимо было иметь задержку ~1мс при переходе с приёма на передачу. Проц на 57600 практически не загружен в слэйве при 32 модулях на шине. Изменено 26 мая, 2008 пользователем Altemir Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
srg_co 0 27 мая, 2008 Опубликовано 27 мая, 2008 · Жалоба Неясно где и как идёт переключение, есть/нужны ли "растяжки" по RS485. Почему бы не попробовать передавать 0x55. И что за дебажные вставки? может, они могут мешать? Рекомендую взглянуть http://electronix.ru/forum/index.php?showtopic=42125 Переключение в данном случае не идет, только прием, "растяжки" - что имеется в виду ? "55" - это и есть 0x55, я указал в скобках что строка HEX. PutStr - пишет в очередь для вывода в UART0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HEX 0 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Мусор может появляться если выходы драйвера ни куда не подтянуты: "прямой" должен быть подтянут к "+", "инверсный" к земле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Мусор может появляться если выходы драйвера ни куда не подтянуты: "прямой" должен быть подтянут к "+", "инверсный" к земле. Это классическое левое решение типа конденсатора на выводах ТТЛ-логики. И не объясняет искажения символов внутри посылки. В данном случае осциллограф - лучший друг программиста, и если он показал отличие данных в линии от принятых, то ясно, что контроллер неправильно принимает, то есть ничего не ясно. :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Это классическое левое решение типа конденсатора на выводах ТТЛ-логики. Это почти нормальное решение. По-хорошему, конечно, протокол верхнего уровня должен игнорировать мусор между посылками, но это не повод испытывать его на прочность, этот мусор специально подсовывая. И не объясняет искажения символов внутри посылки. Внутри посылки ничего не искажается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Это почти нормальное решение. По-хорошему, конечно, протокол верхнего уровня должен игнорировать мусор между посылками, но это не повод испытывать его на прочность, этот мусор специально подсовывая. Осталось третий провод обсудить :-) Как минимум, протокол должен быть. Т.е. время включения и отключения приемопередатчика у мастера и слэйва должны быть определены и соответствовать друг другу. Внутри посылки ничего не искажается. Тогда я ничего не понимаю. Автор в первом посте пишет... 5501160800000000000000000000E0AA(HEX) на приемник LPC2138 приходит 55408B0800000000000000000000E0AA00, Последний нуль можно списать на дефекты реализации протокола, а искажения после 55 - на что? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Тогда я ничего не понимаю. Автор в первом посте пишет... 5501160800000000000000000000E0AA(HEX) на приемник LPC2138 приходит 55408B0800000000000000000000E0AA00, Последний нуль можно списать на дефекты реализации протокола, а искажения после 55 - на что? Виноват, невнимательно смотрел :( Как минимум, протокол должен быть. Т.е. время включения и отключения приемопередатчика у мастера и слэйва должны быть определены и соответствовать друг другу. Вы полагаете, что тут конфликт между передатчиками? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
srg_co 0 4 сентября, 2008 Опубликовано 4 сентября, 2008 (изменено) · Жалоба :) Тема ожила ! Как минимум, протокол должен быть. Т.е. время включения и отключения приемопередатчика у мастера и слэйва должны быть определены и соответствовать друг другу. В данном случае у слэйва приемопередатчик всегда был на приеме. Что касается сети в целом, приемопередатчики у всех девайсов в сети включены в прием, перед началом передачи мастер ждет "тишину" в канале в течении 8ms, если это случилось, начинает передачу. Изменено 4 сентября, 2008 пользователем srg_co Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
evgn 0 5 сентября, 2008 Опубликовано 5 сентября, 2008 · Жалоба А проверьте baud rate и вообще все настройки uart-ов передатчика и приемников... Когда я начинал работу с rs485 была такая проблема с немного отличающимися настройками по baud rate у разных устройств, в результате приходит стабильно повторяющаяся ошибка на некоторых байтах. Можно кстати проверить, послав Ваш пакет наоборот. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
srg_co 0 5 сентября, 2008 Опубликовано 5 сентября, 2008 · Жалоба На всех 38400, кварц 14,7456M, ошибка = 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 5 сентября, 2008 Опубликовано 5 сентября, 2008 · Жалоба На всех 38400, кварц 14,7456M, ошибка = 0. И что планируете дальше делать? :) Последние нули легко устраняются растяжкой и/или промежуточным уровнем протокола. После EOT ака 55 нечего ловить (т.е. писать в буфер) - автомат состояний поддержки протокола должен остановить прием. Кстати, у приборов на AVR были другие авторы? Может, там так и было сделано. Ну а искажение информации после начального 55... Подключите ПиСишный терминал на вход ARM (соблюдая преобразование уровней). Малые емкости в драйвере RS232 при питании 3,3 В творят чудеса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IEC 1 5 сентября, 2008 Опубликовано 5 сентября, 2008 · Жалоба А проверьте baud rate и вообще все настройки uart-ов передатчика и приемников... Когда я начинал работу с rs485 была такая проблема с немного отличающимися настройками по baud rate у разных устройств, в результате приходит стабильно повторяющаяся ошибка на некоторых байтах. Можно кстати проверить, послав Ваш пакет наоборот. Человек идею сказал!!! Надо проверить настройку УАПП. Вероятно проблема в несовместимотсти протоколов. Больше похоже на лишний стоповый бит. Запишите принятый байт. А после этого отправте через передатчик аналогичный байт и сравните длительности и количество стоповых/информационных бит. Я думаю, что ситуация прояснится :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vesago 0 5 сентября, 2008 Опубликовано 5 сентября, 2008 · Жалоба Действительно ли в конце происходит прерывание и из приемника принимается 0? Может софтовый указатель сбился. Имхо 0 в конце похож на результат пустого прерывания - допустим после последнего не почистился буфер. Еще как вариант - если у вас драйвер 485 постоянно на приеме, может быть результатом приема передаваемых данных. Мне не удалось при передаче избежать приема эха. Т.к. к прибору подключается или 485 или 232 пришлось решить радикально - при передаче переключал пинсел приемника на гпио. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться