реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> AVR+FREERTOS+RS485, потеря байтов
Volldemar
сообщение Apr 4 2012, 13:26
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Тупик, прошу помощи, это мой первый опыт с фриртосой.
Значит так, всё крутится в мега1284. Делаю пересылку между юсартами, с первого принимаю, на второй передаю, со второго принима, н апервый передаю. RS485 на втором. Пока было без драйверов 485 (ADM485) две FT232 на два порта юсба в комп, всё бегало без проблем, а вот с драйвером - беда, беда, печалька... Симптом: по юсарт1 принимаю байты, на юсарт2 выдаю, ну и запущено две терминальные проги на компе, теряются байты, передаю 20, принимаю 17...20.
вот мои обработчики прерываний:
Код
ISR( USART1_UDRE_vect )
{
    uint8_t cChar;
    signed portBASE_TYPE cTaskWoken;

    if( xQueueReceiveFromISR( xCharsForTx[1], &cChar, &cTaskWoken ) == pdTRUE )
    {
        RS485_tx;
        UDR1 = cChar;
    }
    else
    {
        vInterruptOff(1); // запрещение прерывания UDRE1
    }
}

Код
ISR( USART1_TX_vect )
{
    RS485_rx;
}

где косяк? подскажите плиз...

Сообщение отредактировал Volldemar - Apr 5 2012, 13:22
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 5 2012, 13:35
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Код
inline portBASE_TYPE xSerialPutChar485( uint8_t uiUSARTport_num, unsigned portBASE_TYPE cOutChar, portTickType xBlockTime )
{
    uint8_t uiReturn;

    if( xQueueSendToBack( xCharsForTx[ uiUSARTport_num ], &cOutChar, xBlockTime ) == pdTRUE )
        {
            uiReturn = pdTRUE;
            vInterruptOn(uiUSARTport_num); //разрешение прерывания UDRE1
            return uiReturn;
        }
    else
        {
            uiReturn = pdFAIL;
            return uiReturn;
        }
}
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 9 2012, 08:33
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Может я что то не так делаю? поздскажите, кто имел опыт с RS485 в фриртосе?
Задача, делающая перенаправление вот:
Код
static void prvUSARTEchoTask1( void *pvParameters )
{
    uint8_t cChar;

    ( void ) pvParameters;

    for(;; )
        {
            if (xSerialGetChar( mainUSART1, &cChar, portMAX_DELAY ) == pdTRUE)

            xSerialPutChar( mainUSART0, cChar, xNoBlock );
        }
    }
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 13 2012, 03:50
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Volldemar @ Apr 4 2012, 19:26) *
Симптом: по юсарт1 принимаю байты, на юсарт2 выдаю, ну и запущено две терминальные проги на компе, теряются байты, передаю 20, принимаю 17...20.

Не совсем понятно как комп отправляет/получает в/из RS485? Наверно есть преобразователь типа USB<->RS485? Проверьте, чтоб был отключен ..... программный контроль (follow control чтоли), иначе некоторые байты будут приняты за управляющие, например 0х11.

Не понятно, что за команда
Код
RS485_tx;
Это макрос какой-то?

Не понятно, а где управление ADM-кой? Ей на ноги надо выставлять RE и DE. Как минимум ногой DE дёргать. А чтоб эха не было ещё и RE нужно управлять.

ps При использовании в компе преобразователя USB<->COM некоторые проги на компе глючат с виртуальными компортами. У меня было подобное, терялись байты. (с чипами ftdi проблем не было, а вот с др были). Я для отладки таких вещей использую вместо говнотерминалок COM Port Toolkit

