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

📄 plc_other.c

📁 以前做的一个仿PLC程序
💻 C
📖 第 1 页 / 共 2 页
字号:
;/****************************************Copyright (C)**************************************************
;**                               	Email:luheding@126.com
;**                                 QQ:614090042                                            
;**                          如有意见或不明可联系,但要注明来意.否则不回                                 
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: PLC_Other.c
;**版        本: V2.1
;**创   建   人: LuHeDing
;**最后修改日期: 2010年05月08日
;**描        述: PLC其它程序集合
;** 
;********************************************************************************************************/

#include "..\Drive\PLC_PUBLIC.H"
/***********************************************
  函数功能:PLC代码错误处理程序
  err_id=01:指令出错(未识别指令)
  err_id=02:指令出错(暂不支持指令)

  err_id=10:数据出错(无法识别数据类型)
  err_id=11:数据出错(数据读取地址超出)
  err_id=12:数据出错(变址Z地址未知)
  err_id=13:数据出错(变址Z地址超出)
  err_id=20:CJ指令地址出错
  D8061,M8061=PC硬件错误
  D8063,M8063=链接,通信错误
  D8064,M8064=参数错误
  D8065,M8065=语法错误
  D8066,M8066=回路错误
  D8067,M8067=运算错误
  D8068,M8068=运算错误锁存
***********************************************/

void PLC_PROG_ERROR(uint16 err_id)
{PLC_BIT_ON(M8067);//出错标志 
 D8012=0;	  //扫描时间
 if (D8068==0)D8065=err_id;//语法错误
 if (D8068==0)D8068=(PLC_PC-PLC_PROG_START_ADD2)/2;//保存出错PC步
 D8069=D8068;
 PLC_RUN_BIT+=6;//PLC运行标志进入出错
 PLC_BIT_OFF(M8000);	 //关闭M8000
 PLC_PC=PLC_PROG_END_ADD;//结束程序运行
}

/***********************************************
  函数功能:PLC通信错误处理程序
  D8063,M8063=链接,通信错误
  0000=无异常;
  6301=奇偶检验错误
  6302=通信字符错误
  6303=通信和校验出错
  6304=数据格式错误
  6305=指令错误
***********************************************/

void PLC_COMM_ERROR(uint16 err_id)
{if(err_id!=0)PLC_BIT_ON(M8063);//出错标志 
 D8063=err_id;
}


/***********************************************
  函数功能:复制数据
***********************************************/

/*void PLC_R_COPY(uint32 C_add_s,uint32 C_add_e,uint32 P_add_s)
{uint32 count=0;
 C_add_e+=1;
 for(;C_add_e>C_add_s;C_add_s++)
 	{PLC_RAM8(P_add_s+count)=PLC_RAM8(C_add_s);count++;}
} */
 
/***********************************************
  函数功能:上电数据复位
***********************************************/

void PLC_PowerUpReset(void)
{uint32 S_Add,S_Add2,E_Add;
 S_Add=PLC_R_START_ADD;
 E_Add=PLC_R_END_ADD;
 for(;S_Add<=E_Add;){PLC_RAM32(S_Add)=0;S_Add+=4;}//复位所有寄存器
 //S_Add=0x50000;E_Add=0x5007F;S_Add2=PLC_R_START_ADD;       //S0-S1024	    0x0000-0x007F   FX1N
 S_Add=0x5003E;E_Add=0x5007F;S_Add2=PLC_R_START_ADD+0X003E;  //S500-S1024	0x003E-0x007F	FX2N
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add2)=PLC_RAM8(S_Add);S_Add++;S_Add2++;}
 PLC_BIT_OFF(496);PLC_BIT_OFF(497);PLC_BIT_OFF(498);PLC_BIT_OFF(499);      //RST S496-S499 FX2N
 //S_Add=0x50130;E_Add=0x501DF;S_Add2=PLC_R_START_ADD+0x0130;//M384-M1535      0x0130-0x01DF		FX1N
 S_Add=0x5013E;E_Add=0x501DF;S_Add2=PLC_R_START_ADD+0x013E;//M500-M3071(M1535) 0x013E-0x01DF		FX2N
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add2)=PLC_RAM8(S_Add);S_Add++;S_Add2++;}
 PLC_BIT_OFF(0X09F0);PLC_BIT_OFF(0X09F1);PLC_BIT_OFF(0X09F2);PLC_BIT_OFF(0X09F3);      //RST M496-M499 FX2N
 //S_Add=0x51100;E_Add=0x54E7F;S_Add2=PLC_R_START_ADD+0x1100;//D128-D7999 0x1100-0x4E7F  FX1N
 S_Add=0x51190;E_Add=0x54E7F;S_Add2=PLC_R_START_ADD+0x1190;//D200-D7999 0x1100-0x4E7F  FX2N
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add2)=PLC_RAM8(S_Add);S_Add++;S_Add2++;}
 S_Add=0x50AC8;E_Add=0x50B8F;S_Add2=PLC_R_START_ADD+0x0AC8;//C100-C199 0x0AC8-0x0B8F  FX2N
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add2)=PLC_RAM8(S_Add);S_Add++;S_Add2++;}
  S_Add=0x50C00;E_Add=0x50CDF;S_Add2=PLC_R_START_ADD+0x0C00;//C200-C255 0x0C00-0x0CDF  FX2N
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add2)=PLC_RAM8(S_Add);S_Add++;S_Add2++;}
//复位D8000 
 D8000 = 200;D8001 = PLC_Type;D8101 = PLC_Type;D8002 = 8;	
 D8102 = 8;D8003 = 0x10;D8010 = 10;D8011 = 20;D8012 = 140;			   	
}

