|
初学PC机串口编程,基于多线程,异步操作,事件驱动的控制台程序,
在VC6.0下编译通过,使用时不占用cpu时间,当有数据到达接收缓冲区时,读取数据,
如要发送数据,直接在主函数里面调用API的发送数据函数即可,
将代码贴上,希望高手不吝指点,以便提高我的编程能力!!!
// bn.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
void init_com(void);//定义串口初始化函数
DWORD WINAPI Thread1Proc(LPVOID lParam);//定义子线程函数
CRITICAL_SECTION com_cs;//定义临界变量对象
struct Thread_Data//定义一个结构类型,用于传参数给子线程
{
HANDLE hcom;
OVERLAPPED vcc;
};
unsigned char receive_data[50];//定义接收数据缓存
int main(int argc, char* argv[])
{
InitializeCriticalSection(&com_cs);//初始化临界变量
init_com(); //初始化串口
while(1)
{
Sleep(200);//使主线程挂起
}
return 0;
}
void init_com()
{
EnterCriticalSection(&com_cs);//进入临界段
//1. //////////////////////////////////////////////////////// 打开串口
HANDLE m_hCom = NULL;//定义一个句柄,用于打开串口
HANDLE hThread1 = NULL;//子线程句柄;
COMMTIMEOUTS TimeOuts;//定义超时结构
DCB dcb; //定义串口设备控制结构
OVERLAPPED wrOverlapped;//定义异步结构
static struct Thread_Data thread_data;//定义一个结构对象,用于给子线程传递参数
m_hCom = CreateFile("com1",GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hCom == INVALID_HANDLE_VALUE)
{
printf("CreateFile fail\n");
}
else
{
printf("CreateFile ok\n");
}
//2. ////////////////////////////////////////////////////////设置读写缓冲区
if(SetupComm(m_hCom,2048,2048))
{
printf("buffer ok\n");
}
else
{
printf("buffer fail\n");
}
//3. ///////////////////////////////////////////////设置串口操作超时
//memset(&TimeOuts,0,sizeof(TimeOuts));
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutConstant = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 1000;
TimeOuts.WriteTotalTimeoutConstant = 1000;
TimeOuts.WriteTotalTimeoutMultiplier = 1000;
if(SetCommTimeouts(m_hCom,&TimeOuts))
{
printf("comm time_out ok!\n");}
//4. /////////////////////////////////////////////////////////设置串口参数
if (GetCommState(m_hCom,&dcb))
{
printf("getcommstate ok\n");
}
else
{
printf("getcommstate fail\n");
}
////////////
dcb.DCBlength = sizeof(dcb);
if (BuildCommDCB("9600,n,8,1",&dcb))//填充DCB的数据传输率、奇偶校验类型、数据位、停止位
{
printf("buildcommdcb ok\n");
}
else
{
printf("buildcommdcb fail\n");
}
////////////
if(SetCommState(m_hCom,&dcb))
{
printf("setcommstate ok\n");
}
else
{
printf("setcommstate fail\n");
}
//5. ///////////////////////////////////////////////////////////////////初始化异步结构
ZeroMemory(&wrOverlapped,sizeof(wrOverlapped));
wrOverlapped.Offset = 0;
wrOverlapped.OffsetHigh = 0;
if (wrOverlapped.hEvent != NULL)
{
ResetEvent(wrOverlapped.hEvent);
}
wrOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建手工复位事件
///////////////////////////创建一个线程//////////////////////////////////////////
thread_data.vcc = wrOverlapped;
thread_data.hcom = m_hCom;///////////////////////////////////////
hThread1=CreateThread(NULL,0,Thread1Proc,(LPVOID)&thread_data,0,NULL); //『注意』创建线程
LeaveCriticalSection(&com_cs);//推出临界段
}
DWORD WINAPI Thread1Proc(LPVOID lParam) //线程的执行函数
{
Thread_Data* pThread_Data = (Thread_Data*)lParam;///将线程函数参数给新定义的结构指针
HANDLE com= pThread_Data->hcom;////通过新定义的结构指针使用原结构的成员
OVERLAPPED wrOverlapped1 = pThread_Data->vcc;/////通过新定义的结构指针使用原结构的成员
COMSTAT ComStat ;///定义一个串口状态结构对象,给结构有10个参数,第九个参数
/////DWORD cbInQue;表示出入缓冲区有多少字节的数据到达,
DWORD word_count;//////存放实际读到的数据字节数存放
DWORD Event = 0;
DWORD CommEvtMask=0 ;
DWORD result;
DWORD error;
unsigned int k;
SetCommMask(com,EV_RXCHAR);//设置串口等待事件
while(1)
{
result = WaitCommEvent(com,&CommEvtMask,&wrOverlapped1);//等待事件函数
if(!result)
{
switch(error = GetLastError())
{
case ERROR_IO_PENDING :
{
break;
}
case 87:
{
break;
}
default:
{
break;
}
}
}
else
{
result = ClearCommError(com,&error,&ComStat);
if(ComStat.cbInQue == 0)
{
continue;
}
}
Event = WaitForSingleObject(wrOverlapped1.hEvent,INFINITE);//异步结果等待函数
EnterCriticalSection(&com_cs);
result = ClearCommError(com,&error,&ComStat);
if(ComStat.cbInQue == 0)
{
continue;
}
ReadFile(com,receive_data,ComStat.cbInQue,&word_count,&wrOverlapped1);//从系统接收缓冲区读出接收到得所有数据
LeaveCriticalSection(&com_cs);//推出临界段
printf("%s\n",receive_data);
for(k=0;k<50;k++)
{
receive_data[k] = 0x00;
}
}
return 0;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|