最近完成了一個項目,項目難度不大,但是過程中還是遇到了一些問題,特此記錄下來,以備不時之需。該項目實現了MCU控制一些LED燈的狀態,這個很簡單無需多講,MCU是通過串口通訊接收上位機APP的指令,然后再去根據指令執行控制LED的動作的。上位機APP是通過C#寫的,其實C#有自帶的串口控件,最簡單的方式是直接利用這個控件來實現通訊,但是為了方便客戶的開發,我還是決定做成一個可以調用的動態鏈接庫(DLL)來實現,后期用戶只需要參考我們的APP調用這個DLL就可以了。下面將講解如何完成DLL和APP的編寫,以及過程中遇到的一些問題。
1.動態鏈接庫(dll):
1.1 創建新項目
這里我使用的是VS2019,界面跟之前的版本有所不同:
這樣,一個工程就建好了,接下來編寫代碼。
1.2 代碼編輯:
1.2.1 創建好的項目中自帶一個dllmain.cpp文件,這個文件一般情況下不需要更改。
1.2.2 需要創建其他源文件或者頭文件,可以右擊“解決方案資源管理器”這一欄中的“源文件”或“頭文件”,選擇“添加”,選擇“新建項”。在本次項目中增加了4個文件,“WzSerialPort.h”,“WzSerialPort.cpp”,“SBC7835_DLL.cpp”,“SBC7835_DLL.h”,其中“WzSerialPort.h”和“WzSerialPort.cpp”是實現串口通訊功能的源文件和頭文件,“SBC7835_DLL.cpp”,“SBC7835_DLL.h”是應用層的代碼,是自定義的數據格式以及串口的開啟及關閉:
WzSerialPort.cpp:
#include "pch.h" #include "WzSerialPort.h" #include <stdio.h> #include <string.h> #include <WinSock2.h> #include <windows.h> WzSerialPort::WzSerialPort() { } WzSerialPort::~WzSerialPort() { } bool WzSerialPort::open(const char* portname, int baudrate, char parity, char databit, char stopbit, char synchronizeflag) { this->synchronizeflag = synchronizeflag; HANDLE hCom = NULL; if (this->synchronizeflag) { //同步方式 hCom = CreateFileA(portname, //串口名 GENERIC_READ | GENERIC_WRITE, //支持讀寫 0, //獨占方式,串口不支持共享 NULL,//安全屬性指針,默認值為NULL OPEN_EXISTING, //打開現有的串口文件 0, //0:同步方式,FILE_FLAG_OVERLAPPED:異步方式 NULL);//用於復制文件句柄,默認值為NULL,對串口而言該參數必須置為NULL } else { //異步方式 hCom = CreateFileA(portname, //串口名 GENERIC_READ | GENERIC_WRITE, //支持讀寫 0, //獨占方式,串口不支持共享 NULL,//安全屬性指針,默認值為NULL OPEN_EXISTING, //打開現有的串口文件 FILE_FLAG_OVERLAPPED, //0:同步方式,FILE_FLAG_OVERLAPPED:異步方式 NULL);//用於復制文件句柄,默認值為NULL,對串口而言該參數必須置為NULL } if (hCom == (HANDLE)-1) { return false; } //配置緩沖區大小 if (!SetupComm(hCom, 1024, 1024)) { return false; } // 配置參數 DCB p; memset(&p, 0, sizeof(p)); p.DCBlength = sizeof(p); p.BaudRate = baudrate; // 波特率 p.ByteSize = databit; // 數據位 switch (parity) //校驗位 { case 0: p.Parity = NOPARITY; //無校驗 break; case 1: p.Parity = ODDPARITY; //奇校驗 break; case 2: p.Parity = EVENPARITY; //偶校驗 break; case 3: p.Parity = MARKPARITY; //標記校驗 break; } switch (stopbit) //停止位 { case 1: p.StopBits = ONESTOPBIT; //1位停止位 break; case 2: p.StopBits = TWOSTOPBITS; //2位停止位 break; case 3: p.StopBits = ONE5STOPBITS; //1.5位停止位 break; } if (!SetCommState(hCom, &p)) { // 設置參數失敗 return false; } //超時處理,單位:毫秒 //總超時=時間系數×讀或寫的字符數+時間常量 COMMTIMEOUTS TimeOuts; TimeOuts.ReadIntervalTimeout = 1000; //讀間隔超時,該時間為串口每次接收等待的時間間隔,數據不多可以把該時間改小,這里每次等待1000mS間隔 TimeOuts.ReadTotalTimeoutMultiplier = 500; //讀時間系數 TimeOuts.ReadTotalTimeoutConstant = 5000; //讀時間常量 TimeOuts.WriteTotalTimeoutMultiplier = 500; // 寫時間系數 TimeOuts.WriteTotalTimeoutConstant = 2000; //寫時間常量 SetCommTimeouts(hCom, &TimeOuts); PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空串口緩沖區 memcpy(pHandle, &hCom, sizeof(hCom));// 保存句柄 return true; } void WzSerialPort::close() { HANDLE hCom = *(HANDLE*)pHandle; CloseHandle(hCom); } int WzSerialPort::send(const void* buf, int len) { HANDLE hCom = *(HANDLE*)pHandle; if (this->synchronizeflag) { // 同步方式 DWORD dwBytesWrite = len; //成功寫入的數據字節數 BOOL bWriteStat = WriteFile(hCom, //串口句柄 buf, //數據首地址 dwBytesWrite, //要發送的數據字節數 &dwBytesWrite, //DWORD*,用來接收返回成功發送的數據字節數 NULL); //NULL為同步發送,OVERLAPPED*為異步發送 if (!bWriteStat) { return 0; } return dwBytesWrite; } else { //異步方式 DWORD dwBytesWrite = len; //成功寫入的數據字節數 DWORD dwErrorFlags; //錯誤標志 COMSTAT comStat; //通訊狀態 OVERLAPPED m_osWrite; //異步輸入輸出結構體 //創建一個用於OVERLAPPED的事件處理,不會真正用到,但系統要求這么做 memset(&m_osWrite, 0, sizeof(m_osWrite)); m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, L"WriteEvent"); ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通訊錯誤,獲得設備當前狀態 BOOL bWriteStat = WriteFile(hCom, //串口句柄 buf, //數據首地址 dwBytesWrite, //要發送的數據字節數 &dwBytesWrite, //DWORD*,用來接收返回成功發送的數據字節數 &m_osWrite); //NULL為同步發送,OVERLAPPED*為異步發送 if (!bWriteStat) { if (GetLastError() == ERROR_IO_PENDING) //如果串口正在寫入 { WaitForSingleObject(m_osWrite.hEvent, 1000); //等待寫入事件1秒鍾 } else { ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通訊錯誤 CloseHandle(m_osWrite.hEvent); //關閉並釋放hEvent內存 return 0; } } return dwBytesWrite; } } int WzSerialPort::receive(void* buf, int maxlen) { HANDLE hCom = *(HANDLE*)pHandle; //if (this->synchronizeflag) //{ // //同步方式,這里因為發送用了同步,接收想用異步,又沒有重新初始化串口打開,就直接注釋掉用串口異步接收了 // DWORD wCount = maxlen; //成功讀取的數據字節數 // BOOL bReadStat = ReadFile(hCom, //串口句柄 // buf, //數據首地址 // wCount, //要讀取的數據最大字節數 // &wCount, //DWORD*,用來接收返回成功讀取的數據字節數 // NULL); //NULL為同步發送,OVERLAPPED*為異步發送 // if (!bReadStat) // { // return 0; // } // return wCount; //} //else { //異步方式,用同步會阻塞 DWORD wCount = maxlen; //成功讀取的數據字節數 DWORD dwErrorFlags; //錯誤標志 COMSTAT comStat; //通訊狀態 OVERLAPPED m_osRead; //異步輸入輸出結構體 //創建一個用於OVERLAPPED的事件處理,不會真正用到,但系統要求這么做 memset(&m_osRead, 0, sizeof(m_osRead)); m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, L"ReadEvent"); ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通訊錯誤,獲得設備當前狀態 if (!comStat.cbInQue)return 0; //如果輸入緩沖區字節數為0,則返回false BOOL bReadStat = ReadFile(hCom, //串口句柄 buf, //數據首地址 wCount, //要讀取的數據最大字節數 &wCount, //DWORD*,用來接收返回成功讀取的數據字節數 &m_osRead); //NULL為同步發送,OVERLAPPED*為異步發送 if (!bReadStat) { if (GetLastError() == ERROR_IO_PENDING) //如果串口正在讀取中 { //GetOverlappedResult函數的最后一個參數設為TRUE //函數會一直等待,直到讀操作完成或由於錯誤而返回 GetOverlappedResult(hCom, &m_osRead, &wCount, TRUE); } else { ClearCommError(hCom, &dwErrorFlags, &comStat); //清除通訊錯誤 CloseHandle(m_osRead.hEvent); //關閉並釋放hEvent的內存 return 0; } } return wCount; } }
WzSerialPort.h:
#pragma once #ifndef _WZSERIALPORT_H #define _WZSERIALPORT_H class WzSerialPort { public: WzSerialPort(); ~WzSerialPort(); // 打開串口,成功返回true,失敗返回false // portname(串口名): 在Windows下是"COM1""COM2"等,在Linux下是"/dev/ttyS1"等 // baudrate(波特率): 9600、19200、38400、43000、56000、57600、115200 // parity(校驗位): 0為無校驗,1為奇校驗,2為偶校驗,3為標記校驗(僅適用於windows) // databit(數據位): 4-8(windows),5-8(linux),通常為8位 // stopbit(停止位): 1為1位停止位,2為2位停止位,3為1.5位停止位 // synchronizeflag(同步、異步,僅適用與windows): 0為異步,1為同步 bool open(const char* portname, int baudrate, char parity, char databit, char stopbit, char synchronizeflag = 1); //關閉串口,參數待定 void close(); //發送數據或寫數據,成功返回發送數據長度,失敗返回0 int send(const void* buf, int len); //接受數據或讀數據,成功返回讀取實際數據的長度,失敗返回0 int receive(void* buf, int maxlen); private: int pHandle[16]; char synchronizeflag; }; #endif
SBC7835_DLL.cpp:
// SBC7835_DLL.cpp : 定義 DLL 應用程序的導出函數。 // #include "pch.h" #include "SBC7835_DLL.h" WzSerialPort w; uint8_t Check(uint8_t data[], uint8_t len) { uint32_t sum = 0; uint8_t ret; for (uint8_t i = 0; i < len; i++) { sum += data[i]; } ret = sum / len; return ret; } bool SBC7835_OpenCOM(const char* portname) { return w.open(portname, 115200, 0, 8, 1); } int SBC7835_CtrlLEDS(uint32_t color) { uint8_t sendData[6]; uint8_t recData[6]; int ret = 0; sendData[0] = 0xAA; sendData[1] = AllLEDCtrl; sendData[2] = color >> 16; sendData[3] = color >> 8; sendData[4] = color; sendData[5] = Check(sendData, 5); ret = w.send(sendData, 6); if (ret != 6) { return ret; } else { /*Sleep(10); ret = w.receive(recData, 6); if (ret != 6) { return false; } for (int i = 0; i < 6; i++) { if (recData[i] != sendData[i]) return false; }*/ return ret; } } bool SBC7835_CtrlOneLED(uint8_t num, uint8_t color) { uint8_t sendData[6]; uint8_t recData[6]; int ret = 0; sendData[0] = 0xAA; sendData[1] = OneLEDCtrl; sendData[2] = num; sendData[3] = color; sendData[4] = 0xff; sendData[5] = Check(sendData, 5); ret = w.send(sendData, 6); if (ret != 6) { return false; } else { /*Sleep(10); ret = w.receive(recData, 6); if (ret != 6) { return false; } for (int i = 0; i < 6; i++) { if (recData[i] != sendData[i]) return false; }*/ return true; } }
SBC7835_DLL.h
#ifndef SBC7835_DLL_H #define SBC7835_DLL_H #include "pch.h" #include <iostream> #include "WzSerialPort.h" #include "Windows.h" #ifdef SBC7835_EXPORTS #define SBC7835_API __declspec(dllexport) //聲明為DLL導出函數的宏定義 #else #define SBC7835_API __declspec(dllimport) #endif #define OneLEDCtrl 0x01 #define AllLEDCtrl 0x02 uint8_t Check(uint8_t data[], uint8_t len); extern "C" SBC7835_API bool SBC7835_OpenCOM(const char* portname); extern "C" SBC7835_API int SBC7835_CtrlLEDS(uint32_t color); extern "C" SBC7835_API bool SBC7835_CtrlOneLED(uint8_t num, uint8_t color); #endif
__declspec(dllexport)與__declspec(dllimport)是DLL內的關鍵字,表示導出和導入。
dllexport是在這些類、函數以及數據的申明的時候使用。用他表明這些東西可以被外部函數使用,即(dllexport)是把 DLL中的相關代碼(類,函數,數據)暴露出來為其他應用程序使用。使用了(dllexport)關鍵字,相當於聲明了緊接在(dllexport)關鍵字后面的相關內容是可以為其他程序使用的。
dllimport是在外部程序需要使用DLL內相關內容時使用的關鍵字。當一個外部程序要使用DLL 內部代碼(類,函數,全局變量)時,只需要在程序內部使用(dllimport)關鍵字聲明需要使用的代碼就可以了,即(dllimport)關鍵字是在外部程序需要使用DLL內部相關內容的時候才使用。(dllimport)作用是把DLL中的相關代碼插入到應用程序中。
_declspec(dllexport)與_declspec(dllimport)是相互呼應,只有在DLL內部用dllexport作了聲明,才能在外部函數中用dllimport導入相關代碼。
C#調用dll:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO.Ports; namespace SBC7835_APP { public partial class SBC7835 : Form { [DllImport("SBC7835_DLL.dll", EntryPoint = "SBC7835_OpenCOM", CallingConvention = CallingConvention.Cdecl)] public static extern bool SBC7835_OpenCOM(string portname); [DllImport("SBC7835_DLL.dll", EntryPoint = "SBC7835_CtrlLEDS", CallingConvention = CallingConvention.Cdecl)] public static extern bool SBC7835_CtrlLEDS(UInt32 color); [DllImport("SBC7835_DLL.dll", EntryPoint = "SBC7835_CtrlOneLED", CallingConvention = CallingConvention.Cdecl)] public static extern bool SBC7835_CtrlOneLED(byte num, byte color); int Count = 0; const byte LED1 = 0; const byte LED2 = 1; const byte LED3 = 2; const byte LED4 = 3; const byte LED5 = 4; const byte LED6 = 5; const byte LED7 = 6; const byte LED8 = 7; const byte LED9 = 8; const byte LED10 = 9; const byte LED11 = 10; const byte LED12 = 11; const byte LED_OFF = 0x00; const byte LED_RED = 0x01; const byte LED_GREEN = 0x02; const byte LED_BLUE = 0x03; public SBC7835() { InitializeComponent(); string[] PortName = SerialPort.GetPortNames(); for(int i = 0;i<PortName.Count();i++) { SerialPort_comboBox.Items.Add(PortName[i]); } LED1_comboBox.SelectedIndex = 0; LED2_comboBox.SelectedIndex = 0; LED3_comboBox.SelectedIndex = 0; LED4_comboBox.SelectedIndex = 0; LED5_comboBox.SelectedIndex = 0; LED6_comboBox.SelectedIndex = 0; LED7_comboBox.SelectedIndex = 0; LED8_comboBox.SelectedIndex = 0; LED9_comboBox.SelectedIndex = 0; LED10_comboBox.SelectedIndex = 0; LED11_comboBox.SelectedIndex = 0; LED12_comboBox.SelectedIndex = 0; } void OpenCOM() { string Com = SerialPort_comboBox.Text; try { if (SBC7835_OpenCOM(Com) != true) { MessageBox.Show("SBC7835 Open COM Failed!", "Warning"); } } catch (Exception ex) { MessageBox.Show("SBC7835 Open COM Error:" + ex.ToString(), "ERROR"); } } private void Manual_button_Click(object sender, EventArgs e) { UInt32 color = 0; if (LED_OFF_radioButton.Checked == true) color = 0; else if (LED_RED_radioButton.Checked == true) color = 0x555555; else if (LED_GREEN_radioButton.Checked == true) color = 0xAAAAAA; else if (LED_BLUE_radioButton.Checked == true) color = 0xFFFFFF; try { if (SBC7835_CtrlLEDS((UInt32)color) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(),"ERROR"); } } private void Auto_button_Click(object sender, EventArgs e) { timer1.Interval = 1000; timer1.Start(); } private void timer1_Tick(object sender, EventArgs e) { UInt32 color = 0; Count++; if (Count >= 4) Count = 0; if (Count == 0) color = 0; else if (Count == 1) color = 0x555555; else if (Count == 2) color = 0xAAAAAA; else if (Count == 3) color = 0xffffff; try { if (SBC7835_CtrlLEDS((UInt32)color) != true) { if (Count == 0) { timer1.Stop(); return; } MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } else if(Count == 0) { LED_OFF_radioButton.Checked = true; timer1.Stop(); } else if (Count == 1) { LED_RED_radioButton.Checked = true; } else if (Count == 2) { LED_GREEN_radioButton.Checked = true; } else if (Count == 3) { LED_BLUE_radioButton.Checked = true; } } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED1_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED1,LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED1_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED1, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED1_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED1, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED1_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED1, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED2_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED2, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED2_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED2, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED2_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED2, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED2_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED2, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED3_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED3, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED3_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED3, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED3_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED3, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED3_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED3, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED4_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED4, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED4_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED4, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED4_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED4, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED4_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED4, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED5_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED5, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED5_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED5, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED5_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED5, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED5_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED5, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED6_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED6, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED6_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED6, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED6_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED6, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED6_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED6, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED7_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED7, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED7_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED7, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED7_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED7, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED7_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED7, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED8_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED8, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED8_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED8, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED8_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED8, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED8_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED8, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED9_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED9, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED9_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED9, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED9_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED9, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED9_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED9, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED10_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED10, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED10_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED10, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED10_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED10, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED10_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED10, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED11_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED11, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED11_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED11, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED11_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED11, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED11_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED11, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED12_OFF_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED12, LED_OFF) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED12_RED_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED12, LED_RED) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED12_GREEN_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED12, LED_GREEN) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void LED12_BLUE_radioButton_CheckedChanged(object sender, EventArgs e) { try { if (SBC7835_CtrlOneLED(LED12, LED_BLUE) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void All_LED_Ctrl_button_Click(object sender, EventArgs e) { Int32 color = 0; /*將所有LED燈的狀態存放到color變量中,每一個LED的狀態占用2個bit,如 [bit1:bit0] * 表示LED1的狀態,0表示熄滅,1表示紅色,2表示綠色,3表示藍色。其他 的LED通理*/ color |= (LED1_comboBox.SelectedIndex << (0 * 2)); color |= (LED2_comboBox.SelectedIndex << (1 * 2)); color |= (LED3_comboBox.SelectedIndex << (2 * 2)); color |= (LED4_comboBox.SelectedIndex << (3 * 2)); color |= (LED5_comboBox.SelectedIndex << (4 * 2)); color |= (LED6_comboBox.SelectedIndex << (5 * 2)); color |= (LED7_comboBox.SelectedIndex << (6 * 2)); color |= (LED8_comboBox.SelectedIndex << (7 * 2)); color |= (LED9_comboBox.SelectedIndex << (8 * 2)); color |= (LED10_comboBox.SelectedIndex << (9 * 2)); color |= (LED11_comboBox.SelectedIndex << (10 * 2)); color |= (LED12_comboBox.SelectedIndex << (11 * 2)); try { if (SBC7835_CtrlLEDS((UInt32)color) != true) MessageBox.Show("SBC7835 Send CMD Failed", "Warning"); } catch (Exception ex) { MessageBox.Show("SBC7835 Ctrl LEDS Error:" + ex.ToString(), "ERROR"); } } private void OpenCOM_button_Click(object sender, EventArgs e) { OpenCOM(); } } }
過程中遇到過一個問題,就是串口發送數據的時候總會失敗,但是其他項目中也是通過這種方式去實現串口通訊的,代碼上應該沒有問題,所以
有點百思不得其解,直到我打開任務管理器,看到后台在運作的任務管理器中的串口助手,才知道串口被占用了。只要把串口助手關掉即可。
另外,C#上有一個簡單的方法可以把設備上所有可用的串口列舉出來的方法,代碼如下:
using System.IO.Ports;
string[] PortName = SerialPort.GetPortNames(); for(int i = 0;i<PortName.Count();i++) { SerialPort_comboBox.Items.Add(PortName[i]); }