/***********************************************
  函数功能:保存旧线圈值 SXMTCY
***********************************************/

void PLC_O_BIT_KEEP(void)
{uint32 S_Add,S_Add2,E_Add;
 S_Add=PLC_R_START_ADD+0x0400;E_Add=PLC_R_START_ADD+0x05FF;S_Add2=PLC_R_START_ADD+0x0600;
 for(;S_Add<=E_Add;){PLC_RAM32(S_Add2)=PLC_RAM32(S_Add);S_Add+=4;S_Add2+=4;}//0x0400-0x05FF->0x0600-0x07FF
 S_Add=PLC_R_START_ADD;E_Add=PLC_R_START_ADD+0x01FF;S_Add2=PLC_R_START_ADD+0x0400;
 for(;S_Add<=E_Add;){PLC_RAM32(S_Add2)=PLC_RAM32(S_Add);S_Add+=4;S_Add2+=4;}//0x0000-0x01FF->0x0400-0x05FF
}

/***********************************************
  函数功能:计时
  T000-T199 100Ms T200-T245 10Ms
  T246-T249 1Ms	  T250-T255 100Ms(保持)
***********************************************/
uint8 PLC_T_TIME;
void PLC_T_COUNT(void)
{uint16 count,count2;
 uint32 TimeAdd;
 PLC_T_TIME++;
 if(PLC_T_TIME%10==0)
   {count=200;count2=249;TimeAdd=PLC_T_START_ADD+400;}  //跳过T000-T199&T250-T255
 else{count=246;count2=249;TimeAdd=PLC_T_START_ADD+492;}//跳过T000-T245&T250-T255
 if(PLC_T_TIME>=100){PLC_T_TIME=0;count=0;count2=255;TimeAdd=PLC_T_START_ADD;}//全部执行
 for(;count<=count2;count++)
	{if(PLC_T_C_BIT_TEST(count)&&	   //测试线圈
	    PLC_T_OUT_BIT_TEST(count)==0&&   //测试输出
		PLC_T_RST_TEST(count)==0)	   //测试复位标志
	   {PLC_RAM16(TimeAdd)++;}
	 TimeAdd+=2;  
	}
}

/***********************************************
  函数功能:结束指令后处理的程序
***********************************************/

void PLC_END_PROG(void)
{PLC_PC=PLC_PROG_START_ADD2;//初始PC指针
 PLC_O_BIT_KEEP();	 //保存旧线圈值 SXMTCY
 PLC_IO_BREAK();	 //输出刷新
 D8012=PLC_RUN_TIME; //保存扫描时间
 PLC_RUN_TIME=0;	 //清除扫描时间
 PLC_BIT_OFF(M8002);
 PLC_BIT_ON(M8003);
}


/***********************************************
  函数功能:STOP_RUN前数据复位
  0x0000-0x009F	S X不复位
  0x00A0-0x012F	Y0-Y177 T0-T255(C) M0-M383
  0x01C0-0x17CF C0-C255(C) M8000-M8255 O_BIT D0-D999
  0x4E80-0x5B8F;空出部分
  0x5B90-0x5FFF;监视部分不复位
***********************************************/

void PLC_RESET_RAM(void)
{uint32 S_Add,E_Add;
 H_Y0_Y1_STOP();
 S_Add=PLC_R_START_ADD+0x00A0;E_Add=PLC_R_START_ADD+0x012F;
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add)=0;S_Add++;}//0x00A0-0x012F
 S_Add=PLC_R_START_ADD+0x01C0;E_Add=PLC_R_START_ADD+0x118F;	
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add)=0;S_Add++;}//0x01C0-0x118F
 S_Add=PLC_R_START_ADD+0x4E80;E_Add=PLC_R_START_ADD+0x5B8F;
 for(;S_Add<=E_Add;){PLC_RAM8(S_Add)=0;S_Add++;}//0x4E80-0x5B8F
	 PLC_1MS_BIT=0;
	 PLC_RUN_BIT=0;
 	 PLC_PC=PLC_PROG_START_ADD2;  //初始化PLC程序指针
  	 D8000 = 200;		   		//扫描时间
	 D8001 = PLC_Type;	   		//型号版本 FX2N(C)
	 D8101 = PLC_Type;	   		//型号版本 FX2N(C)
	 D8002 = 8;			   		//内存容量
	 D8102 = 8;			   		//内存容量
	 D8003 = 0x0010; 	   		//内存类型
	 D8010 = 10;			   	//扫描当前值
     D8011 = 20;			   	//扫描最小时间(0.1MS)
	 D8012 = 140;			   	//扫描最长时间(0.1MS) 
 H_Y0_Y1_STOP();
}

