📄 softplc.cpp 的old
字号:
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "malloc.h"
#include "system.h"
#define OPEN 0
#define STOP 0
#define START 1
#define CLOSE 1
#define AddSpaceError 0x0001
#define SignalError 0x0002
#define AddrError 0x0003
#define InstructionError 0x0004
#define GetInfoErr 0x0005
#define PushError 0x0006
#define PopError 0x0007
#define iInstructionError 0x0008
static char *DeleteLeftSpace(char *Chg_Str);
static void Push(void);
static void Pop(void);
static void RunALine(bool Fl_Pop);
static void ReportErr(int ErrCode);
static void ExcuteLD(void);
static char *strrev(char *str);
static int LetterCnt(const char *str,int letter);
static char *DeleteDoubleSpace(char *Chg_Str);
static char *DeleteRightSpace(char *Chg_Str);
static void GetInfo(char *str);
static void SeparateALine(char *sOriginLine) ;
static void SeparateSeg(char *Str);
static void ExcuteLD(void);
static void ExcuteLDN(void);
static void ExcuteAND(bool Fl_Pop);
static void ExcuteANDN(bool Fl_Pop);
static void ExcuteOR(bool Fl_Pop);
static void ExcuteORN(bool Fl_Pop);
static void ExcuteXOR(bool Fl_Pop);
static void ExcuteXORN(bool Fl_Pop);
static void ExcuteST(void);
static void ExcuteSTN(void);
static void ExcuteS(void);
static void ExcuteR(void);
extern void ImageIn(void);
extern void ImageOut(void);
int Flag_Chgil = 0;
char Signal,DataWidth;
int iSignal=0,iInstruction=0,iFirstAddr=0,iSecondAddr=0,iThirdAddr=0;
int iTop=0,iLine=0,iColumn=0;
short int Stack[2][10]={{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0}};
int bStack[100],bCR=0,Fl_Pop=0,Test[8];
bool In[8]={0,0,0,0,0,0,0,0},Out[8]={0,0,0,0,0,0,0,0},nOut[8]={1,1,1,1,1,1,1,1};
bool Addr[3][10][8]={{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}};
//bool CPI[8]={0,0,0,0,0,0,0,0},CPO[8]={0,0,0,0,0,0,0,0};
//Jackie
//extern char Segment[1024*4];
//Jackie
/*************** AddSpace 插入空格来分解括号
void AddSpace(char *Chg_Str)
{ char *str;
unsigned int jChrLen;
for (jChrLen=0;jChrLen<strlen(Chg_Str);jChrLen++)
{
if (((Chg_Str[jChrLen]!=' ')&&(Chg_Str[jChrLen+1]=='('))||((Chg_Str[jChrLen]!=' ')&&(Chg_Str[jChrLen+1]==')'))||((Chg_Str[jChrLen]=='(')&&(Chg_Str[jChrLen+1]!=' '))||((Chg_Str[jChrLen]==')')&&(Chg_Str[jChrLen+1]!=' ')))
{
strcpy(str,Chg_Str+jChrLen+1);
strcpy(Chg_Str+jChrLen+2,str);
Chg_Str[jChrLen+1]=' ';
}
}
return;
}
*/
/**************
* 函数名:strrev
* 功 能: 翻转字符串,将字符串逆向排列
*
*************/
char *strrev(char *str)
{
char *original =str;
char *forward =str;
char temp;
while (*str)
str++;
while (forward < str)
{
temp=*(--str);
*str=*forward;
*forward++=temp;
}
return (original);
}
/**************
* 函数名:strrevLetterCnt
* 功 能: 计算字符串中字符出现的次数
*
**************/
int LetterCnt(const char *str,int letter)
{
int iLetterCnt=0;
while (*str)
{if (*str==letter)
iLetterCnt++;
str++;}
return iLetterCnt;
}
/**************
* 函数名:DeleteLeftSpace
* 功 能: 删除一行(S)的左空格,例如将" LD %I0.0"转化为"LD %I0.0"
*
**************/
char *DeleteLeftSpace(char *Chg_Str)
{
while (Chg_Str[0]==' ')
strcpy(Chg_Str,Chg_Str+1);
return (Chg_Str);
}
/**************
* 函数名:DeleteDoubleSpace
* 功 能: 删除两个以上的连续空格为一个空格
*
**************/
char *DeleteDoubleSpace(char *Chg_Str)
{ unsigned int iCnt,jChrLen;
for (jChrLen=0;jChrLen<strlen(Chg_Str);jChrLen++)
{ if (Chg_Str[jChrLen]==' ')
{ iCnt=jChrLen+1;
while (Chg_Str[iCnt]==' ')
strcpy(Chg_Str+iCnt,Chg_Str+iCnt+1);
}
}
return (Chg_Str);
}
/**************
* 函数名:DeleteRightSpace
* 功 能: 删除一行(S)的右空格
*
**************/
char *DeleteRightSpace(char *Chg_Str)
{
strrev(Chg_Str);
DeleteLeftSpace(Chg_Str);
strrev(Chg_Str);
return (Chg_Str);
}
/**************
* 函数名:GetInfo
* 功 能: 分解一个单元,得到{I,Q,M},{Addr},{Instruction}
*
**************/
void GetInfo(char *str)
{ int AddrCnt;
if (str[0]=='%')
{
strcpy(str,str+1); //右移一位
Signal= str[0];
switch (Signal)
{
case 'I': iSignal=0;break;
case 'Q': iSignal=1;break;
case 'M': iSignal=2;break;
default:ReportErr(SignalError);
}
/*************** 判断数据位宽度DataWidth
*************** 无--用0表示
***************/
strcpy(str,str+1); //右移一位
if (isdigit(str[0]))
DataWidth='0';
else
DataWidth= str[0];
strcpy(str,str+1);
/*************** 判断有几个"."
**************** 得出FirstAddr,SecondAddr
***************/
AddrCnt=1+LetterCnt(str,'.');
switch (AddrCnt)
{
case 1: iFirstAddr=atoi(str);break;
case 2: iFirstAddr=atoi(strtok(str,"."));iSecondAddr=atoi(strtok( NULL ,"."));break;
// case 3: FirstAddr=strtok(S,".");SecondAddr=strtok( NULL ,".");ThirdAddr=strtok( NULL ,".");break;
default: ReportErr(AddrError);
}
/* printf("Signal=%c\n",Signal);
printf("DataWidth=%c\n",DataWidth);
printf("FirstAddr=%d\n",iFirstAddr);
if (AddrCnt==2) printf("SecondAddr=%d\n",iSecondAddr);
*/ // printf("ThirdAddr=%s\n",ThirdAddr);
// Addr[iSignal][iFirstAddr][iSecondAddr]=1;
// printf("Addr[iSignal][iFirstAddr][iSecondAddr]=%d\n",Addr[iSignal][iFirstAddr][iSecondAddr]);
}
else if (isalpha(str[0]))
{
if (!strcmp(str,"LD")) iInstruction=0;
else if (!strcmp(str,"LDN")) iInstruction=1;
else if (!strcmp(str,"AND")) iInstruction=2;
else if (!strcmp(str,"ANDN")) iInstruction=3;
else if (!strcmp(str,"OR")) iInstruction=4;
else if (!strcmp(str,"ORN")) iInstruction=5;
else if (!strcmp(str,"XOR")) iInstruction=6;
else if (!strcmp(str,"XORN")) iInstruction=7;
else if (!strcmp(str,"ST")) iInstruction=8;
else if (!strcmp(str,"STN")) iInstruction=9;
else if (!strcmp(str,"S")) iInstruction=10;
else if (!strcmp(str,"R")) iInstruction=11;
else ReportErr(InstructionError);
}
else if (str[0]=='(')
{
Push();
}
else if (str[0]==')')
{
Pop();
}
else ReportErr(GetInfoErr);
}
/**************
* 函数名:SeparateALine
* 功 能: 分割一行,结果为sTemp[]
*
**************/
void SeparateALine(char *sOriginLine)
{
char *sTemp[100],*sCpyOfOrigin;
int i_sTemp=0,iLenOrigin;
// AddSpace(sOriginLine);
sOriginLine=strupr(sOriginLine);//全部改为大写
DeleteLeftSpace(sOriginLine); //处理左空格
DeleteRightSpace(sOriginLine);
DeleteDoubleSpace(sOriginLine);
// printf(" sOriginLine=%s\n",sOriginLine);
iLenOrigin=strlen(sOriginLine);
sCpyOfOrigin=(char *)malloc(iLenOrigin+1);
if (LetterCnt(sOriginLine,' ')==0)
{
// printf(" 2sOriginLine=%s\n",sOriginLine);
// strcpy(sTemp[0],sOriginLine);
sTemp[0]=sOriginLine;
strcpy(sCpyOfOrigin,sOriginLine);
GetInfo(sCpyOfOrigin);
// printf("sTemp[0]=%s\n",sTemp[0]);
// Do Run this line as the ' 'number =0
// strcpy(S,sTemp[0]);
}
else
{
do
{
sTemp[i_sTemp]=strtok(sOriginLine," ");//原来字符串取前段
// printf(" sTemp[%d]=%s ",i_sTemp,sTemp[i_sTemp]);
// strcpy(S,sTemp[i_sTemp]);
strcpy(sCpyOfOrigin,sTemp[i_sTemp]);
GetInfo(sCpyOfOrigin);
strcpy(sOriginLine,sOriginLine+strlen(sTemp[i_sTemp])+1);//生成新的行
// printf(" sOriginLine=%s",sOriginLine);
// strcpy(sCpyOfOrigin,sOriginLine);
// GetInfo(sCpyOfOrigin);
i_sTemp++;
if (LetterCnt(sOriginLine,' ')==0)
{ sTemp[i_sTemp]=strtok(sOriginLine," ");
// printf(" sTemp[%d]=%s ",i_sTemp,sTemp[i_sTemp]);
strcpy(sCpyOfOrigin,sTemp[i_sTemp]);
GetInfo(sCpyOfOrigin);
// printf("-------------------------------------\n");
break;}
}while ((strlen(sOriginLine))!=0);
}if (Fl_Pop==0) RunALine(0);Fl_Pop=0;
free(sCpyOfOrigin);
return;
}
/**************
* 函数名:SeparateSeg
* 功 能: 分割IL.TXT,结果为Line[]
*
**************/
void SeparateSeg(char *Str)
{ char *sLine[100],sTmp[100];
int iCnt,iLineCnt;
iLineCnt=LetterCnt(Str,'\n'); //如果Seg用\0D\0A,要用iLineCnt=LetterCnt(Str,13);
if (iLineCnt==0)
{
SeparateALine(Str);
iCnt=0;
}
else {
sLine[0]=strtok(Str,"\n");
for (iCnt=1;iCnt<iLineCnt;iCnt++)
sLine[iCnt]=strtok(NULL,"\n");
for (iCnt=0;iCnt<iLineCnt;iCnt++)
{
strcpy(sTmp,sLine[iCnt]);
SeparateALine(sTmp);
}
}
return;
}
/**************
* 函数名:Push
* 功 能: 入栈
*
**************/
void Push(void)
{
if (iTop==99) ReportErr(PushError);
Stack[0][iTop] = iInstruction;
Stack[1][iTop] = bCR;
iTop=iTop+1;
}
/**************
* 函数名:Pop
* 功 能: 出栈
*
**************/
void Pop(void)
{
if (iTop<1)
{
ReportErr(PopError);
}
else
{
iTop=iTop-1;
iInstruction = Stack[0][iTop];
Fl_Pop=1;
RunALine(1);
Stack[0][iTop] = 0;
Stack[1][iTop] = 0;
}
}
/**************
* 函数名:ExcuteLD
* 功 能: 执行LD指令
*
**************/
void ExcuteLD(void)
{
bCR=Addr[iSignal][iFirstAddr][iSecondAddr];
}
/**************
* 函数名:ExcuteLDN
* 功 能: 执行LDN指令
*
**************/
void ExcuteLDN(void)
{
bCR=!Addr[iSignal][iFirstAddr][iSecondAddr];
}
/**************
* 函数名:ExcuteAND
* 功 能: 执行AND指令
*
**************/
void ExcuteAND(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=bCR&&Addr[iSignal][iFirstAddr][iSecondAddr];
else bCR=bCR&&Stack[1][iTop];
}
/**************
* 函数名:ExcuteANDN
* 功 能: 执行ANDN指令
*
**************/
void ExcuteANDN(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=bCR&&!(Addr[iSignal][iFirstAddr][iSecondAddr]);
else bCR=Stack[1][iTop]&&bCR;
}
/**************
* 函数名:ExcuteOR
* 功 能: 执行OR指令
*
**************/
void ExcuteOR(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=bCR||Addr[iSignal][iFirstAddr][iSecondAddr];
else bCR=bCR||Stack[1][iTop];
}
/**************
* 函数名:ExcuteORN
* 功 能: 执行ORN指令
*
**************/
void ExcuteORN(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=bCR||!(Addr[iSignal][iFirstAddr][iSecondAddr]);
else bCR=Stack[1][iTop]||!bCR;
}
/**************
* 函数名:ExcuteORN
* 功 能: 执行ORN指令
*
**************/
void ExcuteXOR(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=(((!bCR)&&Addr[iSignal][iFirstAddr][iSecondAddr])||(bCR&&(!Addr[iSignal][iFirstAddr][iSecondAddr])));
else bCR=(((!bCR)&&Stack[1][iTop])||(bCR&&(!Stack[1][iTop])));
}
/**************
* 函数名:ExcuteXORN
* 功 能: 执行XORN指令
*
**************/
void ExcuteXORN(bool Fl_Pop)
{ if (Fl_Pop==0)
bCR=((bCR&&Addr[iSignal][iFirstAddr][iSecondAddr])||((!bCR)&&(!Addr[iSignal][iFirstAddr][iSecondAddr])));
else bCR=((bCR&&Stack[1][iTop])||((!bCR)&&(!Stack[1][iTop])));
}
/**************
* 函数名:ExcuteST
* 功 能: 执行ST指令
*
**************/
void ExcuteST(void)
{
Addr[iSignal][iFirstAddr][iSecondAddr]=bCR;
}
/**************
* 函数名:ExcuteSTN
* 功 能: 执行STN指令
*
**************/
void ExcuteSTN(void)
{
Addr[iSignal][iFirstAddr][iSecondAddr]=!bCR;
}
/**************
* 函数名:ExcuteS
* 功 能: 执行S指令
*
**************/
void ExcuteS(void)
{ if (bCR==1)
Addr[iSignal][iFirstAddr][iSecondAddr]=1;
}
/**************
* 函数名:ExcuteR
* 功 能: 执行R指令
*
**************/
void ExcuteR(void)
{ if (bCR==1)
Addr[iSignal][iFirstAddr][iSecondAddr]=0;
}
/**************
* 函数名:RunALine
* 功 能: 执行一行PLC语句
*
**************/
void RunALine(bool Flag_Pop)
{ switch (iInstruction)
{
case 0:ExcuteLD();break;
case 1:ExcuteLDN();break;
case 2:ExcuteAND(Flag_Pop);break;
case 3:ExcuteANDN(Flag_Pop);break;
case 4:ExcuteOR(Flag_Pop);break;
case 5:ExcuteORN(Flag_Pop);break;
case 6:ExcuteXOR(Flag_Pop);break;
case 7:ExcuteXORN(Flag_Pop);break;
case 8:ExcuteST();break;
case 9:ExcuteSTN();break;
case 10:ExcuteS();break;
case 11:ExcuteR();break;
default:ReportErr(iInstructionError);
}
}
/**************
* 函数名:ReportErr
* 功 能: 报错
*
**************/
void ReportErr(int ErrCode)
{
printf("\nERROR CODE = %d\n",ErrCode);
}
/**************
* 函数名:RunIL
* 功 能: 运行PLC(Segment)
*
**************/
int RunIL()
{ char *Sdup;
int len;
Addr[0][1][0]=In[0];
Addr[0][1][1]=In[1];
Addr[0][1][2]=In[2];
Addr[0][1][3]=In[3];
Addr[0][1][4]=In[4];
Addr[0][1][5]=In[5];
Addr[0][2][0]=In[6];
Addr[0][2][1]=In[7];
Addr[1][1][0]=Out[0];
Addr[1][1][1]=Out[1];
Addr[1][1][2]=Out[2];
Addr[1][1][3]=Out[3];
Addr[1][1][4]=Out[4];
Addr[1][1][5]=Out[5];
Addr[1][2][0]=Out[6];
Addr[1][2][1]=Out[7];
/**************
* IL.txt的多行是用 \x0D \x0A来分隔的
* 用Segment表示一段文档
**************/
char *Segment= "LD %IX1.0\n OR %QX1.0\n ANDN %IX1.1\n ST %QX1.0\n LDN %QX1.0\n ST %QX1.1\n LD %IX1.2 \n OR %QX1.2 \n ANDN %IX1.3\n ANDN %IX1.5\n ST %QX1.2\n LD %IX1.3 \n OR %QX1.3 \n ANDN %IX1.1 \n ANDN %IX1.2 \n ANDN %IX1.4 \n ST %QX1.3 \n LD %IX1.4 \n OR %QX1.4 \n ANDN %IX1.1 \n ANDN %IX1.2 \n ANDN %IX1.3 \n ST %QX1.4 \n LD %IX1.5 \n OR %QX1.5 \n ANDN %IX1.1 \n ANDN %IX1.2\n ANDN %IX1.4 \n ST %QX1.5 \n LD %IX2.0 \n OR %QX2.0 \n ANDN %IX2.1 \n ST %QX2.0 \n LDN %QX2.0 \n ST %QX2.1 \n" ;
len=strlen(Segment);
Sdup=(char *)malloc(len+1);
strcpy(Sdup,Segment);
SeparateSeg(Sdup);
free(Sdup);
In[0]=Addr[0][1][0];
In[1]=Addr[0][1][1];
In[2]=Addr[0][1][2];
In[3]=Addr[0][1][3];
In[4]=Addr[0][1][4];
In[5]=Addr[0][1][5];
In[6]=Addr[0][2][0];
In[7]=Addr[0][2][1];
Out[0]=Addr[1][1][0];
Out[1]=Addr[1][1][1];
Out[2]=Addr[1][1][2];
Out[3]=Addr[1][1][3];
Out[4]=Addr[1][1][4];
Out[5]=Addr[1][1][5];
Out[6]=Addr[1][2][0];
Out[7]=Addr[1][2][1];
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -