FT232: Как подружить 1-wire с компом

Некоторые из них хочется подключить к компу. Но как? Неужели придется делать какой-то преобразователь на МК, или ставить специальную микросхему?!
Нет, все гораздо проще. Передавая через UART байты с разным коэфф. заполнения можно получить нужные по длительности импульсы. Таким образом можно эмулировать 1-wire. Идея в общем-то довольно известная, но я о ней узнал недавно, и думаю, что не только я один :)
Для того, чтобы UART порт мог работать как 1-wire, нужно прицепить пару деталей:
С RX мы будем принимать данные, которые сами передаем + изменения, вносимые слейвом. TX подключен так, чтобы не было конфликтов уровней на линии (когда TX в лог единице, а слейв тянет линию вниз). Плату под такое делать рука не поднимается, поэтому я применил скилл говноляпства:
Чтобы UART мог генерировать импульсы нужной длины, нам придется хитро переключать скорости:
RESET передаем так: бодрейт — 9600, предаем 0xF0. В случае если слейв сказал «привет», получим не то, что отправили.

Единичка (или чтение): бодрейт 115200, передаем 0xFF. Если слейв потянул линию вниз — получим что-то меньшее.

Ноль: бодрейт 115200, передаем 0x00.

--Все картинки я нагло скопипастил из аппноута от Максима.
Теперь, попробуем реализовать это на практике. Для примера я написал программу, которая опрашивает датчик DS18b20 и выдает на экран температуру:
Весь код приводить не буду, покажу лишь то, что связано с обменом данными.
Генерация RESET. Если кто-то откликнулся — функция возвращает true, иначе false.
function OneWire_reset: boolean;
begin
Result := false;
FT_Current_Baud := 9600;
FT_Current_DataBits := 8;
FT_Current_StopBits := FT_STOP_BITS_1;
FT_Current_Parity := FT_PARITY_NONE;
FT_Current_FlowControl := FT_FLOW_NONE;
Set_USB_Device_BaudRate;
Set_USB_Device_DataCharacteristics;
Set_USB_Device_FlowControl;
FT_Out_Buffer[0] := $F0;
Write_USB_Device_Buffer(1);
repeat
Get_USB_Device_QueueStatus;
until (FT_Q_Bytes > 0);
Read_USB_Device_Buffer(1);
if FT_In_Buffer[0] <> $F0 then Result := true;
end;
Передача 1 байта данных:
procedure OneWire_send_byte(DataToTransfer: byte);
var
tmp_b: byte;
i: integer;
begin
FT_Current_Baud := 115200;
Set_USB_Device_BaudRate;
for I := 0 to 7 do
if (DataToTransfer and (1 shl I)) <> 0 then
FT_Out_Buffer[i] := $FF
else
FT_Out_Buffer[i] := $00;
Write_USB_Device_Buffer(8);
//RX у нас замкнут на TX, поэтому данные придут обратно,
//и если их не прочитать - будут валяться в буфере FT232.
repeat
Get_USB_Device_QueueStatus;
until (FT_Q_Bytes >= 8);
Read_USB_Device_Buffer(8);
end;
Чтение байта:
function OneWire_read_byte(): byte;
var
tmp_b: byte;
i: integer;
begin
Result := 0;
FT_Current_Baud := 115200;
Set_USB_Device_BaudRate;
for I := 0 to 7 do
FT_Out_Buffer[i] := $FF;
Write_USB_Device_Buffer(8);
repeat
Get_USB_Device_QueueStatus;
until (FT_Q_Bytes >= 8);
Read_USB_Device_Buffer(8);
for I := 0 to 7 do
if FT_In_Buffer[i]<>$FF then
Result := Result or (1 shl I);
Result := not result;
end;
Остальной код + скомпилированную прогу можно взять тут. В папке _inc есть два ценных файла: One_wire.pas — реализация низкоуровневого обмена данными (ресет, чтение, запись); и DS18b20.pas — функции для работы с градусником. А вот, как это все работает:
P.S. Все вышесказаное применимо не только к FT232. Можно сделать тоже самое на железном COM порте или другом преобразователе…

- +14
- 23 мая 2011, 14:59
- dcoder
Уважаемый dcoder, а можно следующий пост по I2C + FT232? Картридж принтерный пора реверсить, а сниффить похоже надо на большой частоте.
А там точно I2C? У меня в принтере (HP LaserJet P1005) что-то типа 1-wire, а в некоторых что-то свое.
Послушать I2C (макс частота, ЕМНИП, 50кГц) и 1-wire можно вот этой приблудой. Первая версия на ком-порт, но oss хотел в близжайшее время выложить свою печатку с ft232.
А I2C + FT232 = мой мультипрог. (Живет вот в этой теме, все лень вытащить в отдельный пост). Но он только I2C мастер и мееедленный.
Послушать I2C (макс частота, ЕМНИП, 50кГц) и 1-wire можно вот этой приблудой. Первая версия на ком-порт, но oss хотел в близжайшее время выложить свою печатку с ft232.
А I2C + FT232 = мой мультипрог. (Живет вот в этой теме, все лень вытащить в отдельный пост). Но он только I2C мастер и мееедленный.
Похоже, что у меня одна из этих: www.maxim-ic.com/products/1-wire/consumable_print.cfm
Точно I2C. Причем с криптозащитой (Samsung ML-1865). Вот, хочу эмулятор чипа запилить, а то замена 10 баксов стоит, да и вообще — интересно же. Мультипрог погляжу, спасибо, может и разогнать смогу :).
А зачем общаться фт-хой через D2XX? Здесь же обычный уарт, можно работать через виртуальный комп-порт, насколько я вижу. А значит — использовать любой другой USB->UART или ком-порт без изменения кода.
D2XX удобен тем, что через него ДиХальтовая версия AVR-программатора работает. И бит-банг тоже, на сколько я понял. А каждый раз переставлять дрова — лишний геморой…
Дрова переставлять не нужно. Максимум фт-шку передернуть. По крайней мере я спокойно прошивал проц на пинборде фт-шным программатором, передергивал питание (это нужно чтобы шлейф программатор-МК без опаски сдернуть) и после включения с фт-шкой можно спокойно работать как с комом. А возможно — даже и передергивание не требуется.
Не требуется. Я так и работаю — нажал в терминале «отключить», запустил дудку — перепрошилось, нажал в терминале «подключить», всё ок.
Правда если контроллер по дурости начинает очень много гадить в сериал порт, то дудка запускается через раз на десятый. Иногда приходится пинцетом на ресет её затыкать.
Правда если контроллер по дурости начинает очень много гадить в сериал порт, то дудка запускается через раз на десятый. Иногда приходится пинцетом на ресет её затыкать.
собрал, но не работает(не определяется датчик-ступор полный ) брал первый попавшийся диод, подозреваю его, на каких диодах у вас работает?
Комментарии (35)
RSS свернуть / развернуть