⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 softplc.cpp 的old

📁 Vxworks 下重矿设备应用开发
💻 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 + -