pps Да и программа как-то написана..... в таск1 вызов xSerialPutChar(), а ниже определение xSerialPutChar485(). Наверно это одно и тоже.
код функции xSerialPutChar485() - жесть. наверно это не вся функция и лишнее выкинуто. Но если это вся, то я бы определил её так
Код
inline portBASE_TYPE xSerialPutChar485( uint8_t uiUSARTport_num, unsigned portBASE_TYPE cOutChar, portTickType xBlockTime )
{
    if( xQueueSendToBack( xCharsForTx[ uiUSARTport_num ], &cOutChar, xBlockTime ) == pdTRUE )
    {
        vInterruptOn(uiUSARTport_num); //разрешение прерывания UDRE1
        return pdTRUE;
    }
    else
        return pdFAIL;
}
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 13 2012, 06:09
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



В компе, на двух юсбах висят FT232, на одной из них ADM485, вторая подключена к RXD/TXD меги.
Макросы:
Код
RS485_tx;
RS485_rx;

как раз управляют адм-кой (выводы RE и DE содинены вместе и подключены к свободному выводу меги), которая установлена на моей плате.
Пользуюсь терминалкой - QT_comport, так как указанная вами "COM Port Toolkit" почему то выдаёт ошибку при запуске, когда запущено два толкита.
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 13 2012, 06:59
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Volldemar @ Apr 13 2012, 12:09) *
В компе, на двух юсбах висят FT232, на одной из них ADM485, вторая подключена к RXD/TXD меги.

эээ...... тоже не совсем понятно.... получается путь такой:

РС - FT232R(USB-UART) -(три провода, TTL уровни)- ADM485 -(2 провода, уровни rs485)- ADM485 -(TTL уровни)- ATMega -
-(TTL уровни)- FT232R(UART-USB) - РС

Если так, то адм-кой возле атмеги управление макросами RS485_tx и RS485_rx. А кто управляет адм-кой возле компа?
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 13 2012, 07:41
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Цитата(juvf @ Apr 13 2012, 09:59) *
эээ...... тоже не совсем понятно.... получается путь такой:

РС - FT232R(USB-UART) -(три провода, TTL уровни)- ADM485 -(2 провода, уровни rs485)- ADM485 -(TTL уровни)- ATMega -
-(TTL уровни)- FT232R(UART-USB) - РС

Если так, то адм-кой возле атмеги управление макросами RS485_tx и RS485_rx. А кто управляет адм-кой возле компа?

Путь сигнала:
РС USB1 - FT232R(USB-UART) - USART0 ATmega - USART1 ATmega ADM485 - ADM485 - FT232R - РС USB0
адм-кой возле компа рулит FT232R схема: http://bsvi.ru/perexodnik-usb-rs485/
Go to the top of the page
 
+Quote Post
juvf
сообщение Apr 13 2012, 09:02
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата
FT232. Оказывается, у нее есть ножка которая переключается в момент фактической передачи. Работает это на отлично
Не знал про это. *WRITE*

Ну если без адм-ок, с атмегой и ртосом всё работает на ура, то может косяк не в ртос? а как будут работать терминалки по пути:

РС USB1 - FT232R(USB-UART) - ADM485 - ADM485 - FT232R - РС USB0

Хотя в таком пути адм-кой, которой управляла атмега, некому управлять. можно у неё ноги DE и RE припаять к 0 или к 1. И проверить только в одну сторону. Может ртос с атмегой не причем, может косяк где-то в преобразователях?
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 13 2012, 11:39
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Цитата(juvf @ Apr 13 2012, 12:02) *
Не знал про это. *WRITE*

Ну если без адм-ок, с атмегой и ртосом всё работает на ура, то может косяк не в ртос? а как будут работать терминалки по пути:

РС USB1 - FT232R(USB-UART) - ADM485 - ADM485 - FT232R - РС USB0

Хотя в таком пути адм-кой, которой управляла атмега, некому управлять. можно у неё ноги DE и RE припаять к 0 или к 1. И проверить только в одну сторону. Может ртос с атмегой не причем, может косяк где-то в преобразователях?

Уверен, что дело не в преобразователях, так как потери идут только по:
-> USART1 ATmega ADM485 - ADM485 - FT232R - РС USB0 ->
если:
-> РС USB0 FT232R - ADM485 - ADM485 - USART1 ATmega ->
то всё ходит без потерь...
да и осцилографом глядел форму сигнала на управляющей ноге меги, которая дрвгает и переключает адм-ку, там явно видны "провалы", и количество провалов соответствует количеству потеряных байт. Значит где то в алгоритме баг...

В варианте вот такого обработчика прерывания:
Код
ISR( USART1_TX_vect )
{
//        RS485_rx;
}
потери байтов нет.
В этом случает драйвер rs485 всегда включен на передачу.


Сообщение отредактировал Volldemar - Apr 13 2012, 10:58
Go to the top of the page
 
+Quote Post
unkier
сообщение Apr 28 2012, 07:40
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 20-01-08
Пользователь №: 34 249



а осцилом или логическим анализатором глянуть где именно пропадают байты ?
Go to the top of the page
 
+Quote Post
Volldemar
сообщение Apr 28 2012, 07:47
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Цитата(unkier @ Apr 28 2012, 10:40) *
а осцилом или логическим анализатором глянуть где именно пропадают байты ?

Глядел осцилом, каждый раз, пропадает случайный байт (байты), повторяемости нет.
Go to the top of the page
 
+Quote Post
unkier
сообщение Apr 28 2012, 08:31
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 20-01-08
Пользователь №: 34 249



мигнуть светодиодом из обработчика прерывания ? и встать щупами на лампочки.
Go to the top of the page
 
+Quote Post
Lotor
сообщение Apr 28 2012, 11:47
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Цитата(Volldemar @ Apr 4 2012, 17:26) *
Код
ISR( USART1_UDRE_vect )
{
    uint8_t cChar;
    signed portBASE_TYPE cTaskWoken;

    if( xQueueReceiveFromISR( xCharsForTx[1], &cChar, &cTaskWoken ) == pdTRUE )
    {
        RS485_tx;
        UDR1 = cChar;
    }
    else
    {
        vInterruptOff(1); // запрещение прерывания UDRE1
    }
}

Код
ISR( USART1_TX_vect )
{
    RS485_rx;
}

где косяк? подскажите плиз...

Я могу ошибаться, но смотрите, приоритет USART1_UDRE_vect выше чем USART1_TX_vect. И т.к. последнее разрешено всегда, то оно может вклиниться в неподходящий момент. Вот и потеря данных. Вообщем, самое простое - это переписать для начала код, чтобы использовалось одно прерывание USART1_TX_vect. Если потери исчезнут - то будете знать, где копать.


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post
Volldemar
сообщение May 4 2012, 11:40
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Цитата(Lotor @ Apr 28 2012, 14:47) *
Я могу ошибаться, но смотрите, приоритет USART1_UDRE_vect выше чем USART1_TX_vect. И т.к. последнее разрешено всегда, то оно может вклиниться в неподходящий момент. Вот и потеря данных. Вообщем, самое простое - это переписать для начала код, чтобы использовалось одно прерывание USART1_TX_vect. Если потери исчезнут - то будете знать, где копать.

Не особо понял на счёт применения только одного прерывания USART1_TX_vect. Проблема ещё актуальна, не победил sad.gif
Go to the top of the page
 
+Quote Post
Lotor
сообщение May 5 2012, 04:34
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866



Цитата(Volldemar @ May 4 2012, 15:40) *
Не особо понял на счёт применения только одного прерывания USART1_TX_vect. sad.gif

Я предлагаю вам для поиска проблемы для начала использовать только это прерывание - переводите rs485 на передачу, в самом прерывании выгребаете очередь, когда она будет пуста переводить rs485 на прием. Есть вероятность, что в такой реализации потери исчезнут.


--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th June 2025 - 21:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01512 секунд с 7
ELECTRONIX ©2004-2016