首页
社区
课程
招聘
[旧帖] [求助]求助!!!关于Windows api实现串口通信 0.00雪花
发表于: 2009-12-10 13:16 1517

[旧帖] [求助]求助!!!关于Windows api实现串口通信 0.00雪花

2009-12-10 13:16
1517
这两周实训,我们的任务是用Windows api实现串口通信。那位大侠能给点帮助??
首先先考虑到我只学过java,在网上凑到的都是C++实现的,那些变量真把我看得头大!
能否给我完整代码??  感激不尽!!一点建议也行。菜鸟很迷茫!
汇编怎么实现呢??

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 14
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
如果用DOS,那一切都简单了,就是in/out端口啦,处理IRQ中断什么的。
但windows下都是保护模式了,不能直接对串口操作。
用文件操作函数像CreateFile等进行操作。

VC++代码见这里:
http://www.codeproject.com/KB/system/SerialPortComm.aspx

要用汇编实现,把上面这个project编译成汇编就好了,看不懂就调试程序,在createfile处设一个断点,停在那点右键切换到deassembly view就可以看到汇编了。
C的代码跟汇编几乎可以一一对应的
2009-12-11 01:51
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
对不起,我这两天有事,没怎么上!好心人 !我一定会记住你们的!!!
我把我找到的代码发出来大家给我支支招,多谢了
后天就该交作业了,主要是我没学过C++,只要能让他运行就行!!
先让它运行下,呵呵,我绝对是超级菜鸟 ,高手们多考虑一下我的情况 尽量详细一点
谢谢了
//Mycom.h
UINT CommWatchProc(LPVOID pParam); // 串口监视线程函数
  class CMyCom
  {
  public:
   CMyCom();
   ~CMyCom();
   BOOL SetupMyCom(); // 初始化端口
   BOOL WriteMyCom(LPVOID lpSndBuffer, DWORD dwBytesToWrite); // 写端口
   DWORD ReadMyCom(LPVOID lpInBuffer, DWORD dwBytesToRead=35); // 读端口
   void CloseMyCom(); // 关闭端口
  };