/***********************************************
  函数功能:IO口初始化
***********************************************/

void PLC_IO_INIT(void)
{LPC_GPIO1->FIODIR |=O1|O2|O3;
 LPC_GPIO1->FIOSET =O1|O2|O3;
 LPC_GPIO4->FIODIR |=O4;
 LPC_GPIO4->FIOSET =O4;
 LPC_GPIO2->FIODIR |=Y0|Y1|Y2|Y3|Y4|Y5|Y6|Y7;
 LPC_GPIO2->FIOSET =Y0|Y1|Y2|Y3|Y4|Y5|Y6|Y7;
 LPC_GPIO1->FIODIR |=X0_OE;
}

/***********************************************
  函数功能:IO口初始化
***********************************************/

void PLC_Init(void)
{   unsigned char count;	 
	LPC_GPIO1->FIODIR|=O1|O2|O3;
	LPC_GPIO1->FIODIR|=O1|O2|O3;
	LPC_GPIO1->FIOCLR=O2|O3;
	LPC_GPIO1->FIOCLR=O2|O3;
	LPC_GPIO1->FIOCLR=O2|O3;
	LPC_GPIO1->FIOCLR=O2|O3;
	for(count=0;count<32;count++)
	{LPC_GPIO1->FIOCLR=O1;
	 LPC_GPIO1->FIOCLR=O1;
	 LPC_GPIO1->FIOCLR=O1;
	 LPC_GPIO1->FIOCLR=O1;
	 LPC_GPIO1->FIOSET=O1;
	 LPC_GPIO1->FIOSET=O1;
	 LPC_GPIO1->FIOSET=O1;
	 LPC_GPIO1->FIOSET=O1;
	}
	LPC_GPIO1->FIOSET=O2|O3;
	LPC_GPIO1->FIOSET=O2|O3;
	LPC_GPIO1->FIOSET=O2|O3;
	LPC_GPIO1->FIOSET=O2|O3;
}
/****************************************************************************
* 名称 : MyD_O_OUTPUT
* 功能 :IO输出
* 入口参数:
* 出口参数:
* 说明:  ok				 
****************************************************************************/
#define  diy_time	0x05
unsigned int MyD_I_DATA,MyD_O_DATA;
unsigned int TempOutData; unsigned long long TempIntData;
unsigned char IO_Count,IO_CMD,IO_Diy;
void  MyD_IO_Refresh(void) {
	if(IO_CMD==0)
	  {if(IO_Diy<diy_time)IO_Diy++;
	   else{TempOutData=MyD_O_DATA;
	        LPC_GPIO1->FIOCLR=O2;
	        LPC_GPIO4->FIOCLR =O4;
	        IO_Diy=0;IO_CMD=1;}
	  }
	else if(IO_CMD==1)
		{if(IO_Diy<diy_time)IO_Diy++;
		 else{LPC_GPIO4->FIOSET =O4;
			  IO_Diy=0;IO_CMD=2;}
		}
	else if(IO_CMD==2)
		{if(IO_Diy<diy_time)IO_Diy++;
		 else{if ((LPC_GPIO4->FIOPIN&I5)!=I5){TempIntData++;}
			  TempIntData<<=1;
			  IO_Count=31;
			  IO_Diy=0;IO_CMD=4;}
		}
	else if(IO_CMD==4)
		{if(IO_Diy<diy_time)IO_Diy++;
		 else{LPC_GPIO1->FIOCLR=O1;
		      if ((TempOutData&0x80000000)!=0x80000000) {LPC_GPIO1->FIOCLR=O3;}
	          else 	{LPC_GPIO1->FIOSET=O3;}
		 	  TempOutData<<=1;
			  IO_Diy=0;IO_CMD=5;}}
	else if(IO_CMD==5)
		{if(IO_Diy<diy_time)IO_Diy++;
		 else{if ((LPC_GPIO4->FIOPIN&I5)!=I5){TempIntData++;}
	          TempIntData<<=1;
		      LPC_GPIO1->FIOSET=O1;
			  if(IO_Count!=0){IO_Count--;IO_Diy=0;IO_CMD=4;}
			  else
			  	{IO_Diy=0;
				 TempIntData>>=1;
				 MyD_I_DATA=(((TempIntData&0xff)*0x1000000)+((TempIntData&0xff000000)/0x1000000)+((TempIntData&0xff0000)>>8)+((TempIntData&0xff00)<<8));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -