求购温控仪:Win32串口编程实例
来源:百度文库 编辑:偶看新闻 时间:2024/04/29 11:08:11
串口编程的一个实例
打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数:
为了让您更好地理解串口编程,下面我们分别编写两个例程(见附带的源码部分),这两个例程都实现了工控机与百特显示仪表通过RS485接口进行的串口通信。其中第一个例程采用同步串口操作,第二个例程采用异步串口操作。
我们只介绍软件部分,RS485接口接线方法不作介绍,感兴趣的读者可以查阅相关资料。
例程1
打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。
在RS485CommDlg.cpp文件中添加全局变量:
HANDLE hCom; //全局变量,串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码:
// TODO: Add extra initialization here hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式 NULL, OPEN_EXISTING, //打开而不是创建 0, //同步方式 NULL); if(hCom==(HANDLE)-1) { AfxMessageBox("打开COM失败!"); return FALSE; } SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是1024 COMMTIMEOUTS TimeOuts; //设定读超时 TimeOuts.ReadIntervalTimeout=MAXDWORD; TimeOuts.ReadTotalTimeoutMultipli分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数:er=0; TimeOuts.ReadTotalTimeoutConstant =0; //在读一次输入缓冲区的内容后读操作就立即返回, //而不管是否读入了要求的字符。 //设定写超时 TimeOuts.WriteTotalTimeoutMultipl ier=100; TimeOuts.WriteTotalTimeoutConstan t=500; SetCommTimeouts(hCom,&TimeOuts); //设置超时 DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600 dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位 dcb.StopBits=TWOSTOPBITS; //两个停止位 SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
void CRS485CommDlg::OnSend() { // TODO: Add your control notification handler code here // 在此需要简单介绍百特公司XMA5000的通讯协议: //该仪表RS485通讯采用主机广播方式通讯。 //串行半双工,帧11位,1个起始位(0),8个数据位,2个停止位(1) //如:读仪表显示的瞬时值,主机发送:DC1 AAA BB ETX //其中:DC1是标准ASCII码的一个控制符号,码值为11H(十进制的17) //在XMA5000的通讯协议中,DC1表示读瞬时值 //AAA是从机地址码,也就是XMA5000显示仪表的通讯地址 //BB为通道号,读瞬时值时该值为01 //ETX也是标准ASCII码的一个控制符号,码值为03H //在XMA5000的通讯协议中,ETX表示主机结束符 char lpOutBuffer[7]; memset(lpOutBuffer,''\0'',7); //前7个字节先清零 lpOutBuffer[0]=''\x11''; //发送缓冲区的第1个字节为DC1 lpOutBuffer[1]=''0''; //第2个字节为字符0(30H) lpOutBuffer[2]=''0''; //第3个字节为字符0(30H) lpOutBuffer[3]=''1''; // 第4个字节为字符1(31H) lpOutBuffer[4]=''0''; //第5个字节为字符0(30H) lpOutBuffer[5]=''1''; //第6个字节为字符1(31H) lpOutBuffer[6]=''\x03''; //第7个字节为字符ETX //从该段代码可以看出,仪表的通讯地址为001 DWORD dwBytesWrite=7; COMSTAT ComStat; DWORD dwErrorFlags; BOOL bWriteStat; ClearCommError(hCom,&dwErrorFlags,&ComStat); bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,& dwBytesWrite,NULL); if(!bWriteStat) { AfxMessageBox("写串口失败!"); } }您可以观察返回的字符串,其中有和仪表显示值相同的部分,您可以进行相应的字符串操作取出仪表的显示值。
打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数:
void CRS485CommDlg::OnClose() { // TODO: Add your message handler code here and/or call default CloseHandle(hCom); //程序退出时关闭串口 CDialog::OnClose(); }程序的相应部分已经在代码内部作了详细介绍。连接好硬件部分,编译运行程序,细心体会串口同步操作部分。
例程2
打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。在RS485CommDlg.cpp文件中添加全局变量:
HANDLE hCom; //全局变量,
串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码:
hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式 NULL, OPEN_EXISTING, //打开而不是创建 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式 NULL); if(hCom==(HANDLE)-1) { AfxMessageBox("打开COM失败!"); return FALSE; } SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是100 COMMTIMEOUTS TimeOuts; //设定读超时 TimeOuts.ReadIntervalTimeout=MAXDWORD; TimeOuts.ReadTotalTimeoutMultipli分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数:er=0; TimeOuts.ReadTotalTimeoutConstant =0; //在读一次输入缓冲区的内容后读操作就立即返回, //而不管是否读入了要求的字符。 //设定写超时 TimeOuts.WriteTotalTimeoutMultipl ier=100; TimeOuts.WriteTotalTimeoutConstan t=500; SetCommTimeouts(hCom,&TimeOuts); //设置超时 DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600 dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位 dcb.StopBits=TWOSTOPBITS; //两个停止位 SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
void CRS485CommDlg::OnSend() { // TODO: Add your control notification handler code here OVERLAPPED m_osWrite; memset(&m_osWrite,0,sizeof(OVERLAPPED)); m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); char lpOutBuffer[7]; memset(lpOutBuffer,''\0'',7); lpOutBuffer[0]=''\x11''; lpOutBuffer[1]=''0''; lpOutBuffer[2]=''0''; lpOutBuffer[3]=''1''; lpOutBuffer[4]=''0''; lpOutBuffer[5]=''1''; lpOutBuffer[6]=''\x03''; DWORD dwBytesWrite=7; COMSTAT ComStat; DWORD dwErrorFlags; BOOL bWriteStat; ClearCommError(hCom,&dwErrorFlags,&ComStat); bWriteStat=WriteFile(hCom,lpOutBuffer, dwBytesWrite,& dwBytesWrite,&m_osWrite); if(!bWriteStat) { if(GetLastError()==ERROR_IO_PENDING) { WaitForSingleObject(m_osWrite.hEvent,1000); } } } void CRS485CommDlg::OnReceive() { // TODO: Add your control notification handler code here OVERLAPPED m_osRead; memset(&m_osRead,0,sizeof(OVERLAPPED)); m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); COMSTAT ComStat; DWORD dwErrorFlags; char str[100]; memset(str,''\0'',100); DWORD dwBytesRead=100;//读取的字节数 BOOL bReadStat; ClearCommError(hCom,&dwErrorFlags,&ComStat); dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue); bReadStat=ReadFile(hCom,str, dwBytesRead,&dwBytesRead,&m_osRead); if(!bReadStat) { if(GetLastError()==ERROR_IO_PENDING) //GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作 { WaitForSingleObject(m_osRead.hEvent,2000); //使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟 //当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号 } } PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); m_disp=str; UpdateData(FALSE); }打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数:
void CRS485CommDlg::OnClose() { // TODO: Add your message handler code here and/or call default CloseHandle(hCom); //程序退出时关闭串口 CDialog::OnClose(); }
vb数据库编程实例
C++ Builder6编程实例
求 plc编程实例
c语言编程实例
FAGOR系统编程实例
数据库实例编程
VFP 编程实例!
java实现串口编程
VB串口编程
串口通信编程
单片机串口编程
如何学习WIN32编程?
翻译数控编程与实例
哪里有java编程实例?
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
求《WIN32 API 编程》,陈志远译
那里有win32编程教程?
哪里可以找到VFP编程的实例?
哪里可以下载松下plc编程实例