合信论坛

快捷导航
查看: 8974|回复: 0

使用CF块写的高低位计算例程

[复制链接]

29

主题

32

帖子

1080

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1080
QQ
发表于 2021-9-9 09:39:27 | 显示全部楼层 |阅读模式
用于计算某段数据中的高低位数量、最前一位最后一位的位置,应用于光幕、测量光栅,物件通过光幕时会遮住发射端的光点,接收端该光电io信号被取反。该例程用于收取光幕io信号集,反馈起始点、长度、结束点,用于物料尺寸检测、物料纠偏。
示例: 示例.jpg
出于便于理解以及对于刚好64/32位数据的使用所以有两个CF块。其中CF_0位64/32bit版,CF_1为任意长度版
符号表对比:
64/32bit:
符号表.png
任意长度版:
符号表-无限制.png
程序整体:
64/32bit:
程序整体.png
任意长度版:
程序整体-无限制.png
几种计算结果:
计算结果1&64.png 计算结果只有高位.png 计算结果只有低位.png


↓↓↓↓↓↓↓↓原代码↓↓↓↓↓↓↓↓
64/32位:
/*判断某64位数内有多少个1,最低位是第几位、最高位是第几位;
**先对low、high、sum寄存器进行初始化(赋0);
**判断开始位为1则进行运算;
**使用右移和与来完成循环比较,对64位数中每一位依次判断是否为1;
**首次位为1则将 i 值存储到low寄存器中;每次位为1都更新high寄存器和sum寄存器;
**计算完成之后分别输出总和、低位、高位。                */

/*计算工作原理:
**将V区的值获取进来,然后进入循环
**在循环中从第一位到最后一位依次进行判断
**判断逻辑:从头到尾按位与1,与完还是1则说明此位为1,对寄存器依次更新
**当第一次碰到或当 i 值小于low值时1时将 i 赋值到low(低位)寄存器                //判断i < low 防止首次赋值了高32位数据后低32位中有更小值
**每次碰到1都对high(高位)、sum(总数)寄存器进行更新        */

#include "math.h"
#include "stdio.h"
#include "plc300.h"
S32 D_low, D_high;                //用于移位的计算寄存器
S16 sum, low, high;                //存储运算结果                sum:总和                low:低位                high:高位
U8 i;                //循环变量

void CF_0( S32 data_low, S32 data_high, BOOL start, S16 *onnum, S16 *rank_low, S16 *rank_high)
{
        low = high = sum = 0;                //初始化寄存器

        if(start)                //判断是否执行程序,start == 1 则执行27—50行的程序
        {
                D_low = data_low ,D_high = data_high;                        //将低、高位数据存储到计算寄存器
                for(i = 1; i <= 32; i++)                //使用for循环对1—32位数据逐个进行判断
                {
                        if((D_low&1) == 1)                //如果数据首位&1后等于1,则判断低位寄存器是否0或是否大于i,并更新寄存器
                        {
                                if(low == 0 || low > i) low = i;
                                if(i>high) high = i;
                                sum++;
                        }
                        if((D_high&1) == 1)//如果数据首位&1后等于1,则判断低位是否0,并更新寄存器
                        {
                                if(low == 0) low = i+32;
                                high = i+32;
                                sum++;
                        }
                        D_low >>=1;                //判断完成后将数据右移1位来更新首位
                        D_high >>=1;
                }
                //输出计算结果↓
                setS16(onnum,sum);
                setS16(rank_low,low);
                setS16(rank_high,high);
        }
}

不做长度限制版:
/*判断某64位数内有多少个1,最低位是第几位、最高位是第几位;
**先对low、high、sum寄存器进行初始化(赋0);
**判断开始位为1则进行运算;
**使用右移和与来完成循环比较,对数据中每一位依次判断是否为1;
**首次位为1则将 i 值存储到low寄存器中;每次位为1都更新high寄存器和sum寄存器;
**计算完成之后分别输出总和、低位、高位。                */

/*计算工作原理:
**将V区的值逐个字节获取进来,然后进入循环
**在循环中从第一位到最后一位依次进行判断
**判断逻辑:从头到尾按位与1,与完等于1则说明此位为1,对寄存器依次更新
**当第一次碰到1时将 i 赋值到low(低位)寄存器
**每次碰到1都对high(高位)、sum(总数)寄存器进行更新        */

#include "math.h"
#include "stdio.h"
#include "plc300.h"
U16 sum, low, high;                //存储运算结果                sum:总和                low:低位                high:高位
U8 i, D, L;                //循环变量

void CF_1( void* data, U8 len, BOOL start, S16 *onnum, S16 *rank_low, S16 *rank_high)
{
        low = high = sum = 0;                //初始化寄存器

        if(start)                //判断是否执行程序,start == 1 则执行27—50行的程序
        {
                for(L =len; L >0; L--)                //从最低个字节像高字节循环,依次获取V区进行计算
                {
                        D =getS8(data+L-1);                        //将低、高位数据存储到计算寄存器
                        for(i = 1; i <= 8; i++)                //使用for循环对字节内数据逐个进行判断
                        {
                                if((D&1) == 1)                //如果数据首位&1后等于1,则判断低位寄存器是否0或是否大于i,并更新寄存器
                                {
                                        if(low == 0) low = i+(len-L)*8;
                                        high = i+(len-L)*8;
                                        sum++;
                                }
                                D >>=1;
                        }
                }
        }

                //输出计算结果↓
                setS16(onnum,sum);
                setS16(rank_low,low);
                setS16(rank_high,high);
}




C函数求高位.rar

13.17 KB, 下载次数: 902

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

客服热线
400-700-4858 周一至周五:09:00 - 18:00
深圳市南山区打石一路深圳国际创新谷6栋A座9层

深圳市合信自动化技术有限公司(简称“合信技术”)成立于2003年,高新技术企业,专注于工业自动化产品的研发、生产、销售和技术服务,依靠高质量、高性能的自动化控制产品与方案为客户创造最大价值,立志于成为全球领先的工业自动化解决方案供应商。

Archiver|手机版|小黑屋|COTRUST Inc. ( 粤ICP备13051915号 )

GMT+8, 2024-4-26 05:35 , Processed in 0.068676 second(s), 24 queries .

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