//Mycom.cpp
BOOL CMyCom::SetupMyCom()
  {
   DCB dcb;
   COMMTIMEOUTS timeouts;
  
   if(bOpen)return FALSE; // 串口被占用
   // 打开COM1
   hComDev = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL,
   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if(hComDev == INVALID_HANDLE_VALUE)
   {
   // MessageBox(NULL, _T("端口被占用,打印程序不能继续运行!"), _T("TRACE"), MB_OK);
   return FALSE; // 打开端口失败
   }
   // 设置超时控制
   SetCommTimeouts(hComDev, &timeouts);
   // 设置接收缓冲区和输出缓冲区的大小
   SetupComm(hComDev, 1024, 512);
   // 获取缺省的DCB结构的值
   GetCommState(hComDev, &dcb);
   // 设定波特率为9600 bps
   dcb.BaudRate = CBR_9600;
   // 设定无奇偶校验
   dcb.fParity = NOPARITY;
   // 设定数据位为8
   dcb.ByteSize = 8;
   // 设定一个停止位
   dcb.StopBits = ONESTOPBIT;
   // 设定相应监视串口的错误和接收到字符两种事件响应
   SetCommMask(hComDev, EV_ERR|EV_RXCHAR);
   // 设置串行设备控制参数
   SetCommState(hComDev, &dcb);
   // 设置参数表示设备已打开
   bOpen = TRUE;
   // 创建一个人工重设,
   hEvent = CreateEvent(NULL, FALSE, FALSE, "WatchEvent");
   return TRUE;
  }
  
  // 数据发送
  // 数据发送利用WriteFile函数实现。对于同步I/O操作,它的最后一个参数可为
  // NULL;而对异步I/O操作,它的最后一个参数必需是一个指向OVERLAPPED结构的指针,
  // 通过OVERLAPPED结构来获得当前的操作状态。
  // lpSndBuffer为发送数据缓冲区指针,
  // dwBytesToWrite为将要发送的字节长度
  BOOL CMyCom::WriteMyCom(LPVOID lpSndBuffer, DWORD dwBytesToWrite)
  {
   BOOL bWriteState;
   DWORD dwBytesWritten; // 实际发送的字节数
   if(!bOpen)return FALSE; // 串口未打开
  bWriteState = WriteFile(hComDev, lpSndBuffer, dwBytesToWrite, &dwBytesWritten, NULL);
   if(!bWriteState || (dwBytesToWrite != dwBytesWritten))
   return FALSE; // 发送数据失败
   return TRUE;
  }
  // 数据接收
  // 接收数据的任务由ReadFile函数完成。该函数从串口接收缓冲区中读取数据,
  // 读取数据前,先用ClearCommError函数获得接收缓冲区中的字节数。接收
  // 数据时,同步
  // 和异步读取的差别同发送数据是一样的。
  // lpInBuffer为接收数据的缓冲区指针,
  // dwBytesToRead为准备读取的数据长度(即字节数)
  DWORD CMyCom::ReadMyCom(LPVOID lpInBuffer, DWORD dwBytesToRead)
  {
   BOOL bReadState;
   COMSTAT ComStat; // 串行设备状态结构
   DWORD dwBytesRead, dwErrorFlags;
   if(!bOpen)return 0; // 串口未打开
   // 用于读取串行设备的当前状态
   ClearCommError(hComDev, &dwErrorFlags, &ComStat);
   // 设定应该读取的数据长度
   dwBytesRead = min(dwBytesToRead, ComStat.cbInQue);
   // 读取数据
   if(dwBytesRead > 0)
  bReadState = ReadFile(hComDev, lpInBuffer, dwBytesRead, &dwBytesRead, NULL);
   if(!bReadState) // 返回数据失败
   dwBytesToRead = 0;
   // 返回所读取的数据
   return dwBytesRead;
  }
  // 关闭串行设备
  // 在整个应用程序结束或不再使用串行设备时,应将串行设备关闭,包括取消事
  // 件监视,将设备打开标志bOpen置为FALSE以使事件监视线程结束,清除发送/接收缓冲
  // 区和关闭设备句柄。
  void CMyCom::CloseMyCom()
  {
   bOpen = FALSE;
   // 取消事件监视,此时监视线程中的WaitCommEvent将返回
   SetCommMask(hComDev, 0);
   // 等待监视线程的结束
   WaitForSingleObject(hEvent, INFINITE);
   // 关闭事件句柄
   CloseHandle(hEvent);
   // 停止发送和接收数据,并清除发送和接收缓冲区
  PurgeComm(hComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|
  PURGE_RXCLEAR);
   // 关闭设备句柄
   CloseHandle(hComDev);
  }
  // 事件监视线程
  // 事件监视线程对串口事件进行监视,当监视的事件发生时,监视线程即运行
  UINT CommWatchProc(LPVOID pParam)
  {
   // pThread->m_bAutoDelete = TRUE;
   HWND hWnd = (HWND)pParam;
   char rbuf[1024]; // 用于接受串口数据
   char wbuf[1]; // 用于返回数据
   CString strtemp;
   DWORD read; // 保存串口缓冲区中的数据
   DWORD dwEventMask = 0; // 发生的事件
  
   while(bOpen) // 串口已被成功打开
   {
   WaitCommEvent(hComDev, &dwEventMask, NULL);
   if((dwEventMask & EV_RXCHAR) == EV_RXCHAR)
   {
   // 接收到字符,在此加入语句进行处理
   read = m_MyCom.ReadMyCom(rbuf);
   if(read > 0)
   {
   for(int i=0; i<(int)read; i++)
   {
   strtemp.Format("%c",rbuf[i]);
   recd += strtemp;
   }
   m_MyCom.WriteMyCom(wbuf, DWORD(1)); // 正确接收数据回写COM1端口数据1
   }
   }
   if((dwEventMask & EV_ERR) == EV_ERR)
   {
   MessageBox(NULL, _T("ComError"), _T("TRACE"), MB_OK);
   }
   }
  
   MessageBox(NULL, _T("ExitThread"), _T("TRACE"), MB_OK);
   SetEvent(hEvent);
   return 1;
  }
  
  CWinThread* pThread = AfxBeginThread(CommWatchProc, m_hWnd);
  // 串口监视进程的建立
  ::TerminateThread(pThread, 0); // 结束串口监视进程
  delete pThread; // 删除串口监视进程指针, 该语句可以省略
2009-12-16 19:51
0
游客
登录 | 注册 方可回帖
返回
//