自己动手编写串口动态库
手把手教你编写串口调试助手,单片机串口程序
一、串口库源码: 自行在vc6中建立动态库工程
#include \ #include
extern \ _declspec(dllexport) void Entry(char *comname, int BaudRate, HWND rhbox); extern \ _declspec(dllexport) bool openport(char *portname); extern \ _declspec(dllexport) bool setupdcb(int rate_arg);
extern \ _declspec(dllexport) void SetTimeOut(int a, int b, int c, int d, int e); //发送字符或16进制数
extern \ _declspec(dllexport) void SendChar(unsigned char ch); //显示方式:1:hex 0:char
extern \ _declspec(dllexport) void DisplayHex(int flag); extern \ _declspec(dllexport) void Close(); //只使用上面有注释的三个函数即可
HANDLE hComm;//串口的句柄
OVERLAPPED m_ov;//是一个包含了用于异步输入输出的信息的结构体 COMSTAT comstat;//包含串口结构信息 HANDLE hThread1; //读线程句柄 HANDLE hThread2; //写线程句柄 HWND hRbox;
bool sendflag = false;
unsigned char sendchar, receivechar; bool DisplayHEX = false;
ProcessErrorMessage(char* ErrorText)//打印进程错误信息 { }
/****************打开串口*********************/ bool openport(char *portname) {
char *Temp = new char[200]; LPVOID lpMsgBuf; FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL );
sprintf(Temp, \, MessageBox(NULL, Temp, \, MB_ICONSTOP); LocalFree(lpMsgBuf); delete[] Temp; return true;
(char*)ErrorText, lpMsgBuf, \);
}
hComm = CreateFile(portname,
GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
return FALSE; return true;
if (hComm == INVALID_HANDLE_VALUE) else
/****************设备控制块的设置*********************/ //参数 波特率rate_arg: 9600 bool setupdcb(int rate_arg) {
DCB dcb;
int rate = rate_arg;
memset(&dcb, 0, sizeof(dcb)); //申请一个DCB结构体空间 if (!GetCommState(hComm, &dcb))//获取当前DCB配置 { }
/* -------------------------------------------------------------------- */ // 配置当前串口
dcb.DCBlength = sizeof(dcb); /* ----------串口的配置 ------- */ dcb.BaudRate = rate; dcb.Parity = NOPARITY; dcb.fParity = 0;
dcb.StopBits = ONESTOPBIT; dcb.ByteSize = 8; dcb.fOutxCtsFlow = 0; dcb.fOutxDsrFlow = 0;
dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = 0; dcb.fInX = 0;
/* ------其他参数的设置 ----- */ dcb.fErrorChar = 0; dcb.fBinary = 1; dcb.fNull = 0;
ProcessErrorMessage(\);//打印错误信息 return FALSE;
}
dcb.fAbortOnError = 0; dcb.wReserved = 0; dcb.XonLim = 2; dcb.XoffLim = 4; dcb.XonChar = 0x13; dcb.XoffChar = 0x19; dcb.EvtChar = 0;
/* -------------------------------------------------------------------- */ // 用上面的设备控制块来设置当前串口 if (!SetCommState(hComm, &dcb)) { } else
return true;//设置成功
ProcessErrorMessage(\); return false;
/*******************超时的设置***************************/
bool setuptimeout(int ReadInterval, int ReadTotalMultiplier, int ReadTotalconstant, int WriteTotalMultiplier, int WriteTotalconstant) { }
void ReceiveChar() {
BOOL bRead = TRUE; BOOL bResult = TRUE; DWORD dwError = 0; DWORD BytesRead = 0; char RXBuff;//接收数据缓冲器 char str[10];
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = ReadInterval;
// 读间隔超时
timeouts.ReadTotalTimeoutConstant = ReadTotalconstant;// 读时间常量 timeouts.ReadTotalTimeoutMultiplier = ReadTotalMultiplier;// 读时间系数 timeouts.WriteTotalTimeoutConstant = WriteTotalconstant;// 写时间常量 timeouts.WriteTotalTimeoutMultiplier = WriteTotalMultiplier;// 写时间系数 if (!SetCommTimeouts(hComm, &timeouts)) { } else
return true;
ProcessErrorMessage(\); return false;
//设置当前串口的超时设置
for (;;)//死循环等待 {
Sleep(100);
bResult = ClearCommError(hComm, &dwError, &comstat);//清除硬件的通讯错误以及if (comstat.cbInQue == 0) {
bResult = ReadFile(hComm, // Handle to COMM port } else{ }
// printf(\打印接收到的数据 sprintf(str, \, RXBuff); SetWindowText(hRbox, str); &RXBuff, 1,
// RX Buffer Pointer
// Read one byte
continue; if (bRead)
获取通讯设备的当前状态
&BytesRead, // Stores number of bytes read &m_ov);
// pointer to the m_ov structure
if (DisplayHEX){
// printf(\打印接收到的数据 sprintf(str, \, RXBuff); SetWindowText(hRbox, str);
if (!bResult)//读不成功 { } else {
bRead = TRUE;
switch (dwError = GetLastError()) {
case ERROR_IO_PENDING: { } default: { } }
break;
bRead = FALSE; break;