Перейти к содержанию
    

использование управления потоком FT232BM

устройство на контроллере подключается через FT232BM к USB.

задача периодически пополнять внутренний буфер контроллера.

контроллер управляет медленным устройством.

 

поэтому если кидать данные без управления потоком, они теряются.

если с управлением потока, то вроде все нормально. но иногда все же теряется 1-4 байта.

 

использую DSR-DTR

 

делаю так.

в микроконтроллере.

 

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status;

DSR=1;

status=UCSRA;

rx_d=UDR;

rx_b=1;

//DSR=0;

}

 

main()

{

while(1)

{

if (rx_b)

{

rx_b=0;

get_ser();

}

}

}

 

void get_ser(void)

{

// обрабатываю полученный байт, заполнение буфера

delay_ms(500); // задержка, вроде как устройство занято. если эту задержку убрать, то вроде как работает, но с ней, байты теряются, из 20 посланных 1-2 теряются.

DSR=0;

}

 

 

на Delphi

 

 

procedure wait_tx;

begin

repeat

Get_USB_Device_ModemStatus;

Application.ProcessMessages;

until (FT_Modem_Status and $00000020) = $00000020;

end;

 

 

..........................

 

 

 

if Open_USB_Device<>FT_OK then begin exit; end;

Reset_USB_Device;

FT_Current_Baud:=FT_BAUD_38400;

Set_USB_Device_BaudRate;

 

FT_Current_FlowControl:=FT_FLOW_DTR_DSR;

FT_XON_Value:=0;

FT_XOFF_Value:=0;

if Set_USB_Device_FlowControl<>FT_OK then showmessage('Set_USB_Device_FlowControl');

 

Purge_USB_Device_Out;

Purge_USB_Device_IN;

 

 

...............

 

for i:=1 to n do

begin

for j:=0 to 100 do FT_Out_Buffer[j]:=mas[j];

wait_tx; // ждем разрешения DSR

Write_USB_Device_Buffer(100);

end;

 

 

 

т.е. я выдаю в порт по 100 байт.

как мне точно узнать что все 100 байт переданы и можно передавать следующие ?

 

 

пробовал передавать по одному байту, тоже теряются байты.

 

 

может есть где пример как правильно, или кто что может посоветует.

заранее спасибо.

 

 

 

==========================================================

 

ответ zltigo

Я все исходники написанные Вами не читал, но:

1. Контроллер после выставления им неготовности обязан принять как минимум один байт

2. Нарезка на байты/порции со стороны PC - побайтовая передача с flush после каждого байта/порции.

 

==========================================================

 

 

 

 

есть ли где информация как построен сам процес управления потоком?

а то велосипед изобретать как-то не очень получается :-)

 

или где можно почитать про это.

 

меня интересует. точнее нужно.

 

есть боьшой масив данных, его нужно передать в контроллер порциями (размером с буфер контроллера 100 байт)

причем контроллер может в любой момент замереть в ожидании события почти на две секунды.

 

так вот.

управление потоком немного облегчило жизнь, при использовании DTR DSR.

но программа на дельфи, которая выкидывает по 100 байт, не может толком понять, кидать ей следующие 100 байт или нет.

 

или лучше кидать по одному байту постоянно, и ждать пока он не дойдет до контроллера и контроллер не разрешит дальнейший обмен.

но тогда получается что это уже програмный контроль, а не аппаратный.

 

может есть гре пример нормальной работы или алгаритма работы.

 

заранее спасибо.

Изменено пользователем showone

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Берем лучшее из hdlc - байт стаффинги для контроля потока, берем лучшее из modbus - адресацию и CRC. Объединяем это и получаем помехозащищенный протокол с контролем потока. И не придется использовать сигнальные линии, плюс легко можно перенести на сеть устройств (485).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После DSR=0 :

- Стандартный UART com-порта PC выдает еще на выход 1 байт инфомации (заканчивает текущую передачу).

- FT232BM - выдает 2 байта (заканчивает текущую передачу + выдает еще 1 байт). Проверял только на скорости 19200.

 

В Делфи использую компонент ComPort Library by Dejan Crnila. Ставлю тайм - аут на передачу и пишу в ком-порт в асинхронном режиме. При необходимости можно использовать событие OnTxCompleate.

Изменено пользователем Александр Куличок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После DSR=0 :

- Стандартный UART com-порта PC выдает еще на выход 1 байт инфомации (заканчивает текущую передачу).

- FT232BM - выдает 2 байта (заканчивает текущую передачу + выдает еще 1 байт). Проверял только на скорости 19200.

 

В Делфи использую компонент ComPort Library by Dejan Crnila. Ставлю тайм - аут на передачу и пишу в ком-порт в асинхронном режиме. При необходимости можно использовать событие OnTxCompleate.

 

Это не совсем верно.

 

1) Всё идёт от 16550. Там фифо буфер (у первых) 16 байт. Поэтому после приостановки потока может быть отправлено десяток и более байт.

 

Лично я не проверял сколько, но приостанавливаю когда буфер заполнен не до конца байт 16.

 

2) Приостанавливать надо (если использовать аппаратное управление компьютера) сигналом CTS

RxU1:
    stsx    cbufe,X    ; и сохранить
    lds        wl,cbufbl; Определить объём свободного места
    lds        wh,cbufbh
    sub        wl,Xl    ; в буфере
    sbc        wh,Xh
    brcc    RxU2
    subi    wl,low(-lBuf); Откорректировать при перехлёсте
    sbci    wh,high(-lBuf); Откорректировать при перехлёсте
RxU2:
    tst        wh        ; Осталось меньше 16 байт?
    brne    RxUE    ; если нет, то выйти
    cpi        wl,16    ; Осталось меньше 16 байт?
    brsh    RxUE    ; если нет, то выйти

    sbi        portCTS,CTS; Сбросить готовность модема

 

3) В обратную сторону тоже надо проверять. Компьютер может снять готовность (и делает это) RTS.

    sbis    pinRTS,RTS    ; если убран RTS
    rjmp    onl31

 

4) При программном управлении потоком (так называемым Xoff/Xon обмене) используется два знаменитых символа

es22:    .db    17; XON
es23:    .db    19; XOFF

 

Естественно, что при программном управлении потока надо их убирать из потока. Поток также может оборваться не сразуже. Оно и понятно. Например при работе модема байт пять где-то бродят по проводам. Это я проверял лично.

 

Да и ещё на последок. Если используете HARD управление потоком, то позаботьтесь о выдаче готовности модема в линию, а то передача может и не начаться. Либо закольцуйте в вашем устройстве сигналы DSR/DTR.

    cbi        portDSR,DSR; постоянно выдавать готовность модема
    cbi        portMR,MR; и подсвечивать её
    sbi        portDCD,DCD; сбросить сигнал DCD

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) Приостанавливать надо (если использовать аппаратное управление компьютера) сигналом CTS

Извиняюсь, был неправ (думал одно - писал другое). Спасибо за поправку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

задача периодически пополнять внутренний буфер контроллера.

контроллер управляет медленным устройством.

Эти два пункта не означают, что нужен флоу-контроль, скорее наоборот. Пока медленное устройство медленно шевелится, контроллер может принимать данные от компьютера в фоне, и укладывать их в буфер. С помощью прерываний можно организовать тучу процессов.

Поэтому что-то тут с мотивировками не в порядке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эти два пункта не означают, что нужен флоу-контроль, скорее наоборот. Пока медленное устройство медленно шевелится, контроллер может принимать данные от компьютера в фоне, и укладывать их в буфер. С помощью прерываний можно организовать тучу процессов.

Поэтому что-то тут с мотивировками не в порядке.

 

получается такая фигня.

контроллер заполняет в фоне буфер, но в какой-то момент работы с устройством, получает по прерыванию от УАРТ байт, не успевает его обработать, получает следующий байт и этот второй байт теряется.

 

