|
Непонятное поведение RS485-UART1 |
|
|
|
May 26 2008, 19:30
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
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» такое ощущение, что нарушается синхронизация при приеме первых байтов.
|
|
|
|
|
May 26 2008, 20:49
|
Местный
  
Группа: Свой
Сообщений: 249
Регистрация: 2-05-06
Из: Россия, Поволжье
Пользователь №: 16 686

|
У меня работа по 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 модулях на шине.
Сообщение отредактировал Altemir - May 26 2008, 21:08
|
|
|
|
|
May 27 2008, 07:13
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Цитата(sensor_ua @ May 27 2008, 00:31)  Неясно где и как идёт переключение, есть/нужны ли "растяжки" по RS485. Почему бы не попробовать передавать 0x55. И что за дебажные вставки? может, они могут мешать? Рекомендую взглянуть http://electronix.ru/forum/index.php?showtopic=42125Переключение в данном случае не идет, только прием, "растяжки" - что имеется в виду ? "55" - это и есть 0x55, я указал в скобках что строка HEX. PutStr - пишет в очередь для вывода в UART0.
|
|
|
|
|
Sep 4 2008, 11:11
|
Участник

Группа: Свой
Сообщений: 54
Регистрация: 25-11-04
Из: Тула
Пользователь №: 1 228

|
Мусор может появляться если выходы драйвера ни куда не подтянуты: "прямой" должен быть подтянут к "+", "инверсный" к земле.
|
|
|
|
|
Sep 4 2008, 11:29
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(HEX @ Sep 4 2008, 14:11)  Мусор может появляться если выходы драйвера ни куда не подтянуты: "прямой" должен быть подтянут к "+", "инверсный" к земле. Это классическое левое решение типа конденсатора на выводах ТТЛ-логики. И не объясняет искажения символов внутри посылки. В данном случае осциллограф - лучший друг программиста, и если он показал отличие данных в линии от принятых, то ясно, что контроллер неправильно принимает, то есть ничего не ясно.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Sep 4 2008, 12:13
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(aaarrr @ Sep 4 2008, 14:42)  Это почти нормальное решение. По-хорошему, конечно, протокол верхнего уровня должен игнорировать мусор между посылками, но это не повод испытывать его на прочность, этот мусор специально подсовывая. Осталось третий провод обсудить :-) Как минимум, протокол должен быть. Т.е. время включения и отключения приемопередатчика у мастера и слэйва должны быть определены и соответствовать друг другу. Цитата(aaarrr @ Sep 4 2008, 14:42)  Внутри посылки ничего не искажается. Тогда я ничего не понимаю. Автор в первом посте пишет... 5501160800000000000000000000E0AA(HEX) на приемник LPC2138 приходит 55408B0800000000000000000000E0AA00, Последний нуль можно списать на дефекты реализации протокола, а искажения после 55 - на что?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Sep 4 2008, 19:11
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
 Тема ожила ! Цитата Как минимум, протокол должен быть. Т.е. время включения и отключения приемопередатчика у мастера и слэйва должны быть определены и соответствовать друг другу. В данном случае у слэйва приемопередатчик всегда был на приеме. Что касается сети в целом, приемопередатчики у всех девайсов в сети включены в прием, перед началом передачи мастер ждет "тишину" в канале в течении 8ms, если это случилось, начинает передачу.
Сообщение отредактировал srg_co - Sep 4 2008, 19:12
|
|
|
|
|
Sep 5 2008, 05:09
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 4-10-06
Пользователь №: 20 954

|
А проверьте baud rate и вообще все настройки uart-ов передатчика и приемников... Когда я начинал работу с rs485 была такая проблема с немного отличающимися настройками по baud rate у разных устройств, в результате приходит стабильно повторяющаяся ошибка на некоторых байтах. Можно кстати проверить, послав Ваш пакет наоборот.
|
|
|
|
|
Sep 5 2008, 05:59
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(srg_co @ Sep 5 2008, 08:44)  На всех 38400, кварц 14,7456M, ошибка = 0. И что планируете дальше делать?  Последние нули легко устраняются растяжкой и/или промежуточным уровнем протокола. После EOT ака 55 нечего ловить (т.е. писать в буфер) - автомат состояний поддержки протокола должен остановить прием. Кстати, у приборов на AVR были другие авторы? Может, там так и было сделано. Ну а искажение информации после начального 55... Подключите ПиСишный терминал на вход ARM (соблюдая преобразование уровней). Малые емкости в драйвере RS232 при питании 3,3 В творят чудеса.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Sep 5 2008, 07:43
|
Местный
  
Группа: Свой
Сообщений: 263
Регистрация: 22-03-05
Из: г. Харьков, Украина
Пользователь №: 3 598

|
Цитата(evgn @ Sep 5 2008, 09:09)  А проверьте baud rate и вообще все настройки uart-ов передатчика и приемников... Когда я начинал работу с rs485 была такая проблема с немного отличающимися настройками по baud rate у разных устройств, в результате приходит стабильно повторяющаяся ошибка на некоторых байтах. Можно кстати проверить, послав Ваш пакет наоборот. Человек идею сказал!!! Надо проверить настройку УАПП. Вероятно проблема в несовместимотсти протоколов. Больше похоже на лишний стоповый бит. Запишите принятый байт. А после этого отправте через передатчик аналогичный байт и сравните длительности и количество стоповых/информационных бит. Я думаю, что ситуация прояснится :-)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|