Управление FT232RL с компьютера

Введение

Микросхема 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. 


У вас недостаточно прав для комментирования.