FT232 это не только USB <> UART (Часть 2) - CBUS bit bang

gmens.JPG

До FT232R в микросхемах FTDI было всего два вида битбанга — синхронный и асинхронный.
Отличались они друг от друга тем, что в синхронном режиме данные читались с пинов и записывались одновременно (как в SPI), а в асинхронном скапливались в буфере сами-по себе с указаной скоростью.

Но в FT232R добавились 5 ножек с настраиваемым функционалом и на них тоже решили сделать Bit Bang. Получилось, честно говоря, не очень. Битбанг на CBUS работает значительно медленнее, чем его синхронный и асинхронный аналоги. Тем не менее, для неспешного ножкодрыгательства он вполне сгодится. Да и работать с ним проще, чем с двумя другими.

Сегодня в качестве примера построим себе умный дом. Да-да, самый настоящий. Со светодиодным освещением, датчиком освещенности и вентилятором для охлаждения пользователя :) Управляться все это будет, естественно, от компьютера через FT232R.

Для начала определимся с подключением.
FT232 может давать нам сигнал с лог уровнями 0 и +5V. Мой датчик освещенности из фотодиода и компаратора можно подключить напрямую к микросхеме. Я его повесил на ножку CBUS0.

smart_house2.JPG
sensor.PNG

Неведомую декоративную херню светодиодный фонарь для дачи подключим через ULN2003 на ножку CBUS1:

redlight.JPG
led_drive.PNG

На случай если придется управлять 220В нагрузкой, у меня заготовлена TTL-совместимая розетка:

ttl_rozetka.JPG
ttl_rozetka_s.PNG

Разъемчик "+ -" идет на вход оптопары, которая дергает симистор. К нему подключим обычный совковый вентилятор. А вывод CBUS2 будет им рулить.

ВНИМАНИЕ! Надо настроить пины CBUS0, CBUS1 и CBUS2 на bit bang режим. Если не настроить — фокус не получится.
И установить D2XX драйвер. Без него тоже фокус не получится.

Для управления всей этой компанией нам понадобится пара кнопок: на свет и вентилятор. И еще таймер, по которому, каждые 2-3 секунды мы будем опрашивать датчик освещенности. Получился вот такой пульт управления:

smart_house1.PNG

Теперь перейдем к коду.
При запуске программы (точнее, при создании окна) определяем — подключен-ли FTDI. Их может быть много, но мы смотрим только на самый первый в списке. Если он подключен — выводим название на экран и открываем модуль.

if GetFTDeviceDescription(0) <> FT_OK then
  begin
   Label4.Caption := 'FTDI: НЕ НАЙДЕНО';
   Label4.Hint := '';
   Label4.font.Color := clRed;
   
   Button1.Enabled := false;
   Button2.Enabled := false;
   Button3.Enabled := false;
   Button4.Enabled := false;
   CheckBox1.Enabled := false;
  end
  else
  begin
   Label4.Caption := 'FTDI: '+FT_Device_String;
   Label4.Hint := FT_Device_string;
   Label4.font.Color := clGreen;

   ReadTimer.Enabled := true;
   Open_USB_Device_By_Device_Description(FT_Device_string);
  end;

Пара комментариев к коду:
— Функция GetFTDeviceDescription принимает в качестве параметра номер FTDI-девайса (начиная с нуля), если все хорошо возвращает FT_OK. То зачем её вызывали (строка с названием устройства) будет лежать в переменной FT_Device_String.
Open_USB_Device_By_Device_Description получает в качестве параметра название устройства (которое мы только-что добыли) и открывает к нему доступ.

Вся работа с ножками CBUS осуществляется с помощью двух функций:
FT_SetBitMode. В качестве первого параметра принимает идентификатор устройства (после открытия он у нас лежит в FT_Handle). Второй параметр — байт, старшая половина которого определяет направление порта, а младшая — значения, которые в этот порт выводятся. Встроенной подтяжки нет, поэтому если задать направление = 0, а значение = 1, то это ни к чему не приведет. Третий параметр — магическое число 0x20 — означает режим CBUS bit bang.
FT_GetBitMode. Принимает идентификатор устройства и указатель на байт, в который драйвер положит значения пинов. Зачем было передавать в качестве параметра указатель, который в четыре раза больше, чем то, на что он указывает — неизвестно. Из того, что она возвращает смысл имеют только младшие 4 бита — это и есть значения пинов.

