精华内容
下载资源
问答
  • API串口通信实例
    2020-12-29 07:38:42

    第一节

    实现串口通讯的函数及串口编程简介

    API

    函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操

    作。常用函数及作用下:

    函数名

    作用

    CreateFile

    打开串口

    GetCommState

    检测串口设置

    SetCommState

    设置串口

    BuilderCommDCB

    用字符串中的值来填充设备控制块

    GetCommTimeouts

    检测通信超时设置

    SetCommTimeouts

    设置通信超时参数

    SetCommMask

    设定被监控事件

    WaitCommEvent

    等待被监控事件发生

    WaitForMultipleObjects

    等待多个被监测对象的结果

    WriteFile

    发送数据

    ReadFile

    接收数据

    GetOverlappedResult

    返回最后重叠(异步)操作结果

    PurgeComm

    清空串口缓冲区

    ,

    退出所有相关操作

    ClearCommError

    更新串口状态结构体

    ,

    并清除所有串口硬件错误

    CloseHandle

    关闭串行口

    Windows API

    编写串口程序本身是有巨大优点的,因为控制能力会更强,效率也会更

    高。

    API

    编写串口,过程一般是这样的:

    1

    创建串口句柄,用

    CreateFile

    2

    对串口的参数进行设置,其中比较重要的是波特率(

    BaudRate

    ),数据宽度(

    BytesBits

    ),奇偶

    校验(

    Parity

    ),停止位(

    StopBits

    ),当然,重要的还有端口号(

    Port

    );

    3

    然后对串口进行相应的读写操作,这时候用到

    ReadFile

    WriteFile

    函数;

    4

    读写结束后,要关闭串口句柄,用

    CloseFile

    下面依次讲述各个步骤的过程。

    第二节

    创建串口句柄打开串口

    从字面上去理解,大家也可以发现

    CreateFile

    实际上表明

    Windows

    是把串口当作一个文件来处理的,所以

    它也有文件那样的缓冲区、句柄、读写错误等,不同的是,这个文件名字只有固定的几个(一般为四个),

    而且始终存在(

    EXSITING

    ),而且在调用

    CreateFile

    的时候请注意它的参数。

    CreateFile

    函数原型如下:

    更多相关内容
  • C#调用API串口通信

    2017-09-17 10:51:04
    C#调用API串口通信C#调用API串口通信C#调用API串口通信C#调用API串口通信C#调用API串口通信C#调用API串口通信
  • Delphi API 串口通信 多线程例子.rar
  • 本文章是关于Windows API串口通信编程概述。
  • C#串口通信、发送、监听串口数据,可以使用windows api或者C#自带serialPort通信
  • 很好的串口资料
  • 串口通信API

    2018-05-19 11:40:51
    串口同步读写函数库, 打开, 读写, 关闭。 可以实现串口的同步读写。
  • vs2010基于Win32API串口通信MFC实例

    千次阅读 2019-05-17 09:57:47
    介绍如何使用win32API函数进行通信端口的编程,因为串口数据接收需要不停地监视串口和处理串口事件,因此,再本实例中将其封装为单个线程执行类。 工程源代码在文章底部,群里。MFC_Win32API_同步串口.rar Win32API...

    vc++MFCvs2015Win32API_串口通信实例.rar源码-C++文档类资源-CSDN下载解压密码:blog.csdn.net/txwtech参考:https://blog.csdn.ne更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/txwtech/33372165

    介绍如何使用win32API函数进行通信端口的编程,因为串口数据接收需要不停地监视串口和处理串口事件,因此,再本实例中将其封装为单个线程执行类。

    工程源代码在文章底部,群里。MFC_Win32API_同步串口.rar       Win32API_串口通信实例.rar

    测试用的虚拟串口软件也在群文件里面。

    创建串口线程类并初始化,由CThreadCom1对象的构造函数完成,它实现串口工作变量的初始化工作。

    CThreadCom1::CThreadCom1(HANDLE hCom)
    {
    	m_hCom=hCom;
    	m_bInit=false;
    	m_sCom="";
    	m_sError="No Error!";
    	m_hThread=NULL;
    	m_dwSendMsgToParent=0;
    	m_dwRecvMsgToParent=0;
    	m_pWndParent=NULL;
    	memset((unsigned char*)&m_overRead,0,sizeof(OVERLAPPED));
    	memset((unsigned char*)&m_overWrite,0,sizeof(OVERLAPPED));
    	m_overRead.hEvent=CreateEvent(NULL,true,false,NULL);
    	m_overWrite.hEvent=CreateEvent(NULL,true,false,NULL);
    	
    }
    
    CThreadCom1::~CThreadCom1()
    {
    	CloseHandle(m_overRead.hEvent);
    	CloseHandle(m_overWrite.hEvent);
    }
    
    BOOL CThreadCom1::InitInstance()
    {
    	// TODO: 在此执行任意逐线程初始化
    	m_bAutoDelete=false;
    	m_bDone=false;
    	return TRUE;
    }
    
    int CThreadCom1::ExitInstance()
    {
    	// TODO: 在此执行任意逐线程清理
    	BOOL bFlag=CloseCom();
    	return CWinThread::ExitInstance();
    }

    串口接收线程的处理工作由CThreadCom1对象的Run()函数完成。它实现

    循环从串口读取数据,并将接收的数据发送给处理函数的功能。

    int CThreadCom1::Run(void)//重载线程类的Run()运行函数
    {
    	//return 0;
    	DWORD dwError,dwReadNum,dwByteRead,dwEvent;
    	COMSTAT	ComStat;//串口状态变量
    	BYTE rBuf[MAXCOMINBUF];//输入缓冲区
    	while(!m_bDone)
    	{
    		while(m_hCom!=INVALID_HANDLE_VALUE)
    		{
    			if(::WaitCommEvent(m_hCom,&dwEvent,NULL))//等待注册的串口事件发生
    			{
    				dwByteRead=0;//初始化读字节数
    				if(dwEvent&EV_RXCHAR)
    				{
    					ClearCommError(m_hCom,&dwError,&ComStat);//清空当前串口事件
    					if(ComStat.cbInQue!=0)//输入列队中的数据个数
    					{
    						dwReadNum=ComStat.cbInQue;
    						dwByteRead=0;
    						if(dwReadNum>200)
    							dwReadNum=200;
    						memset(rBuf,0,sizeof(rBuf));//清空接收缓冲区变量
    						DWORD i=::ReadFile(m_hCom,rBuf,dwReadNum,&dwByteRead,&m_overRead);
    						for(i=dwByteRead;i<1024;i++)
    							rBuf[i]=0;//用0x00填充剩余字节
    					}
    				}
    				if(dwByteRead)
    					if(m_pWndParent)
    						m_pWndParent->SendMessage(m_dwRecvMsgToParent,(DWORD)rBuf,dwByteRead);//读取的数据发送到父窗口
    						
    			}
    
    		}
    		Sleep(1000);
    	}
    	return CWinThread::Run();//调用基类的Run()函数
    }

    //打开串口,根据程序配置,打开指定工作串口的功能

    BOOL CThreadCom1::OpenCom(CString strCom, CWnd* pWndParent, DWORD dwSendMsgToParent, DWORD dwRecvMsgToParent)
    {
    	//return 0;
    	CloseCom();
    	CString strLog;
    	m_hCom=::CreateFile(strCom,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);//打开串口
    	if(m_hCom==INVALID_HANDLE_VALUE)
    	{
    		strLog.Format("Open %s Error",strCom);
    		AfxMessageBox(strLog);
    		return FALSE;
    	}
    	::SetupComm(m_hCom,MAXCOMINBUF,MAXCOMOUTBUF);//设置串口输入输出缓冲区
    	DCB dcb;//定义DCB结构
    	if(!GetCommState(m_hCom,&dcb))
    	{
    		AfxMessageBox("获取串口状态错误");
    		CloseHandle(m_hCom);
    		m_hCom=INVALID_HANDLE_VALUE;
    		return FALSE;
    	}
    	if(!SetCommState(m_hCom,&dcb))
    	{
    		CloseHandle(m_hCom);
    		m_hCom=INVALID_HANDLE_VALUE;
    		strLog.Format("set %s CommState Error!",strCom);
    		AfxMessageBox(strLog);
    		return FALSE;
    	}
    	//
    
    	m_sError="No Error";	
    	m_pWndParent	=	pWndParent;//存储父窗口句柄
    	m_dwSendMsgToParent	= dwSendMsgToParent;//存储接收发送消息的父窗口
    	m_dwRecvMsgToParent	= dwRecvMsgToParent;//存储接收接收消息的父窗口
    
    
    
    	//
    	DWORD CommMask;
    	CommMask=0|EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_EVENT1|EV_EVENT2|EV_PERR|EV_RING|EV_RLSD|EV_RX80FULL|EV_RXCHAR|EV_RXFLAG|EV_TXEMPTY;
    	::SetCommMask(m_hCom,CommMask);//注册要处理的事件
    	::GetCommTimeouts(m_hCom,&m_Commtimeout);//读取超时时间设置
    	m_Commtimeout.ReadTotalTimeoutMultiplier=5;
    	m_Commtimeout.ReadTotalTimeoutConstant=100;
    	m_bInit=true;
    	return TRUE;
    
    
    }
    

    //关闭串口

    BOOL CThreadCom1::CloseCom(void)
    {
    	//return 0;
    	if(m_hCom!=INVALID_HANDLE_VALUE)
    	{
    		PurgeComm(m_hCom,PURGE_RXCLEAR);//释放串口事件
    		CloseHandle(m_hCom);
    		m_hCom=INVALID_HANDLE_VALUE;//设置句柄无效
    	}
    	m_bInit=false;
    	return true;
    }

    //发送数据

    BOOL CThreadCom1::SendData(BYTE* s, DWORD dwLen)
    {
    	//return 0;
    	if(!dwLen)
    		return false;
    	::GetCommTimeouts(m_hCom,&m_Commtimeout);
    	m_Commtimeout.WriteTotalTimeoutMultiplier=0;//设置读操作超时时间
    	m_Commtimeout.WriteTotalTimeoutConstant=2*dwLen;//设置读操作超时常量
    
    	::SetCommTimeouts(m_hCom,&m_Commtimeout);//设置超时时间设置
    	if(m_hCom!=INVALID_HANDLE_VALUE)
    	{
    		DWORD dwSend;
    		m_pWndParent->SendMessage(m_dwSendMsgToParent,(DWORD)s,dwLen);
    	//发送日志
    		if(!WriteFile(m_hCom,s,dwLen,&dwSend,&m_overWrite))//向串口发送数据
    		{
    			m_sError="串口发送数据失败";
    			return false;
    		}
    		return true;
    	}
    	else
    	{
    		m_sError="串口句柄无效";
    		return false;
    	}
    }

    串口线程类代码结束后。界面的处理,对话框类中,实现相关按钮触发事件。

    对话框类头文件相关声明:

    public:
    //	CString m_Log;
    	CString m_editSend;
    	CString m_editReceive;
    	CComboBox m_comboComm;
    	afx_msg void OnBnClickedButtonOpenserial();
    	CThreadCom1* pThreadCom; 
    	BOOL m_bCom;
    	void WriteLog(CString log);
    	afx_msg void OnBnClickedButtonSend();
    //	void OnSendMsg(DWORD dwEvent, DWORD dwLen);
    	CEdit m_Log;
    //	void OnRecvMsg(DWORD dwEvent, DWORD dwLen);
    	//HRESULT OnSendMsg(DWORD dwEvent, DWORD dwLen);
    	HRESULT OnSendMsg(WPARAM dwEvent, LPARAM dwLen);
    	//HRESULT OnRecvMsg(DWORD dwEvent, DWORD dwLen);
    	HRESULT OnRecvMsg(WPARAM dwEvent, LPARAM dwLen);
    	CEdit m_edit_Receive1;

    //打开串口的按钮

    void CTxwtechWin32API_CommDlg::OnBnClickedButtonOpenserial()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	if(pThreadCom!=NULL) return;
    	CString str;
    	CString com;
    	//int com1;
    	//com1=m_comboComm.GetCurSel();
    	//com1+=1;
    	//com=m_comboComm.GetWindowText();
    	m_comboComm.GetWindowTextA(com);//获取组合框com的内容
    	//com.Format("%s",com1);
    	pThreadCom=(CThreadCom1*)AfxBeginThread(RUNTIME_CLASS(CThreadCom1));
    	pThreadCom->SetComStr(com);//设置串口线程的串口名称变量
    	if(pThreadCom->OpenCom(com,(CWnd*)this->GetSafeOwner(),WM_USER_COMSENDMESSAGE,WM_USER_COMRECVMESSAGE))
    	{
    		str.Format("打开串口%s成功",pThreadCom->GetComStr());
    		WriteLog(str);
    	}
    	else
    	{
    		str.Format(pThreadCom->m_sError+",请重新配置串口");
    		WriteLog(str);
    		pThreadCom->m_bInit=FALSE;
    		return;
    	}
    	m_bCom=TRUE;
    	m_comboComm.EnableWindow(FALSE);
    	return;
    }

    //发送按钮绑定的代码

    void CTxwtechWin32API_CommDlg::OnBnClickedButtonSend()
    {
    	// TODO: 在此添加控件通知处理程序代码
    	UpdateData(true);
    	int iLen=m_editSend.GetLength();
    	BYTE* s=new BYTE[iLen];
    	memset(s,0x00,iLen);//初始化数据缓冲区
    	memcpy(s,(LPCTSTR)m_editSend,iLen);//复制数据
    	pThreadCom->SendData((unsigned char*)s,iLen);
    }

    //发送数据通知

    HRESULT CTxwtechWin32API_CommDlg::OnSendMsg(WPARAM dwEvent, LPARAM dwLen)
    {
    	if(!dwLen)
    		return 0;
    	BYTE* temp=new BYTE[dwLen+1];
    	memset(temp,0x00,dwLen+1);
    	memcpy(temp,(const void*)dwEvent,dwLen);
    	CString log;
    	log.Format("\r\n发送数据%s",(LPCTSTR)temp);
    	if(m_Log)
    	{
    		CEdit* editLog=(CEdit*)FromHandle(m_Log);
    		if(editLog->GetWindowTextLength()>50000)
    		{
    			editLog->SetSel(0,-1);//把发送区的全部内容选中
    			editLog->Clear();//清空全部内容
    			editLog->SetSel(0,0);//设置光标到0字节处
    			editLog->ReplaceSel(log);//更新新的内容
    		}
    		else
    		{
    			editLog->SetSel(editLog->GetWindowTextLength(),editLog->GetWindowTextLength());//光标指向句末
    			editLog->ReplaceSel(log);//添加新内容
    		}
    	}
    //	return;
    	return E_NOTIMPL;
    }

    //接收消息通知

    HRESULT CTxwtechWin32API_CommDlg::OnRecvMsg(WPARAM dwEvent, LPARAM dwLen)
    {
    	if(!dwLen) return 0;
    	BYTE* temp=new BYTE[dwLen+1];
    	memset(temp,0x00,dwLen+1);
    	memcpy(temp,(const void*)dwEvent,dwLen);
    	CString log;
    	log.Format("\r\n接收数据=%s",(LPCTSTR)temp);
    	if(m_editReceive.GetLength()>50000)
    		m_editReceive="";
    	m_editReceive+=log;
    	CEdit* editLog=(CEdit*)FromHandle(m_edit_Receive1);
    	editLog->SetSel(editLog->GetWindowTextLength(),editLog->GetWindowTextLength());
    			editLog->ReplaceSel(log);
    	//UpdateData(false);
    	return E_NOTIMPL;
    }

    相关调试遇到的问题:

    error C2511: “CThreadCom1::CThreadCom1(HANDLE)”:“CThreadCom1”中没有找到重载的成员函数
    原因:头文件未定义。
    CThreadCom1(HANDLE hCom=INVALID_HANDLE_VALUE);
    error C2668: “CThreadCom1::CThreadCom1”: 对重载函数的调用不明确
    头文件中只有有一个重载函数,把默认的删除掉

    TxwtechWin32API_Comm.exe 中的 0x100c14cf (msvcr100d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000002 时发生访问冲突,
    rootcause:连接串口不能是数值,而是字符串COM1...

    TxwtechWin32API_Comm.exe 中的 0x7898391c (mfc100d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000020 时发生访问冲突
    缺少如下两句://m_dwSendMsgToParent 没有获取父窗口的值
    //m_dwSendMsgToParent = dwSendMsgToParent;
     m_dwRecvMsgToParent = dwRecvMsgToParent;

    接收框中无法接收消息,注意消息的映射与宏定义

    #define WM_USER_COMSENDMESSAGE WM_USER+200
    #define WM_USER_COMRECVMESSAGE WM_USER+201

    BEGIN_MESSAGE_MAP(CTxwtechWin32API_CommDlg, CDialogEx)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_BN_CLICKED(IDC_BUTTON_OpenSerial, &CTxwtechWin32API_CommDlg::OnBnClickedButtonOpenserial)
    	ON_BN_CLICKED(IDC_BUTTON_Send, &CTxwtechWin32API_CommDlg::OnBnClickedButtonSend)
    	ON_MESSAGE(WM_USER_COMSENDMESSAGE,OnSendMsg)
    	ON_MESSAGE(WM_USER_COMRECVMESSAGE,OnRecvMsg)
    END_MESSAGE_MAP()

    展开全文
  • VB API 串口通讯 源码

    2013-08-15 19:25:04
    VB API 串口通讯 源码
  • 测绘仪器与计算机之间的异步串行通信是现代测绘中经常遇到的问题,如何在Windows平台下实现测绘仪器与计算机之间数据通信是测量内、外业一体化的基本问题。在工作经验的基础上,详细研究和分析了利用Win32 API通信...
  • c# API串口通信

    千次阅读 2019-04-12 09:06:54
    本文主要是讲述如何通过C# .net1.1平台调用API操作串口,.net2.0已经内置串口操作类! 通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,...

    本文主要是讲述如何通过C# .net1.1平台调用API操作串口,.net2.0已经内置串口操作类!

    通常,在C#中实现串口通信,我们有四种方法:

    第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册。可以访问
    http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320
    一个外国人写的教程
    第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的可以访问微软网站
    Serial Comm
    Use P/Invoke to Develop a .NET Base Class Library for Serial Device Communications

    http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/
    第三:就是用第三方控件啦,可一般都要付费的,不太合实际,何况楼主不喜欢,不作考虑
    第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能。

    我们采用第四种方法来实现串口通信,用现成的已经封装好的类库,常见两个串口操作类是JustinIO和SerialStreamReader。介绍JustinIO的使用方法:
    打开串口:

    函数原型:public void Open()

    说明:打开事先设置好的端口

    示例:

    using JustinIO; 
     
    static JustinIO.CommPort ss_port = new JustinIO.CommPort(); 
    ss_port.PortNum = COM1; //端口号 
    ss_port.BaudRate = 19200; //串口通信波特率 
    ss_port.ByteSize = 8; //数据位 
    ss_port.Parity = 0; //奇偶校验 
    ss_port.StopBits = 1;//停止位 
    ss_port.ReadTimeout = 1000; //读超时 
    try 
    { 
    if (ss_port.Opened) 
    { 
    ss_port.Close(); 
    ss_port.Open(); //打开串口 
    } 
    else 
    { 
    ss_port.Open();//打开串口 
    } 
    return true; 
    } 
    catch(Exception e) 
    { 
    MessageBox.Show("错误:" + e.Message); 
    return false; 
    } 
    
    

    写串口:

    函数原型:public void Write(byte[] WriteBytes)

    WriteBytes 就是你的写入的字节,注意,字符串要转换成字节数组才能进行通信

    示例:

    ss_port.Write(Encoding.ASCII.GetBytes(“AT+CGMI\r”)); //获取手机品牌

    读串口:

    函数原型:public byte[] Read(int NumBytes)

    NumBytes 读入缓存数,注意读取来的是字节数组,要实际应用中要进行字符转换

    示例:

    string response = Encoding.ASCII.GetString(ss_port.Read(128)); //读取128个字节缓存

    关闭串口:

    函数原型:ss_port.Close()

    示例:

    ss_port.Close();

    整合代码:

    using System; 
    using System.Runtime.InteropServices; 
     
    namespace JustinIO { 
    class CommPort { 
     
    public int PortNum; 
    public int BaudRate; 
    public byte ByteSize; 
    public byte Parity; // 0-4=no,odd,even,mark,space 
    public byte StopBits; // 0,1,2 = 1, 1.5, 2 
    public int ReadTimeout; 
     
    //comm port win32 file handle 
    private int hComm = -1; 
     
    public bool Opened = false; 
     
    //win32 api constants 
    private const uint GENERIC_READ = 0x80000000; 
    private const uint GENERIC_WRITE = 0x40000000; 
    private const int OPEN_EXISTING = 3; 
    private const int INVALID_HANDLE_VALUE = -1; 
     
    [StructLayout(LayoutKind.Sequential)] 
    public struct DCB { 
    //taken from c struct in platform sdk 
    public int DCBlength; // sizeof(DCB) 
    public int BaudRate; // current baud rate 
    /* these are the c struct bit fields, bit twiddle flag to set 
    public int fBinary; // binary mode, no EOF check 
    public int fParity; // enable parity checking 
    public int fOutxCtsFlow; // CTS output flow control 
    public int fOutxDsrFlow; // DSR output flow control 
    public int fDtrControl; // DTR flow control type 
    public int fDsrSensitivity; // DSR sensitivity 
    public int fTXContinueOnXoff; // XOFF continues Tx 
    public int fOutX; // XON/XOFF out flow control 
    public int fInX; // XON/XOFF in flow control 
    public int fErrorChar; // enable error replacement 
    public int fNull; // enable null stripping 
    public int fRtsControl; // RTS flow control 
    public int fAbortOnError; // abort on error 
    public int fDummy2; // reserved 
    */ 
    public uint flags; 
    public ushort wReserved; // not currently used 
    public ushort XonLim; // transmit XON threshold 
    public ushort XoffLim; // transmit XOFF threshold 
    public byte ByteSize; // number of bits/byte, 4-8 
    public byte Parity; // 0-4=no,odd,even,mark,space 
    public byte StopBits; // 0,1,2 = 1, 1.5, 2 
    public char XonChar; // Tx and Rx XON character 
    public char XoffChar; // Tx and Rx XOFF character 
    public char ErrorChar; // error replacement character 
    public char EofChar; // end of input character 
    public char EvtChar; // received event character 
    public ushort wReserved1; // reserved; do not use 
    } 
     
    [StructLayout(LayoutKind.Sequential)] 
    private struct COMMTIMEOUTS { 
    public int ReadIntervalTimeout; 
    public int ReadTotalTimeoutMultiplier; 
    public int ReadTotalTimeoutConstant; 
    public int WriteTotalTimeoutMultiplier; 
    public int WriteTotalTimeoutConstant; 
    } 
     
    [StructLayout(LayoutKind.Sequential)] 
    private struct OVERLAPPED { 
    public int Internal; 
    public int InternalHigh; 
    public int Offset; 
    public int OffsetHigh; 
    public int hEvent; 
    } 
     
    [DllImport("kernel32.dll")] 
    private static extern int CreateFile( 
    string lpFileName, // file name 
    uint dwDesiredAccess, // access mode 
    int dwShareMode, // share mode 
    int lpSecurityAttributes, // SD 
    int dwCreationDisposition, // how to create 
    int dwFlagsAndAttributes, // file attributes 
    int hTemplateFile // handle to template file 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool GetCommState( 
    int hFile, // handle to communications device 
    ref DCB lpDCB // device-control block 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool BuildCommDCB( 
    string lpDef, // device-control string 
    ref DCB lpDCB // device-control block 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool SetCommState( 
    int hFile, // handle to communications device 
    ref DCB lpDCB // device-control block 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool GetCommTimeouts( 
    int hFile, // handle to comm device 
    ref COMMTIMEOUTS lpCommTimeouts // time-out values 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool SetCommTimeouts( 
    int hFile, // handle to comm device 
    ref COMMTIMEOUTS lpCommTimeouts // time-out values 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool ReadFile( 
    int hFile, // handle to file 
    byte[] lpBuffer, // data buffer 
    int nNumberOfBytesToRead, // number of bytes to read 
    ref int lpNumberOfBytesRead, // number of bytes read 
    ref OVERLAPPED lpOverlapped // overlapped buffer 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool WriteFile( 
    int hFile, // handle to file 
    byte[] lpBuffer, // data buffer 
    int nNumberOfBytesToWrite, // number of bytes to write 
    ref int lpNumberOfBytesWritten, // number of bytes written 
    ref OVERLAPPED lpOverlapped // overlapped buffer 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern bool CloseHandle( 
    int hObject // handle to object 
    ); 
    [DllImport("kernel32.dll")] 
    private static extern uint GetLastError(); 
     
    public void Open() { 
     
    DCB dcbCommPort = new DCB(); 
    COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); 
     
     
    // OPEN THE COMM PORT. 
     
     
    hComm = CreateFile("COM" + PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0); 
     
    // IF THE PORT CANNOT BE OPENED, BAIL OUT. 
    if(hComm == INVALID_HANDLE_VALUE) { 
    throw(new ApplicationException("Comm Port Can Not Be Opened")); 
    } 
     
    // SET THE COMM TIMEOUTS. 
     
    GetCommTimeouts(hComm,ref ctoCommPort); 
    ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout; 
    ctoCommPort.ReadTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutConstant = 0; 
    SetCommTimeouts(hComm,ref ctoCommPort); 
     
    // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS. 
    GetCommState(hComm, ref dcbCommPort); 
    dcbCommPort.BaudRate=BaudRate; 
    dcbCommPort.flags=0; 
    //dcb.fBinary=1; 
    dcbCommPort.flags|=1; 
    if (Parity>0) 
    { 
    //dcb.fParity=1 
    dcbCommPort.flags|=2; 
    } 
    dcbCommPort.Parity=Parity; 
    dcbCommPort.ByteSize=ByteSize; 
    dcbCommPort.StopBits=StopBits; 
    if (!SetCommState(hComm, ref dcbCommPort)) 
    { 
    //uint ErrorNum=GetLastError(); 
    throw(new ApplicationException("Comm Port Can Not Be Opened")); 
    } 
    //unremark to see if setting took correctly 
    //DCB dcbCommPort2 = new DCB(); 
    //GetCommState(hComm, ref dcbCommPort2); 
    Opened = true; 
     
    } 
     
    public void Close() { 
    if (hComm!=INVALID_HANDLE_VALUE) { 
    CloseHandle(hComm); 
    } 
    } 
    public byte[] Read(int NumBytes) { 
    byte[] BufBytes; 
    byte[] OutBytes; 
    BufBytes = new byte[NumBytes]; 
    if (hComm!=INVALID_HANDLE_VALUE) { 
    OVERLAPPED ovlCommPort = new OVERLAPPED(); 
    int BytesRead=0; 
    ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort); 
    OutBytes = new byte[BytesRead]; 
    Array.Copy(BufBytes,OutBytes,BytesRead); 
    } 
    else { 
    throw(new ApplicationException("Comm Port Not Open")); 
    } 
    return OutBytes; 
    } 
     
    public void Write(byte[] WriteBytes) { 
    if (hComm!=INVALID_HANDLE_VALUE) { 
    OVERLAPPED ovlCommPort = new OVERLAPPED(); 
    int BytesWritten = 0; 
    WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort); 
    } 
    else { 
    throw(new ApplicationException("Comm Port Not Open")); 
    } 
    } 
    } 
     
    } 
    } 
    
    
    展开全文
  • android-serialport-api串口通信精简demo

    热门讨论 2014-07-15 13:22:08
    关于利用android-serialport-api实现在安卓设备上进行串口通信,附精简版demo,亲测可用。符个人博文说明:http://blog.csdn.net/ckw474404603/article/details/37811499
  • API串口通信

    2015-12-04 21:04:32
    一点API串口通信基本函数的操作,包含了打开文件,设置串口,读写文件,异步I/O操作等等
  • 该demo亲测可用。相应的demo文档,可看本人博客。有问题可以一起探讨!
  • Win7x64下的MFC中不可调用MSCOMM控件。所以在MFC下使用WinAPI来实现串口通信,亲测可用。
  • WIN32 API串口通讯实例教程 第一节实现串口通讯的函数及串口编程简介 API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作。常用函数及作用下: 函数名作用...

    WIN32 API串口通讯实例教程

     

     

    第一节   实现串口通讯的函数及串口编程简介

     

    API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作。常用函数及作用下:

    函数名                     作用

    CreateFile                 打开串口

    GetCommState               检测串口设置

    SetCommState               设置串口

    BuilderCommDCB             用字符串中的值来填充设备控制块

    GetCommTimeouts            检测通信超时设置

    SetCommTimeouts            设置通信超时参数

    SetCommMask                设定被监控事件

    WaitCommEvent              等待被监控事件发生

    WaitForMultipleObjects     等待多个被监测对象的结果

    WriteFile                  发送数据

    ReadFile                   接收数据

    GetOverlappedResult        返回最后重叠(异步)操作结果

    PurgeComm                  清空串口缓冲区,退出所有相关操作

    ClearCommError             更新串口状态结构体,并清除所有串口硬件错误

    CloseHandle                关闭串行口

    Windows API 编写串口程序本身是有巨大优点的,因为控制能力会更强,效率也会更

    高。

        API编写串口,过程一般是这样的:

        1、  创建串口句柄,用CreateFile

        2、  对串口的参数进行设置,其中比较重要的是波特率(BaudRate),数据宽度(BytesBits),奇偶校验(Parity),停止位(StopBits),当然,重要的还有端口号(Port);

        3、  然后对串口进行相应的读写操作,这时候用到ReadFileWriteFile函数;

    4、       读写结束后,要关闭串口句柄,用CloseFile

    下面依次讲述各个步骤的过程。

     

     

    WIN32 API串口通讯实例教程 - lishaoan77 - 药人博客

      

     

     

     

     

     

     

     

     

     

     

    第二节   创建串口句柄打开串口

     

    从字面上去理解,大家也可以发现CreateFile实际上表明Windows是把串口当作一个文件来处理的,所以它也有文件那样的缓冲区、句柄、读写错误等,不同的是,这个文件名字只有固定的几个(一般为四个),而且始终存在(EXSITING),而且在调用CreateFile的时候请注意它的参数。CreateFile函数原型如下:

        HANDLE CreateFile(LPCTSTR lpFileName,

                          DWORD dwDesiredAccess,

                          DWORD dwShareMode,

                          LPSECURITY_ATTRIBUTES lpSecurityAttributes,

                          DWORD dwCreationDisposition,  

                          DWORD dwFlagsAndAttributes,

                          HANDLE hTemplateFile );

    lpFileName:指向一个以NULL结束的字符串,该串指定了要创建、打开或截断的文件、管道、通信源、磁盘设备或控制台的名字。当用CreateFile打开串口时,这个参数可用“COM1指定串口1,用“COM2指定串口2,依此类推。

    dwDesireAccess: 指定对文件访问的类型,该参数可以为GENERIC_READ(指定对该文件的读访问权)GENERIC_WRITE(指定该文件的写访问权)两个值之一或同时为为这两个值。用ENERIC_READ|GENERIC_WRITE则指定可对串口进行读写;

    dwShareMode:指定此文件可以怎样被共享。因为串行口不支持任何共享模式,所以dwShareMode必须设为0;

    lpSecurityAttributes定义安全属性,一般不用,可设为NULLWin 9x下该参数被忽略;

    dwCreationDistribution定义文件创建方式, 对串口必须设为OPEN_EXISTING,表示打开已经存在的文件;

    dwFlagsAndAttributes为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPED,表示异步通信方式;

        hTemplateFile 指向一个模板文件的句柄,串口无模板可言,设为NULL。在 Windows 9x下该参数必须为NULL

    串口被成功打开时,返回其句柄,否则返回INVALID_HANDLE_value(0XFFFFFFFF)

    上面说到了异步,那什么是异步呢?异步是相对同步这个概念而言的。异步,就是说,

    在进行串口读写操作时,不用等到I/O操作完成后函数才返回,也就是说,异步可以更快得

    响应用户操作;同步,相反,响应的I/O操作必须完成后函数才返回,否则阻塞线程。对于

    一些很简单的通讯程序来说,可以选择同步,这样可以省去很多错误检查,但是对于复杂一点的应用程序,异步是最佳选择。

    实例1

    /******************   example1.cpp   ******************************************/

    /* lishaoan  2009-06-29  *****************************************************/

    /*   ******************************************************/

    #include  <windows.h>

    #include   <stdio.h>

    #include   <stdlib.h>

     

    bool openport(char *portname)//打开串口

    {

    HANDLE hComm;

    hComm = CreateFile(portname, //串口号

                       GENERIC_READ | GENERIC_WRITE, //允许读写

                       0, //通讯设备必须以独占方式打开

                       0, //无安全属性

                       OPEN_EXISTING, //通讯设备已存在

                       FILE_FLAG_OVERLAPPED, //异步I/O

                       0); //通讯设备不能用模板打开

    if (hComm == INVALID_HANDLE_VALUE)

    {

    CloseHandle(hComm);

    return FALSE;

    }

    else

    return true;

    }

       

    void   main()

    {

    bool open;

    open=openport("com2");

    if(open)

    printf("open comport success");

    system("pause") ;

    }

    /************************** program end***************************************/

     

    实例2

    /******************   example2.cpp   ******************************************/

    /* lishaoan  2009-06-29  *****************************************************/

    /*   ******************************************************/

    #include  <windows.h>

    #include   <stdio.h>

    #include   <stdlib.h>

     

    bool openport(char *portname)//打开串口

    {

    HANDLE hComm;

    hComm = CreateFile(portname, //串口号

                       GENERIC_READ | GENERIC_WRITE, //允许读写

                       0, //通讯设备必须以独占方式打开

                       0, //无安全属性

                       OPEN_EXISTING, //通讯设备已存在

                       0, //同步I/O

                       0); //通讯设备不能用模板打开

    if (hComm == INVALID_HANDLE_VALUE)

    {

    CloseHandle(hComm);

    return FALSE;

    }

    else

    return true;

    }

       

    void   main()

    {

    bool open;

    open=openport("com2");

    if(open)

    printf("open comport success");

    system("pause") ;

    }

    /************************** program end***************************************/

     

    展开全文
  • Win API串行通信

    2021-04-04 12:33:43
    当系统调用失败时,您需要调用GetLastError找出原因。 请参见SetCommMask函数(winbase.h)-Win32应用| 例如,Microsoft Docs [^]。
  • API串口通讯和定时器

    2018-12-04 15:32:58
    本程序基于VS2010使用API函数来实现定时器的达到1ms的精度来完成串口发送数据
  • 在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由...本文只介绍API串口通信部分。
  • pb调用API串口通讯.docx

    2022-05-07 14:00:07
    pb调用API串口通讯
  • API实现串行通讯 API实现串行通讯 API实现串行通讯
  • API通信函数,有关串口网络通讯用到的api函数。
  • 基于 win32 API 串口通讯收发设置等。 文件传送 在线升级 demo,VC2005 编译通过。很强大的说~!
  • VB API实现的串口通信代码

    热门讨论 2009-05-22 19:54:16
    API函数写的串口通信代码。 感谢lyserver的帮助!
  • WIN32 API串口通讯实例教程,包括串口通讯的函数介绍和举例
  • 串口设备为:PN532读卡器 源码中用到了一条命令数据: 0000FF09F7D400006C69626E6663BE00 这是PN532的一条指令,相关指令 NXP官网有: https://www.nxp.com/docs/en/nxp/application-notes/AN133910.pdf
  • VB串口通信源码210个

    千次下载 热门讨论 2013-10-15 11:32:27
    036、VB串口通信,API串口通信模块源码 037、VB串口通信,适用简单,适合初学者 038、VB串口通信操作界面,进行数据采集,画实时曲线 039、VB串口通信程序,可以读取串口并显示保存数据,且能显示数据曲线 040、VB串口通信...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,275
精华内容 20,110
关键字:

api串口通信