多线程技术的PLC与PC的通讯方式
Posted 工业之家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程技术的PLC与PC的通讯方式相关的知识,希望对你有一定的参考价值。
基于多线程技术的PLC与PC的通讯方式
1.系统构成
推进系统中,PC机选用工控计算机。它是整个控制系统的核心,是上位机。其主要利用良好的图形用户界面,显示从PLC接收的开关量和控制手柄的位置,进行一些较复杂的数据运算,并且向PLC发出控制指令。
PLC是该系统的下位机,负责现场高速数据采集(控制手柄的位置),实现逻辑、定时、计数、PID调节等功能,通过串行通讯口向PC机传送PLC工作状态及有关数据,同时从PC机接受指令,向蜂鸣器、指示灯、滑油泵、控制手柄的位置等发出命令,实现PC机对控制系统的管理,提高了PLC的控制能力和控制范围,使整个系统成为集散控制系统。
2.通讯协议
计算机与PLC进行通讯时,计算机与PLC之间是以帧为单位进行信息交换的,其中控制字符ENQ、ACK、NAK,可以构成单字符帧发送和接受,其余的信息帧发送和接受时都是由字符STX、命令字、数据、字符ETX以及和校验5部分组成。
校验和在信息帧的尾部用来判断传输的正确与否,和校验码的计算方法是将命令码到ETX之间的所有字符的ASCⅡ码(十六进制数)相加,取所得和的最低2位数,在后面的通信程序设计里面还会提到。进行差错检验的方法很多,常用的有奇偶校验码,水平垂直冗余校验LRC,目前广泛使用的是CRC校验码,它能查处99%以上18位或更长的突出错误,而在计算机与PLC点对点的短距离通讯时,出错的几率较小,因而采用校验和法,基本能满足要求。
3.多线程技术及在VC++串口通信程序中的实现
在Windows的一个进程内,包含一个或多个线程,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等等。
Windows内部的抢先调度程序在活动的线程之间分配CPU时间,Windows区分两种不同类型的线程,一种是用户界面线程(UserInterfaceThread),它包含消息循环或消息泵,用于处理接收到的消息;另一种是工作线程(WorkThread)它没有消息循环,用于执行后台任务、监视串口事件的线程即为工作线程。
本系统采用MFC编程方法,MFC是把串口作为文件设备来处理的,它用CreateFile()打开串口,并获得一个串口句柄,用SetCommState()进行端口配置,包括缓冲区设置,超时设置和数据格式等。然后调用函数ReadFile()和WriteFile()进行数据的读写,用WaitForSingleObject()监视通信事件。在用ReadFile()和WriteFile()读写串口时,一般采用重叠方式。因为同步I/O方式是当程序执行完毕才返回,这样会阻塞其他线程,降低程序执行效率。而重叠方式能使调用的函数立即返回,I/O操作在后台进行,这样线程就可以处理其他事务,同时也实现了线程在同一串口句柄上实现读写操作。
使用重叠I/O方式时,线程要创建OVERLAPPED结构供读写函数使用,该结构最重要的成员是hEvent事件句柄。它将作为线程的同步对象使用,读写函数完成时hEvent处于有信号状态,表示可进行读写操作;读写函数未完成时,hEvent被置为无信号。
利用Windows的多线程技术,在辅助线程中监视串口,有数据到达时依靠事件驱动,读入数据并向主线程报告;并且,依靠重叠读写操作,让串口读写操作在后台运行。
4.上位计算机通信程序设计
BOOLCPlcComDlg::ReadFromPLC(char*Read_char,char*Read_address,intRead_bytes)
{CSerialSerial;//用于串行通讯的类
if(Serial.Open(1))//初始化串行通讯口COM1
{Serial.SendData(&ENQ_request,1);//发送联络讯号
Sleep(20);//等待20ms秒
Serial.ReadData(&read_BUFFER,1);//读取PLC响应讯号
if(read_BUFFER==ACK){
……
Serial.SendData(&STX_start,1);//向PLC发送“开始”标志代码
Serial.SendData(&CMD0_read,1);//发送“读”命令代码
datasum_check+=CMD0_read;
for(i=0;i<4;i++){
……
Serial.SendData(&ETX_end,1);//发送结束标志代码
Change_to_ASCII(senddatasum_CHECK,datasum_check);//将“和”转化成ASCⅡ代码
Sleep(40);//等待PLC的反应
……
Serial.ReadData(&Read_char[i>,1);//读Read_bytes个字节
if(*readdatasum_CHECK==*readdatasum_check)//“和”效验
{AfxMessageBox("数据读取成功!");
returnTRUE;}
else{AfxMessageBox("校验错误!");
returnFALSE;}}
}
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
以上是关于多线程技术的PLC与PC的通讯方式的主要内容,如果未能解决你的问题,请参考以下文章