1、智能仪表只能控制一个或几个控制回路。
2、PLC本身就可以作为一个独立系统的上位控制器,控制的回路可成百上千,还能够通过通讯网络扩展为更加庞大的控制网络。
3、智能仪表要扩大控制的范围,必须接入上位控制系统。
首先配置好智能仪表从站通讯参数,拿9600 8 1 none 地址3举例200PLC主站程序 第一步初始化,复位modbus库完成位,初始化完成后,启动读写指令m0.1置位
网络3,填写从站通讯参数
M0.1置位读取从站数据,读取保持寄存器40001-40008 8个数据根据数据格式写入&VB1000,如40001 40002为32位浮点数,则保存在VB1000 VB1001 VB1002 VB1003中,依次类推,读取完成M2.1置位,复位读取从站保持寄存器M0.1 M2.3
读取输入寄存器,读取完成M2.2置位,复位M2,.1
6
M2.2置位,写数据开始,VB3000写入00001中,写完成,M2.3置位,开始读,M2.2复位。
例程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=MAXDWORDTimeOuts.ReadTotalTimeoutMultiplier=0TimeOuts.ReadTotalTimeoutConstant=0//在读一次输入缓冲区的内容后读 *** 作就立即返回, //而不管是否读入了要求的字符。 //设定写超时 TimeOuts.WriteTotalTimeoutMultiplier=100TimeOuts.WriteTotalTimeoutConstant=500SetCommTimeouts(hCom,&TimeOuts)//设置超时 DCB dcbGetCommState(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)分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数: 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=7COMSTAT ComStatDWORD dwErrorFlagsBOOL bWriteStatClearCommError(hCom,&dwErrorFlags,&ComStat)bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,&dwBytesWrite,NULL)if(!bWriteStat) { AfxMessageBox("写串口失败!")}}void CRS485CommDlg::OnReceive() { // TODO: Add your control notification handler code here char str[100]memset(str,''\0'',100)DWORD wCount=100//读取的字节数 BOOL bReadStatbReadStat=ReadFile(hCom,str,wCount,&wCount,NULL)if(!bReadStat) AfxMessageBox("读串口失败!")PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR)m_disp=strUpdateData(FALSE)}您可以观察返回的字符串,其中有和仪表显示值相同的部分,您可以进行相应的字符串 *** 作取出仪表的显示值。打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数: void CRS485CommDlg::OnClose() { // TODO: Add your message handler code here and/or call defaultCloseHandle(hCom)//程序退出时关闭串口 CDialog::OnClose()}程序的相应部分已经在代码内部作了详细介绍。连接好硬件部分,编译运行程序,细心体会串口同步 *** 作部分。参考资料: http://www.vckbase.com/document/viewdoc/?id=1734欢迎分享,转载请注明来源:内存溢出
评论列表(0条)