S7-1500模拟量用SCL写批量转化程序

6 篇文章 2 订阅
6 篇文章 2 订阅
FUNCTION_BLOCK "模拟量转换"
TITLE = 模拟量输入转换
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : SDZYG2000
FAMILY : 77-1500
NAME : AI_OUT
VERSION : 1.0
//
// 模拟量输入量程批量转换
//
// Block Parameters
   VAR_INPUT 
      ADDRESS : Int := 512;   //   开始的PIW地址
      NUM : Int := 1;   //   仪表数量即多少个PIW地址
      Sdata : DInt := 2;
      DATA_NUM : DInt;   //   用于存放数据的量程 偏差设定
      VALUE_NUM : DInt;   //   存放输出结果
   END_VAR

   VAR 
      K1 : Real;
      K2 : Real;
   END_VAR

   VAR_TEMP 
      I : DInt;   //   循环变量
      IW_INT_VAL : Int;
      IW_VAL : Real;
      HI_VAL : Real;
      LI_VAL : Real;
      OF_VAL : Real;
      DIP_VAL : Byte;
      TEMP : Real;
   END_VAR


BEGIN
	//###########################################################
	//采用FC105相同的计算公式OUT = ((FLOAT (IN) -K1)/(K2-K1)) * (HI_LIM-LO_LIM) + LO_LIM
	//增加一个修正偏差公式改为OUT = ((FLOAT (IN) -K1)/(K2-K1)) * (HI_LIM-LO_LIM) + LO_LIM + OFFSET
	//循环批量转换循环体
	//##########################################################
	(*		//参考数据类型
	TYPE "转换"
	VERSION : 0.1
	   STRUCT
		  VALUE : Real;   //  转换后输出值
		  ERR : Byte;   //  错误值 通道值超出范围即输出0位为1
	   END_STRUCT;

	END_TYPE
	//-----------------
	TYPE "量程"
	VERSION : 0.1
	   STRUCT
		  H : Real := 1000.0;   //  量程上限设定值
		  L : Real := 0.0;   //  量程下限设定值
		  OFF : Real := 2.0;   //  修正偏差设定值
		  DIP : Byte;   //  双极性设置
	   END_STRUCT;

	END_TYPE
	*)
	(*		//参数DB块数据结构
	DATA_BLOCK "转换结果"
	{ S7_Optimized_Access := 'FALSE' }
	VERSION : 0.1
	NON_RETAIN
	   STRUCT 
		  Static_1 : Array[0..50] of "转换";
	   END_STRUCT;
	BEGIN
	
	END_DATA_BLOCK
	//----------------------
	DATA_BLOCK "DB10"
	{ S7_Optimized_Access := 'FALSE' }
	VERSION : 0.1
	NON_RETAIN
	   STRUCT 
		  A11 : Array[0..50] of "量程";   
	   END_STRUCT;
	BEGIN

	END_DATA_BLOCK
	*)
	FOR #I := 1 TO #NUM BY 1 DO
	    //读取IW地址以及数据块的参数
	    //------------------------------------------
	    (*#IW_INT_VAL := WORD_TO_INT(PEEK_WORD(area := 16#81, dbNumber := 0, byteOffset := #ADDRESS + (#I - 1) * 2));//数据有正负性,必须转换为INT格式*)
	    #IW_INT_VAL := WORD_TO_INT(PEEK_WORD(area := 16#84, dbNumber :=#Sdata, byteOffset := #ADDRESS + (#I - 1) * 2));//数据有正负性,必须转换为INT格式
	    #IW_VAL := DINT_TO_REAL(INT_TO_DINT(#IW_INT_VAL));
	    #HI_VAL := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14));
	    #LI_VAL := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 4));
	    #OF_VAL := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 8));
	    #DIP_VAL := PEEK_BYTE(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 12);
	    //-------------------------------------------
	    //判断是否是双极性
	    //读取数据库参数判断是否是双极性,0为单极性,>=1为双极性并判断通道值是否溢出
	    //-----------------------------------------------------
	    IF #DIP_VAL >= 16#1 THEN
		
	        //双极性
	        #K1 := -27648.0;
	        #K2 := 27648.0;
	        //读取IW数值通过数值判断数值是否异常若异常则将异常状态写入数据块,异常就给错误字0位写1	        
	        IF #IW_INT_VAL <= -27649 OR #IW_INT_VAL >= 27649 THEN	            
	            POKE_BOOL(area := 16#84,
	                      dbNumber := #VALUE_NUM,
	                      byteOffset := (#I - 1) * 6 + 4,
	                      bitOffset := 0,
	                      value := TRUE);
	           
	            #TEMP := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #VALUE_NUM, byteOffset := (#I - 1) * 6)); //不在量程范围内则读取当前输出的值给TEMP变量
	            
	            // #TEMP := 0.0;//不在量程范围内输出为0;
	        ELSE
	            POKE_BOOL(area := 16#84,
	                      dbNumber := #VALUE_NUM,
	                      byteOffset := (#I - 1) * 6 + 4,
	                      bitOffset := 0,
	                      value := FALSE);
	            //若在量程范围内就做量程转换
	            //#TEMP := (#IW_VAL - #K1) / (#K2 - #K1) * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
	            //算法优化
	            #TEMP := (#IW_VAL + 27648.0) / 55296.0 * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
	        END_IF;
	        
	    ELSE
	        //单极性
	        #K1 := 0.0;
	        #K2 := 27648.0;
	        //读取IW数值通过数值判断数值是否异常若异常则将异常状态写入数据块,异常就给错误字0位写1
	        IF (#IW_INT_VAL >= 27649) OR (#IW_INT_VAL <= -1) THEN
	            // IF #IW_INT_VAL<=-1 THEN
	            POKE_BOOL(area := 16#84,     dbNumber := #VALUE_NUM,  byteOffset := (#I - 1) * 6 + 4, bitOffset := 0,value := TRUE);	            
	            #TEMP := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #VALUE_NUM, byteOffset := (#I - 1) * 6));//不在量程范围内则读取当前输出的值给TEMP变量
	            //不在量程范围内输出为0;
	            // #TEMP := 0.0;
	        ELSE
	            POKE_BOOL(area := 16#84,
	                      dbNumber := #VALUE_NUM,
	                      byteOffset := (#I - 1) * 6 + 4,
	                      bitOffset := 0,
	                      value := FALSE);
	            //若在量程范围内就做量程转换
	            //#TEMP := (#IW_VAL - #K1) / (#K2 - #K1) * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
	            //算法优化
	            #TEMP := #IW_VAL / 27648.0 * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
	            
	        END_IF;
	        
	    END_IF;
	    //-------------------------------------------------------
	    POKE(area := 16#84,dbNumber := #VALUE_NUM, byteOffset := (#I - 1) * 6,value := REAL_TO_DWORD(#TEMP));
	    
	END_FOR;
	
	
	
	
END_FUNCTION_BLOCK

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值