Чтобы не писать 4 обработчика для кнопок, я заюзал свойство tag. Это переменная типа integer, которая есть у каждого компонента. Полностью отдана в распоряжение программиста — её значение никак не влияет на компонент. У кнопочек ВЫКЛ оставим tag = 0, а у ВКЛ запишем туда 1. Теперь в общем обработчике для кнопок, управляющих светом, пишем:

procedure TForm1.Light_ctrl(Sender: TObject);
var
tmp_b: byte;
begin
FT_GetBitMode(FT_Handle,@tmp_b);
tmp_b := tmp_b and (not CBUS1);
if TButton(Sender).Tag=1 then
begin
 tmp_b := tmp_b or CBUS1;
 Label2.Font.Color := clRed;
end
else
begin
 Label2.Font.Color := clBlack;
end;

FT_SetBitMode(Ft_Handle, CBUS2_out or CBUS1_out or (tmp_b and $0f) ,$20);
end;


Что происходит:
Берем значения пинов. Продавливаем маской бит CBUS0. Берем tag того компонента, который вызвал обработчик. Если он = 1, то устанавливаем бит CBUS1.

В поддержку международной кампании по борьбе с магическими числами и прочей НЕХ я использовал удобные константы для работы с пинами CBUS:

const
  CBUS3_out=$80;
  CBUS2_out=$40;
  CBUS1_out=$20;
  CBUS0_out=$10;

  CBUS3=$08;
  CBUS2=$04;
  CBUS1=$02;
  CBUS0=$01;

Первые 4 позволяют настроить направление порта, а последние — значение. Если мы, к примеру хотим настроить все, кроме CBUS2 на выход, и закинуть в CBUS1 единичку, то вызываем FT_SetBitMode(Ft_Handle, CBUS3_out+CBUS1_out+CBUS0_out+CBUS1, $20);

Для кнопок вентилятора тоже самое, но вместо CBUS1 пищем CBUS2. Можно было сделать еще хитрожопнее и написать один обработчик на все 4 кнопки (храня в tag и номер пина и значение), но тогда код станет менее читаемым, а это плохо.

Обработчик для таймера выглядит так:

procedure TForm1.ReadSensor(Sender: TObject);
var
tmp_b: byte;
begin
FT_GetBitMode(FT_Handle,@tmp_b);

if tmp_b and CBUS0=0 then
 begin
  Label5.Caption := 'Темно';
  Label5.Font.Color := clBlack;

  if checkbox1.Checked then
   if tmp_b and CBUS1=0 then Button1.Click;
 end
 else
 begin
  Label5.Caption := 'Светло';
  Label5.Font.Color := clGreen;
 end;
end;


Тут все просто:
Читаем значения пинов. Если выход сенсора = 0, то выводим надпись «темно». И если при этом стоит флажек (автоматическое управление), и свет не включен, то включаем его, эмулируя нажатие на кнопку ВКЛ. Если на дворе светло — просто выводим надпись.

При закрытии окна (событие OnClose) закрываем устройство функцией Close_USB_Device, for the great justice.

Вот так. Ничего сложного. Пара функций открытия/закрытия устройства, еще пара для битбанга.
В следующей серии будет асинхронный битбанг. А между сериями реклама тоже самое, что и здесь, только в LabView.

Исходники программы прикреплены к статье… наверное…
Работает вот так:


Как обычно, немного полезностей:
Аппноуты:
AN_232R-01 — бит банг режимы в FT232 и FT245.
D2XX Programmer's Guide — описание функций драйвера D2XX

Софт:
Пример по работе с CBUS на дельфи.
Куча других примеров живет тут.

  • +8
  • 24 мая 2011, 17:22
  • dcoder
  • 1
Файлы в топике: CBUS_example.zip

Комментарии (23)

