用vc实现多串口多线程工业控制

上传人:子 文档编号:43296373 上传时间:2018-06-05 格式:DOC 页数:9 大小:49.50KB
返回 下载 相关 举报
用vc实现多串口多线程工业控制_第1页
第1页 / 共9页
用vc实现多串口多线程工业控制_第2页
第2页 / 共9页
用vc实现多串口多线程工业控制_第3页
第3页 / 共9页
用vc实现多串口多线程工业控制_第4页
第4页 / 共9页
用vc实现多串口多线程工业控制_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《用vc实现多串口多线程工业控制》由会员分享,可在线阅读,更多相关《用vc实现多串口多线程工业控制(9页珍藏版)》请在金锄头文库上搜索。

1、用 VC 实现多串口多线程工业控制串口通信 2009-05-09 22:50 阅读 22 评论 0 字号: 大 中 小 在中小型电站系统就地控制中,比如水电站中如果我们要进行各种设备控制的话,串口数量就可能比较多了,有的地方加上载波甚至可以达到 10 个以上,很多的解决方法是将某些功能设备并行接到一个串口上面尽量减少串口的数量,然后进行数据采集的时候采取环的方法进行。但是工业控制要求实时性比较高,比如报警和各种控制,如果不能在尽可能短的时间里面进行处理可能引发大的后果,我们觉得还是应该将各种不同设备接入不同的串口,比如水电站中间各个机组的 PLC 和机组的调速器通讯等就接入不同串口。如果某个相

2、同设备数量很多,如温度装置,有的 1 个发电机组可能超过 20 个温度点,我们可以采用接入 2 个或者多个串口的方法处理。为了使初学者能够更容易看懂串口通讯的处理过程,我采用援助非洲刚果(布)姆古古鲁水电站的温度表为实例进行程序的分析。在我们这个项目中有 4 台发电机组,每个机组温度表有 20 个点。由于这个与上位机通讯串口安排极多,我们只能将 20 个温度表并行接入串口进行通讯。在进行硬件通讯之前我们首先要看懂改硬件的通讯协议。通讯协议就是上位机向改外围设备进行读取数据和进行某种功能控制时候的一系列指令和外围设备返回上位机的各数据位代表的意思。比如那个位是控制码,哪个位是数据,是什么数据等。

3、首先启动 VC 新建一个给予 SDI 的工程,然后加入 SerialPort 类。由于要进行多串口通讯,我们需要对 SerialPort 进行一些简单的修改,由于在与硬件通讯过程中一般通讯协议都采用 BYTE 类型数据传送,我们可以将该类中间的发送和接收数据类型修改成为 BYTE 类型。我修改了下面部分内容,详细改动请见附录提供的 SERIALPORT 类。/ Write a string to the port/void CSerialPort:WriteToPort(BYTE bWriteBuffer,int nWriteBufferSize) assert(m_hComm != 0);

4、int nSize = sizeof(bWriteBuffer)/sizeof(BYTE);m_nWriteBufferSize = nWriteBufferSize;for(int i = 0 ; i m_Ports.StartMonitoring();启动监视线程SetCommVal();发送第一台设备数据命令 下面是启动外部控制线程unsigned int nDummy;m_pThread=(HANDLE) _beginthreadex(NULL,0,CommThread,this,CREATE_SUSPENDED,/开辟外部控制线程 ResumeThread(m_pThread); 运

5、行线程 外部控制线程控制当前设备发送要数据命令和收到数据报文是否超时UINT CView:CommThread(LPVOID pParam)CView *pView = (CView *)pParam; while(1)CTime cNowTime = CTime:GetCurrentTime(); tNow = cNowTime.GetTime();struct _timeb timebuffer; _ftime(int nNowMillSecond = timebuffer.millitm;/tLast = cLastColtTime0.GetTime();if(tNow - tLast)

6、*1000 + (nNowMillSecond - nMillSecond0) 800)pView-SetCommVal();发送下一台设备要数据命令或者进行其他的相关处理Sleep(100); 发送串口数据命令,这里要根据外部设备的制定的通讯协议来进行。这次温度表采用的是ASCII 的形式通讯。void CView:SetCommVal()int HAddr,LAddr,m_Xnh;int nHAdd,nLAdd;nHAdd = ExchangeAscII(nColtAddr4)nLAdd = ExchangeAscII(nColtAddr m_Xnh = nHAddnLAdd0x520x4

7、4; HAddr = ExchangeAscII(m_Xnh4)LAddr = ExchangeAscII(m_Xnh BYTE OutBuff8 = 0x40,nHAdd,nLAdd,0x52,0x44,HAddr,LAddr,0x0d; m_Ports.WriteToPort(OutBuff,8); cLastColtTime = CTime:GetCurrentTime();nColtAddr+;if(nColtAddr 19)/19 define max addr numbers nColtAddr = 0; ASCII 码的一些简单变换,我们进行一下简单的封装,方便调用:BYTE C

8、View:ExchangeAscII(BYTE bInput)BYTE bRef = 0;if(bInput 9) bRef = bInput+0x37;else bRef = bInput+0x30;return bRef;BYTE CView:ExchangeAscIItoNormal(BYTE bInput)BYTE bRef = 0;if(bInput 0x39) bRef = bInput-0x37;else bRef = bInput-0x30;return bRef; LONG CView:OnCommunication(WPARAM ch, LPARAM port)进行数据处理

9、,WPARAM,LPARAM 类型是多态性数据(polymorphic data type),在 WIN32 中为 32 位,支持多种数据类型,根据需要自动适应,这样程序就有很强的适应性。再次我们这里理解成为 BYTE 类型(与外围设备通讯协议保持一致,方便解包)。每当串口接收缓冲区内有一个字符的时候,就会产生一个WM_COMM_RXCHAR 消息,触发 OnCommunication 函数,下面我们可以根据我们的需要进行解包处理了;LONG CMy11View:OnCommunication(WPARAM ch, LPARAM port) if(port = 1)m_RecBuffnColt

10、s += (BYTE)(char *)(ch);nColts+;if(nColts = 24)/这里根据通讯协议规定的发送定制要数据命令就会上传 24 个字节的数据报文内容。这里可以根据不同外部设备进行不同的设置DataProcessTemp(m_RecBuff);/处理解包nColts = 0;/缓冲区指针清 0,准备接收下一台设备数据ResetBuffVal();/清空缓冲区内容SetCommVal(); /发送下一台设备内容 return 0; 数据解包处理,这里就必须根据外部设备定义的通讯协议来处理了。void CMy11View:DataProcessTemp(BYTE m_Inbu

11、ff)int nTempAddr = nColtAddr - 1;if(nTempAddr 4)nLAdd = ExchangeAscII(nTempAddrif(m_Inbuff0 = 0x40)if(m_Inbuff1 = nHAdd float fTemp;nzTemp0 = m_Inbuff7;nzTemp1 = m_Inbuff8;nzTemp2 = m_Inbuff9;nzTemp3 = m_Inbuff10;for(int i = 0 ; i 0x39)nzTempi -= 0x37;elsenzTempi -= 0x30; fTemp=float(nzTemp1+(nzTemp0m_Ports0.InitPort(this,2,9600,N,8,1,EV_RXCHAR|EV_RXFLAG,1024) this-m_Ports0.StartMonitoring();SetComBufferVal(0); /Diandu Deviceif(this-m_Ports1.InitPort(this,4,1200,E,8,1,EV_RXCHAR|EV_RXFLAG,1024) this-m_Ports1.StartMonitoring();SetComBufferVal(1); 我们对各种发送命令函数进行载入形参的方法来解决。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号