[英]Windows COM Communication via CDC COM Port to Arduino
我剛剛購買了 SparkFun Pro Micro ( https://www.sparkfun.com/products/12640 ),並嘗試在 Windows 10 上使用 ReadFile 和 WriteFile 與其通信。
我已經用 Stellaris、Tiva、Arduino Mega 甚至 Arduino Leonardo 測試並運行了我的代碼,幾乎沒有問題(它工作正常)。 但是,我無法使用微型 USB 電纜和我自己的自定義程序從 Pro Micro 發送任何數據或在我的計算機上接收數據。 我可以使用 Arduino 串行監視器來發送和接收數據就好了。 我也可以使用 PuTTY 終端。 Arduino IDE 和 PuTTY 中的波特率似乎對使用 Pro Micro 發送/接收數據的能力沒有影響。
我希望能夠使用我自己的程序發送和接收數據,因為我將它用作數據記錄、后處理和實時圖形/顯示的服務器。 如果這個項目不需要更小的硬件包,我會使用 Arduino Mega,但遺憾的是,這不是一個選擇。
我正在 Windows 10 上編譯,使用 Visual Studio 2015。我還使用帶有 SparkFuns 插件/驅動程序的官方 Arduino IDE,v1.6.7(更新到 1.6.8,有同樣的問題)。
這是我連接到 COM 端口的代碼,我嘗試了各種波特率以及 BAUD_XXXX 宏:
*port = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); //CreateFile(TEXT("COM8:"), ...
if (*port == INVALID_HANDLE_VALUE){
printf("Invalid handle\n");
return(1);
}
/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB); ///< Initialize the DCBlength member
GetCommState(*port, &portDCB); ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200; ///< Current baud
portDCB.fBinary = TRUE; ///< Binary mode; no EOF check
portDCB.fParity = FALSE; ///< Disable parity checking
portDCB.fOutxCtsFlow = FALSE; ///< No CTS output flow control
portDCB.fOutxDsrFlow = FALSE; ///< No DSR output flow control
portDCB.fDtrControl = DTR_CONTROL_DISABLE; ///< Disable DTR flow control type
portDCB.fDsrSensitivity = FALSE; ///< DSR sensitivity
portDCB.fTXContinueOnXoff = TRUE; ///< XOFF continues Tx
portDCB.fOutX = FALSE; ///< No XON/XOFF out flow control
portDCB.fInX = FALSE; ///< No XON/XOFF in flow control
portDCB.fErrorChar = FALSE; ///< Disable error replacement
portDCB.fNull = FALSE; ///< Disable null stripping
portDCB.fRtsControl = RTS_CONTROL_DISABLE; ///< Disable RTS flow control
portDCB.fAbortOnError = FALSE; ///< Do not abort reads/writes on error
portDCB.ByteSize = 8; ///< Number of bits/byte, 4-8
portDCB.Parity = NOPARITY; ///< 0-4 = no, odd, even, mark, space
portDCB.StopBits = ONESTOPBIT; ///< 0, 1, 2 = 1, 1.5, 2
if (!SetCommState(*port, &portDCB)){
printf("Error Configuring COM Port\n");
return(1);
}
GetCommTimeouts(*port, &comTimeOut);
comTimeOut.ReadIntervalTimeout = 20;
comTimeOut.ReadTotalTimeoutMultiplier = 10;
comTimeOut.ReadTotalTimeoutConstant = 100;
comTimeOut.WriteTotalTimeoutMultiplier = 10;
comTimeOut.WriteTotalTimeoutConstant = 100;
SetCommTimeouts(*port, &comTimeOut);
我的讀寫功能:
char inChar(HANDLE port){
char output = 0;
DWORD noOfBytesRead = 0;
int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
if (retval == 0) {
return (0);
}
return(output);
}
void outChar(HANDLE port, char output){
DWORD bytesTransmitted = 0;
char buffer[] = { output, 0 };
WriteFile(port, buffer, 1, &bytesTransmitted, NULL);
}
我有這個來測試PC上的通信:
while (1) {
outChar(portHandle, 'b');
inchar = inChar(portHandle);
printf("%c", inchar);
}
在 Arduino 上:
void setup(){Serial.begin(115200);}
void loop(){
Serial.read();
Serial.println('a');
delay(10);
}
Arduino 上的 Rx LED 瘋狂閃爍,但 Tx LED 什么也不做,這表明只有數據以一種方式傳輸。 我做了其他測試,我發現 Arduino 正在讀取正確的信息(如果輸入字符是特定字符,則通過閃爍 LED 進行測試)但它不會向我的程序發送任何內容(不使用 Arduino 時的 PC 端) IDE 或 PuTTY)。
在 PuTTY 中,無論 Arduinos Serial.begin() 如何,我都能夠以任何波特率啟動 COM 通信。 8 個數據位,1 個停止位,無奇偶校驗,無流量控制,與我在 Visual Studio 中的設置相同。
編輯:我想如果我不自己配置它,我只會捎帶從 PuTTy 遺留下來的 COM 配置,所以我修改了我的代碼並刪除了所有多余的:
/// COM Port Configuration
portDCB.DCBlength = sizeof(DCB); ///< Initialize the DCBlength member
GetCommState(*port, &portDCB); ///< Get the default port setting information.
/// Change the DCB structure settings
portDCB.BaudRate = 115200; ///< Current baud
portDCB.ByteSize = 8; ///< Number of bits/byte, 4-8
portDCB.Parity = NOPARITY; ///< 0-4 = no, odd, even, mark, space
portDCB.StopBits = ONESTOPBIT; ///< 0, 1, 2 = 1, 1.5, 2
/*
portDCB.fBinary = TRUE; ///< Binary mode; no EOF check
portDCB.fParity = FALSE; ///< Disable parity checking
portDCB.fOutxCtsFlow = FALSE; ///< No CTS output flow control
portDCB.fOutxDsrFlow = FALSE; ///< No DSR output flow control
portDCB.fDtrControl = DTR_CONTROL_DISABLE; ///< Disable DTR flow control type
portDCB.fDsrSensitivity = FALSE; ///< DSR sensitivity
portDCB.fTXContinueOnXoff = TRUE; ///< XOFF continues Tx
portDCB.fOutX = FALSE; ///< No XON/XOFF out flow control
portDCB.fInX = FALSE; ///< No XON/XOFF in flow control
portDCB.fErrorChar = FALSE; ///< Disable error replacement
portDCB.fNull = FALSE; ///< Disable null stripping
portDCB.fRtsControl = RTS_CONTROL_DISABLE; ///< Disable RTS flow control
portDCB.fAbortOnError = FALSE; ///< Do not abort reads/writes on error
*/
它與注釋代碼一起工作得很好,但為什么呢? 是什么讓這款 Pro Micro 與我使用過的其他微控制器如此不同? 我將逐一測試它們,直到我找出哪個負責,因為這只有在我第一次打開和關閉 PuTTY 中的端口后連接時才有效(不方便)。
當您在 Windows DCB 結構中禁用 RTS 控制時,SparkFun Pro Micro 不喜歡它。
問題通過以下方式解決:
portDCB.fRtsControl = RTS_CONTROL_ENABLE; //was RTS_CONTROL_DISABLE
portDCB.fOutxCtsFlow = TRUE; //was FALSE
像往常一樣,忽略數據表中的重要信息是一個錯誤,我花了幾個小時閱讀寄存器信息,試圖確認我出錯的地方或原因,答案很簡單,如數據表中 USART 設備的功能列表所示:
USART:
...
• Flow control CTS/RTS signals hardware management
...
char inChar(HANDLE port){
char output = 0;
DWORD noOfBytesRead = 0;
int retval = ReadFile(port, &output, 1, &noOfBytesRead, NULL);
if (retval == NULL) {
return (NULL);
}
return(output);
}
這是不正確的,因為您將 retval(它是 int)與 NULL 進行比較,並且您的函數返回 NULL 作為 char 函數的返回值。 盡管我不認為這會導致報告的問題,但應該對其進行更改。
在此處查看已接受的答案。 我建議您從 PC 端的工作示例開始,然后將其減少到您的需要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.