|
用于计算某段数据中的高低位数量、最前一位最后一位的位置,应用于光幕、测量光栅,物件通过光幕时会遮住发射端的光点,接收端该光电io信号被取反。该例程用于收取光幕io信号集,反馈起始点、长度、结束点,用于物料尺寸检测、物料纠偏。
示例:
出于便于理解以及对于刚好64/32位数据的使用所以有两个CF块。其中CF_0位64/32bit版,CF_1为任意长度版
符号表对比:
64/32bit:
任意长度版:
程序整体:
64/32bit:
任意长度版:
几种计算结果:
↓↓↓↓↓↓↓↓原代码↓↓↓↓↓↓↓↓
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);
}
|
|