最近完成了一個項目,項目難度不大,但是過程中還是遇到了一些問題,特此記錄下來,以備不時之需。該項目實現了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]); }
