【Codesys】DINT类型环形计数处理,计数到2的64次方-CODESYS资源下载区-酷德网 - CoDeSys软件教程下载,CoDeSys工控资讯门户 

酷德网

HSC6490-cn中国制造,中国芯~
查看: 912|回复: 0

【Codesys】DINT类型环形计数处理,计数到2的64次方

[复制链接]
  • TA的每日心情
    开心
    2017-11-20 22:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2024-11-6 20:02:14 | 显示全部楼层 |阅读模式
    最近有遇到编码器计数的计数处理,抓取编码器锁存的数值只能在DINT类型范围内,是从-2147483648到2147483647数值,但是现场会有正向多圈的情况。此时需要记录这个数的位置值。就需要记录多圈计数下,圈数的处理。
    PROGRAM FB_DintCirAcc
    VAR  
         currentCount :  DINT; // 当前计数器的值,DINT类型的范围是从-2147483648到2147483647
         circle1 : ULINT := 0; // 经过的极限值圈数  
         circle2 : ULINT := 0; // 经过的一次16位最大值的圈数
         maxThreshold :  DINT := 2147470000; // 接近最大值的阈值  
         minThreshold :  DINT := -2147470000; // 接近最小值的阈值  
         ZeroThreshold :  DINT := -10000; // 接近零值的阈值  
         approachingMax :  BOOL := FALSE; // 标志位,表示是否接近最大值  
         approachingMin :  BOOL := FALSE; // 标志位,表示是否接近最小值  
         approachingZero :  BOOL := FALSE; // 标志位,表示是否接近零值
         LastCount: DINT;//记录上一周的计数。
         bInit: BOOL:=TRUE;  //初始化
         bCountStrat: BOOL;    //模拟开始周期计数
         EncoderPos: LREAL;//编码器位置
         CalcPos: LREAL;//计数值累加位置
         ulCurrentCount:ULINT;//累加计数值
         DiffData: DINT;//负向累加差值
         UlCirData: ULINT;//负向时圈数值
    END_VAR  

    //模拟先给最大值,跑到第一圈的最大值
    IF bInit THEN
         currentCount:=2147400000;
         Encoder.diEncoderPosition:=currentCount;
         bInit:=FALSE;
    END_IF
    // 假设currentCount在每个周期更新  
    IF bCountStrat THEN
         currentCount := currentCount+10000;  
         Encoder.diEncoderPosition:=currentCount;
    END_IF

    // 检测是否接近最大值或最小值  
    IF (currentCount > maxThreshold) AND NOT approachingMax THEN  
         // 开始接近最大值  
         approachingMax := TRUE;  
    ELSIF currentCount>0 AND  (currentCount <= maxThreshold) AND approachingMax THEN  
         // 不再接近最大值  
         approachingMax := FALSE;  
    END_IF  
    // 检测是否接近最大值或最小值
    IF (currentCount < minThreshold) AND NOT approachingMin THEN  
         // 开始接近最小值  
         approachingMin := TRUE;  
    ELSIF currentCount<0 AND (currentCount >= minThreshold) AND approachingMin THEN  
         // 不再接近最小值  
         approachingMin := FALSE;  
    END_IF  
    // 检测负值累加是否接近0值。  
    IF (currentCount < ZeroThreshold)
         AND (currentCount>(ZeroThreshold*2))
         AND NOT approachingZero THEN  
         // 开始接近最小值  
         approachingZero := TRUE;  
    END_IF  
    // 检测是否从接近最大值过渡到接近最小值,累加一次计数
    IF approachingMax AND approachingMin THEN  
         // 从最大值过渡到最小值,计为一圈  
         circle1 := circle1 + 1;  
         circle2    := circle2 + 1;
         approachingMax := FALSE; // 重置接近最大值的标志  
         approachingMin := FALSE; // 重置接近最小值的标志  
    END_IF  
    // 检测是否从接近0值,累加一次计数
    IF approachingZero AND currentCount>0 THEN
         circle2    := circle2 + 1;
         approachingZero:=FALSE;
    END_IF
    Encoder.iTurn;
    IF  circle1 = 0 THEN
         ulCurrentCount:=(currentCount);
    ELSE
         IF currentCount>0 THEN
             ulCurrentCount:=(circle2*2147483647)+DINT_TO_ULINT(currentCount);
         ELSE
             IF circle1=1 THEN
                 DiffData:=ABS((2147483647-currentCount));
                 UlCirData:=(circle1*2147483647);
                 ulCurrentCount:=DINT_TO_ULINT(DiffData)+UlCirData;
             ELSIF circle1>1 THEN
                 DiffData:=ABS((2147483647-currentCount));
                 UlCirData:=(((circle1*2)-1)*2147483647);
                 ulCurrentCount:=DINT_TO_ULINT(DiffData)+UlCirData;
             END_IF
         END_IF
    END_IF
    EncoderPos:=Encoder.fActPosition;
    CalcPos:=(ulCurrentCount*97.456)/10000;

    【Codesys】DINT类型环形计数处理,计数到2的64次方-1.png
    +10
    不赞一个?
    打赏鼓励一下!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

    本版积分规则

    
    顶部qrcode底部
    关注酷德网订阅号,获取更多资讯!

    QQ|Archiver|手机版|小黑屋|酷德论坛 ( 苏ICP备16065247号-1 )|网站地图

    GMT+8, 2026-10-24 14:57 , Processed in 0.134301 second(s), 49 queries .

    酷德网

    © 2001-2013 Hicodesys. 技术支持 by 酷德网

    快速回复 返回顶部 返回列表