Tôi đã thực hiện một số lượng đáng kể công việc với các chip FTDI trên máy Mac, vì vậy tôi có thể cung cấp một chút thông tin chi tiết tại đây. Tôi đã sử dụng các biến thể kênh đơn và kênh đôi của bộ chuyển đổi nối tiếp USB và tất cả chúng đều hoạt động theo cùng một cách.
FTDI có cả trình điều khiển cổng COM ảo, tạo cổng COM nối tiếp trên hệ thống của bạn đại diện cho kết nối nối tiếp được gắn với chip và thư viện truyền thông trực tiếp D2XX của chúng. Bạn sẽ muốn làm việc với cái sau, trong đó can be downloaded from their site for various platforms.
Thư viện D2XX dành cho máy Mac có một tệp .dylib độc lập (mới nhất là libftd2xx.1.2.2.dylib) hoặc một thư viện tĩnh mới mà chúng bắt đầu giao hàng gần đây. Bao gồm trong gói đó sẽ là các tập tin tiêu đề thích hợp bạn cần (ftd2xx.h và WinTypes.h) là tốt.
Trong dự án Xcode của bạn, thêm .dylib làm khuôn khổ để liên kết và thêm tệp ftd2xx.h, WinTypes.h và ftd2xx.cfg vào dự án của bạn. Trong giai đoạn xây dựng Bản dựng khung được sao chép của bạn, hãy đảm bảo rằng libftd2xx.1.2.2.dylib và ftd2xx.cfg có mặt trong giai đoạn đó. Bạn cũng có thể cần phải điều chỉnh đường dẫn tương đối mà thư viện này mong đợi, để thư viện hoạt động trong gói ứng dụng của bạn, vì vậy bạn có thể cần phải chạy lệnh sau dựa vào dòng lệnh:
install_name_tool -id @executable_path/../Frameworks/libftd2xx.1.2.2.dylib libftd2xx.1.2.2.dylib
Sau khi dự án được cấu hình đúng cách, bạn sẽ muốn nhập các tiêu đề FTDI:
#import "ftd2xx.h"
và bắt đầu kết nối với thiết bị nối tiếp của bạn. Ví dụ bạn liên kết đến trong câu hỏi của bạn có mẫu C++ có thể tải xuống cho biết cách họ liên lạc với thiết bị của họ. Bạn có thể mang theo hầu như tất cả mã C được sử dụng ở đó và đặt nó trong ứng dụng Objective-C của bạn. Họ chỉ xem xét việc sử dụng các lệnh FTDI D2XX tiêu chuẩn, được mô tả chi tiết trong phạm vi có thể tải xuống D2XX Programmer's Guide.
Đây là một số mã mà tôi đã nâng lên từ một trong những ứng dụng của tôi, sử dụng để kết nối với một trong những thiết bị này:
DWORD numDevs = 0;
// Grab the number of attached devices
ftdiPortStatus = FT_ListDevices(&numDevs, NULL, FT_LIST_NUMBER_ONLY);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Unable to list devices");
return;
}
// Find the device number of the electronics
for (int currentDevice = 0; currentDevice < numDevs; currentDevice++)
{
char Buffer[64];
ftdiPortStatus = FT_ListDevices((PVOID)currentDevice,Buffer,FT_LIST_BY_INDEX|FT_OPEN_BY_DESCRIPTION);
NSString *portDescription = [NSString stringWithCString:Buffer encoding:NSASCIIStringEncoding];
if (([portDescription isEqualToString:@"FT232R USB UART"]) && (usbRelayPointer != NULL))
{
// Open the communication with the USB device
ftdiPortStatus = FT_OpenEx("FT232R USB UART",FT_OPEN_BY_DESCRIPTION,usbRelayPointer);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't open USB relay device: %d", (int)ftdiPortStatus);
return;
}
//Turn off bit bang mode
ftdiPortStatus = FT_SetBitMode(*usbRelayPointer, 0x00,0);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't set bit bang mode");
return;
}
// Reset the device
ftdiPortStatus = FT_ResetDevice(*usbRelayPointer);
// Purge transmit and receive buffers
ftdiPortStatus = FT_Purge(*usbRelayPointer, FT_PURGE_RX | FT_PURGE_TX);
// Set the baud rate
ftdiPortStatus = FT_SetBaudRate(*usbRelayPointer, 9600);
// 1 s timeouts on read/write
ftdiPortStatus = FT_SetTimeouts(*usbRelayPointer, 1000, 1000);
// Set to communicate at 8N1
ftdiPortStatus = FT_SetDataCharacteristics(*usbRelayPointer, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE); // 8N1
// Disable hardware/software flow control
ftdiPortStatus = FT_SetFlowControl(*usbRelayPointer, FT_FLOW_NONE, 0, 0);
// Set the latency of the receive buffer way down (2 ms) to facilitate speedy transmission
ftdiPortStatus = FT_SetLatencyTimer(*usbRelayPointer,2);
if (ftdiPortStatus != FT_OK)
{
NSLog(@"Electronics error: Can't set latency timer");
return;
}
}
}
Ngắt kết nối khá đơn giản:
ftdiPortStatus = FT_Close(*electronicsPointer);
*electronicsPointer = 0;
if (ftdiPortStatus != FT_OK)
{
return;
}
Viết vào thiết bị nối tiếp sau đó khá dễ dàng:
__block DWORD bytesWrittenOrRead;
unsigned char * dataBuffer = (unsigned char *)[command bytes];
//[command getBytes:dataBuffer];
runOnMainQueueWithoutDeadlocking(^{
ftdiPortStatus = FT_Write(electronicsCommPort, dataBuffer, (DWORD)[command length], &bytesWrittenOrRead);
});
if((bytesWrittenOrRead < [command length]) || (ftdiPortStatus != FT_OK))
{
NSLog(@"Bytes written: %d, should be:%d, error: %d", bytesWrittenOrRead, (unsigned int)[command length], ftdiPortStatus);
return NO;
}
(command
là một NSData và runOnMainQueueWithoutDeadlocking()
chỉ đơn thuần là a convenience function I use to guarantee execution of a block on the main queue).
Bạn có thể đọc byte thô từ giao diện nối tiếp sử dụng giống như sau:
NSData *response = nil;
DWORD numberOfCharactersToRead = size;
__block DWORD bytesWrittenOrRead;
__block unsigned char *serialCommunicationBuffer = malloc(numberOfCharactersToRead);
runOnMainQueueWithoutDeadlocking(^{
ftdiPortStatus = FT_Read(electronicsCommPort, serialCommunicationBuffer, (DWORD)numberOfCharactersToRead, &bytesWrittenOrRead);
});
if ((bytesWrittenOrRead < numberOfCharactersToRead) || (ftdiPortStatus != FT_OK))
{
free(serialCommunicationBuffer);
return nil;
}
response = [[NSData alloc] initWithBytes:serialCommunicationBuffer length:numberOfCharactersToRead];
free(serialCommunicationBuffer);
Vào cuối những điều trên, response
sẽ là một ví dụ NSData chứa các byte bạn đã đọc từ cổng.
Ngoài ra, tôi khuyên bạn nên luôn truy cập thiết bị FTDI từ chuỗi chính. Mặc dù họ nói rằng họ hỗ trợ truy cập đa luồng, tôi đã tìm thấy rằng bất kỳ loại truy cập không chính-chủ (thậm chí đảm bảo truy cập độc quyền từ một chủ đề duy nhất) gây ra tai nạn liên tục trên máy Mac.
Ngoài các trường hợp tôi đã mô tả ở trên, bạn có thể tham khảo hướng dẫn lập trình D2XX cho các chức năng khác mà FTDI cung cấp trong thư viện C của chúng. Một lần nữa, bạn chỉ cần chuyển qua mã thích hợp từ các mẫu đã được nhà sản xuất thiết bị cung cấp cho bạn.
"Trình điều khiển" bạn đang nói về [có vẻ sẵn có tại trang FTDI Chip] (http://www.ftdichip.com/Drivers/VCP.htm) và tôi không biết bất kỳ mục tiêu nào " C "các ứng dụng mẫu cụ thể, nhưng nếu bạn có thể sử dụng bất kỳ mã mẫu MacOS nào sử dụng C hoặc C++, thì nó cũng sẽ hoạt động trong ứng dụng Objective C. –
Vâng, tôi đã cố gắng tìm một mã mẫu MacOS trong C hoặc C++ .... – objectiveccoder001
Không chắc chắn nếu nó giúp, nhưng có thể đáng xem [ofxDmx] (https://github.com/kylemcdonald/ofxDmx) hoặc khối kết dính [DMXusbPro] (https://github.com/q-depot/Cinder-DMXusbPro) –