Введение
Микросхема FT232RL имеет интересный режим работы - bit-bang mode. В этом режиме восемь выводов микросхемы превращаются в 8-ми разрядный порт общего назначения. Используя библиотеку фирмы ftdi, можно управлять этим портом с компьютера - читать и записывать в него данные. Также можно управлять в режиме бит банга выводами CBUS, но для этого нужно разрешать данный режим работы в EEPROM`e.
Как выяснилось на практике, управлять выводами FT232RL совсем не сложно. Я научился этому буквально за полчаса, хотя совсем не занимаюсь программированием для компа. В этом посте я расскажу о полученном опыте.
Что понадобится
Для написания программы я использовал Visual Studio Express 2012 для Windows Desktop. Ее можно скачать бесплатно с сайта Microsoft. Думаю, подойдет и C++ Builder, но у меня не оказалось его под рукой.
Для управления выводами FT232RL требуется библиотека ftd2xx.lib. На сайте ftdichip.com в разделе Drivers\D2XX Drivers нужно скачать архив с драйверами для своей операционной системы. В архиве есть еще один архив - CDM v2.08.30 WHQL Certified, который и содержит нужную библиотеку.
В качестве подопытной платы был задействован самодельный usb-uart переходник на FT232RL. Впрочем подойдет абсолютно любая плата на этой микросхеме, главное чтобы на контактные площадки были выведены все необходимые сигналы
Создание проекта в Visual Studio Express 2012
Открываем Visual Studio и в верхнем меню выбираем Файл > Создать Проект. В открывшемся окне выбираем Visual C++ - консольное приложение Win32. Обзываем проект и сохраняем его.
В следующем окне жмем Готово и у нас открывается пустой проект.
Первое, что нужно сделать - это добавить к проекту библиотеку ftd2xx.lib. Для этого копируем файлы ftd2xx.lib и ftd2xx.h в папку, где лежат исходники только что созданного проекта. Затем подключаем файл ftd2xx.lib к нашему проекту внутри среды разработки. С левой стороны в Visual Studio отображается иерархия проекта. Нужно кликнуть правой кнопкой мыши "Файлы исходного кода" и выбрать "Добавить" > "Существующий элемент" и указать файл ftd2xx.lib.
После этого с помощью директивы include включаем заголовочный файл ftd2xx.h в главный файл проекта. У меня это FTDI_test1.cpp.
Базовые функции библиотеки ftd2xx.lib
Функций для работы с FT232R в библиотеке довольно много. Все они подробно описаны в руководстве "D2XX Programmer's Guide".Чисто для ознакомления мне понадобились только 5 из них: FT_Open, FT_SetBitMode, FT_Write, FT_Read, FT_Close.
FT_STATUS FT_Open (int iDevice, FT_HANDLE *ftHandle) - открывает устройство, инициализирует переменную типа FT_HANDLE и возвращает результат выполнения этой функции типа FT_STATUS. Если функция выполнилась успешно, она возвратит FT_OK.
Принимает в качестве параметров индекс устройства и указатель на пустую переменную типа FT_HANDLE. Для одного устройства на FT232R индекс будет равен 0. Если устройств много, то в библиотеке есть специальная функция для получения списка устройств. ftHandle - эта некая переменная, с помощью которой происходят дальнейшие обращения к FT232R.
Пример:
FT_HANDLE handle;
...
if (FT_Open(0,&handle) == FT_OK){
cout <<"Device is open\n";
...
}
FT_STATUS FT_SetBitmode (FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucMode) - устанавливает режим работы выводов (вход или выход) и режим бит банга, возвращает результат выполнения функции.
В качестве параметров принимает инициализированную переменную типа FT_HANDLE, поэтому эту функцию нужно запускать после FT_Open(..). Второй принимаемый параметр - это битовая маска ucMask. Каждый бит ucMask определяет направление соответствующего вывода ft232r. 0 устанавливает вывод на вход, 1 - на выход. И третий параметр - байт ucMode, задающий режим работы бит банга. Есть два основных режима бит банга - это синхронный (0x04) и асинхронный (0x01). В синхронном режиме чтение данных из FT232R выполняется только когда происходит запись (при вызове функции FT_Write(..)). Причем сначала выполняется чтение, а потом в FT232R записываются новые данные.
Пример:
FT_HANDLE handle;
...
if (FT_Open(0,&handle) == FT_OK){
cout <<"Device is open\n";
/*все 8 выводов - выходы, синхр. режим*/
FT_SetBitMode(handle, 0xff, 0x04);
...
}
FT_STATUS FT_Write (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpdwBytesWritten) - запись данных в FT232R.
В качестве параметров принимает инициализированную переменную типа FT_HANDLE. lpBuffer - указатель на буфер, содержащий записываемые данные. dwBytesToWrite - количество байтов, которые нужно записать в устройство. lpdwBytesWritten - указатель на переменную, в которую сохранится количество записанных байтов.
Пример:
FT_HANDLE handle;
DWORD bytesWritten;
unsigned char buf;
...
if (FT_Open(0,&handle) == FT_OK){
cout <<"Device is open\n";
/*все 8 выводов - выходы, синхр. режим*/
FT_SetBitMode(handle, 0xff, 0x04);
buf = 0xff;
/*установить на всех выводах единицы*/
if (FT_Write(handle,&buf, 0, &bytesWritten){
cout <<"FT_Write OK\n";
...
}
...
}
FT_STATUS FT_Read (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpdwBytesReturned) - читает данные из FT232R.
В качестве параметров принимает инициализированную переменную типа FT_HANDLE. lpBuffer - указатель на буфер, в который сохранятся данные от устройства. dwBytesToRead - количество байтов, которые нужно прочитать. lpdwBytesReturned - указатель на переменную, в которую сохранится количество прочитанных байтов.
Пока что я разобрался только с чтением данных в синхронном бит банг режиме.
Пример:
unsigned char port = 0;
unsigned char statePort = 0;
DWORD numBytes = 0;
FT_HANDLE handle;
...
cout << "FTDI Bit Bang mode\n";
if(FT_Open(0, &handle) == FT_OK) {
/*установить направление выводов и синхронный режим бит банга*/
FT_SetBitMode(handle, ((1<<LED)|(0<<BUT)), 0x04);
/*чтение, а затем запись данных в ft232rl*/
FT_Write(handle, &port, 1, &numBytes);
/*чтение данных*/
FT_Read(handle, &statePort,1, &numBytes);
FT_STATUS FT_Close (FT_HANDLE ftHandle) - закрывает открытое устройство. Нужно запускать эту функцию после окончания работы с FT232R. Что произойдет, если проигнорировать это, я не знаю.
Пример:
FT_HANDLE handle;
...
if (FT_Open(0,&handle) == FT_OK){
cout <<"Device is open\n";
...
FT_Close(handle);
cout <<"Device is close\n";
}
Тестовый проект для FT232R
Схему для тестового проекта я собрал из USB-UART переходника, светодиода и кнопки.
Код тестового проекта представлен ниже. Программа настраивает один вывод FT232R на вход, а другой на выход и устанавливает синхронный бит банг. Далее в цикле происходит запись и чтение FT232R. Если кнопка нажата, то зажигается светодиод. Если кнопка удерживается некоторое время, то программа выходит из цикла.
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <windows.h>
#include "ftd2xx.h"
using namespace std;
#define LED 0
#define BUT 3
#define MODE 0x04
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char port = 0;
unsigned char statePort = 0;
unsigned int count = 0;
char buf = 0;
DWORD numBytes = 0;
FT_HANDLE handle;
cout << "FTDI Bit Bang mode\n";
if(FT_Open(0, &handle) != FT_OK) {
cout << "Can't open device\n";
}
else{
cout <<"Device is open\n";
/*установить направление выводов и режим бит банга*/
FT_SetBitMode(handle, ((1<<LED)|(0<<BUT)), MODE);
/*запись и чтение ft232rl*/
for(;;) {
FT_Write(handle, &port, 1, &numBytes);
FT_Read(handle, &statePort,1, &numBytes);
if (statePort & (1<<BUT)){
port &= ~(1<<LED);
count = 0;
}
else{
port |= (1<<LED);
count++;
/*если кнопка удерживается долго,
выходим из цикла*/
if (count > 200){
FT_Close (&handle);
cout << "Device is close.\n";
break;
}
}
}
}
return 0;
}
С функцией записи не возникло никаких проблем. И в синхронном и в асинхронном режимах бит банга она, по сути, используется одинаково. А вот с функцией чтения пришлось помучаться. Я получил от нее то, что мне нужно, только в синхронном режиме работы. Как было сказано выше, в синхронном бит банг режиме данные из ft232r читаются во время записи, то есть когда вызывается функция FT_Write(): сначала данные читаются, а потом производится запись. Когда вызывается FT_Read(), то мы получаем значение, которое было прочитано при вызове FT_Write(). Вроде так.
Заключение
Надеюсь мой пост поможет вам в освоении FT232R, ведь ее можно использовать в широком спектре приложений. Начиная от таких банальных вещей как управление нагрузками по USB, и заканчивая программаторами или 1-Wire, SPI, I2C адаптерами.
Ссылки
Описание библиотеки ft2xx.lib
Скачать библиотеку ft2xx.lib
Скачать Visual Studio Express
USB-UART переходник на FT232R
Файлы
ftdi-test.rar - проект для Visual Studio Express 2012. Чтобы запустить проект в студии, нужно нажать Ctrl + F5.