вот и хотелось сделать так, чтобы второй байт не отсылался из компа или буфера FTDI, пока не будет полностью обработан первый. т.е. управление потоком как я понимаю нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

получается такая фигня.

контроллер заполняет в фоне буфер, но в какой-то момент работы с устройством, получает по прерыванию от УАРТ байт, не успевает его обработать, получает следующий байт и этот второй байт теряется.

Да сделайте нормальный протокол, который будет гарантировать доставку и забудьте про эти символы..

 

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

Приходит символ, возникает прерывание, мы сразу вытаскиваем принятый символ из UDR, тут же анализируем стаффинги (если есть), здесь же считаем частичную CRC.. Анализируем условие окончания пакета. Если условие наступило - проверяем CRC, если CRC в порядке - размещаем пакет в очереди на обработку (если модбас - то проще никакой очереди нет т.к. может прийти только один пакет). (Мне вот непоятно, как же ж тут можно неуспеть обработать байт-то??)

 

После чего возвращаемся к исполнению прерванной программы...

 

Когда подходит время - переходим к обработке пакета: вытаскиваем данные, размещаем их в требуемом буфере, и формируем и отправляем подтверждение для компа. Если комп получает подтверждение, то шлет следующий пакет, если не получает, то через заданное время (Таймаут) поторяет текущий пакет, до тех пор пока не получит подтверждения..

 

Привожу иллюстрацию организации обмена:

post-12326-1178925665_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

получается такая фигня.

контроллер заполняет в фоне буфер, но в какой-то момент работы с устройством, получает по прерыванию от УАРТ байт, не успевает его обработать, получает следующий байт и этот второй байт теряется.

 

вот и хотелось сделать так, чтобы второй байт не отсылался из компа или буфера FTDI, пока не будет полностью обработан первый. т.е. управление потоком как я понимаю нужно.

А зачем байты обрабатывать? Положить в буфер и все. Мне трудно представить, как можно потерять байты.

Вот тут мой примерчик прерывания по приему для того, чтобы положить байты в буфер

http://electronix.ru/forum/index.php?showtopic=31415

 

Длительность прерывания намного меньше длительности байта. Если не происходит прерывание на следующий байт, значит оно запрещено во время работы с медленным устройством. Так разрешите, какие проблемы то?

 

Вообще-то теперь, с ростом производительности контроллеров, при непосредственном подключении двух устройств (то есть без модемов), контроль потока не используется, как правило, и Вы двигаетесь в сторону, противоположную техническому прогрессу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

всем большое спасибо за ответы !

нужно будет менять весь подход в программе по работе с УАРТ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем байты обрабатывать? Положить в буфер и все. Мне трудно представить, как можно потерять байты.

 

Потерять байт элементарно, хотя управление потоком здесь не при чём. Так например в моём нынешнем устройстве есть объёмное прерывание. Его нельзя отложить и разбить на части. Так вот это прерывание не должно превышать длительность прихода двух байт в AVR. Иначе произойдёт потеря. При скорости 115200 2 байта это всего лишь 173.6 мкс. На 14745600 это 2560 тактов. Не так и много если требуется математика к примеру.

 

На lpc, я уже посмотрел, имеется аппаратный буфер на 16 байт. Это хорошо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так например в моём нынешнем устройстве есть объёмное прерывание. Его нельзя отложить и разбить на части. Так вот это прерывание не должно превышать длительность прихода двух байт в AVR. Иначе произойдёт потеря.
У меня тоже есть такое прерывание. В нем я разрешаю вложенные. Точнее, вложенные я разрешаю во всех прерываниях (среди них одно длинное) кроме одного, которое терять нельзя и которое выполняется 90-115 тактов при периоде следования 128 тактов.
На lpc, я уже посмотрел, имеется аппаратный буфер на 16 байт. Это хорошо.
Тогда глянь еще на AT91SAM7, там DMA позволяет сделать аппаратный буфер на все ОЗУ :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...