RSS свернуть / развернуть
Схему включения приложил бы. А то каких то дебилоидов с флажками воткнул, а схему нет :)
0
И схемы внешних модулей тоже. Датчик освещенности, управлялка фонариком, ттл-розетка.
0
Прилепил.
0
Гм. Схемы кстати говоря не конкретные. Особенно фотодатчик.
А зачем дырко на лицевой стороне ттл розетки?
И ULN2003 — попахивает стрельбой из пушки по воробьям. Достаточно транзистора с резистором. На одноваттный СИД вообще потянет биполярник в ТО-92.
0
А зачем дырко на лицевой стороне ттл розетки?
Там раньше была кнопка и светодиод. Управлялось это все от МК. Потом разобрал и розетка валялась без дела. Сейчас хочу сделать модуль на 3 розетки с датчиками тока, и zero-crossing детектором.
И ULN2003 — попахивает стрельбой из пушки по воробьям.
Когда собираешь за 5 минут из готовых модулей — и не такое бывает :)
0
но человечков то оставить можно прикольные ))))))))))
+2
  • avatar
  • oss
  • 24 мая 2011, 19:16
Да я против них ничего собстна не имею. Пущай махают.
0
читаю название статьи
вижу там «USB <> UART»
а в мозгах-усб не равно уарт))))) логично черт подери
вот до чего программирование доводит совсем дауном становлюсь))))
спасиб за статью
0
не в тему статьи, но хотелось бы увидеть что-то вроде обучалки написания подобных приложений для компа. что-то вроде обзора, по которому чайник в моем лице сможет написать приложение с кнопкой.
0
Про то, как рисовать окошко с кнопкой написана не одна книга. Например «Библия Delphi» М. Фленова. Хорошая, годая книжка описывает все начиная от рисования кнопок и заканчивая COM портом и сетью.
0
Гм. Фленов. Не-не, по дельфи надо советовать Тексейру и Пачеко или Марко Кэнту, но никак не Фленова. Сам я правда начинал с более другой книжки, но уж ее-то точно никому не посоветую.
0
Слить книги этих авторов на русском можно у Подгорецкого. Находится в Библиотека->Чужие работы. И вообще, стоит по сайту полазить. Кстати, я ошибся, «Тейксейра», а не «Тексейра».
0
А чем по-твоему Фленов плох? На мой взгяд для начала норм книга.
0
Я его библию почитал краем глаза когда уже нормально разбирался в программировании и оценил как сомнительную. Кроме того, это мнение разделяют если не все, то большинство специалистов по дельфи — не читайте Фленова и Архангельского. А названные мной — классика, признанная всеми. Сборка Delphi Lite например напрямую советует почитать их вместо выкинутого хелпа.
А для начала и того хуже, привьет читателю тараканов Фленова и хрен знает когда они еще вытравятся. Может и никогда, Дейкстра вон вообще программеров начавших с бейсика и фортрана за людей не считал.
0
Например «Библия Delphi» М. Фленова. Хорошая, годая книжка описывает все начиная от рисования кнопок и заканчивая COM портом и сетью.
С хорошими, годными примерами, как за пять строк добавить в программу утечки памяти, потери указателей, забыть (или забить) про декструкторы объектов и подобные трудноуловимые ошибки…

Реально там много ляпов.
0
От себя советую эту книгу: delphikingdom.com/asp/book.asp?BookID=270
Являюсь обладателем её за победу в конкурсе, так же знаю автора по конференции. Человек грамотный, и книга написана не для «срубить бабла».
0
Да, слышал о ней. Но это книга «для продолжающих». А начинающим лучше скурить Кэнту.
С хорошими, годными примерами
А также с тараканами в духе «хайль ASPack» и другими. Глава про уменьшение размера ехе делала меня facepalm. Хотя есть и правильные идеи, в духе «оптимизируй там, где эффект максимален, а затраты минимальны». Но в целом, начинающим вредно, а продолжающие и так все это знают.
0
люто, бешно реквестирую примеры на LabView!
0
Будут.
Просто щас началась пора Еб**ых Гос. Экзаменов (ЕГЭ), потому я немного занят. Числа этак до 14. С перерывами, в которые скорее всего буду вдали от интернетов. :)

На данный момент готов пример, узнающий название устройства и открывающий его.
0
ок, хорошо тебе экзамены сдать желаю. Поступать куда думаешь?
0
Я, конечно, извиняюсь, но для тупых могли бы схемку и воткнуть, тем более ди халт упоминал об этом…
0
Прошло уже три года. Где схема. В моей молодости девки также делали… раздроч-знят и просят денег. SWG все тайны унес с собой. А вам оно такое надо? Уважаемый dcoder, я Вас очень боюсь, но все-же схему в студию!
0
  • avatar
  • Aks
  • 28 августа 2013, 12:54
О Великий DI HALT!
0
  • avatar
  • Aks
  • 28 августа 2013, 12:56
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.