思维一号free版指令实现原理

发布: 2008-12-09 13:46 | 作者: qmycy | 来源: StmFans思蜕盟 OPELC 自由电子联盟

思维一号free版指令实现:

介绍指令实现之前,我们来回顾一下,栈(stack)这种数据结构。
这个中结构是表的一种,其核心是后进先出(last in first outIFO)。
改数据结构有如下操作:
1、取数据通过,pop();来实现。
2、放入数据通过,push();来实现。
3、栈顶,栈底指针,stack_top,stack_base;
4、堆栈满,StackIsFull();
5、堆栈空,StackIsEmpty();
6、堆栈初始化,InitStack();
如果您对堆栈这种数据结构不了解,请看《数据结构》 C语言版本,清华大学出版社。数据结构经典教材。

1、LD指令。
比如:
        LD X0;
实际就是将X0送入栈中。
所以,LD指令相当于PUSH()操作。LD X0 即push(X0)即可。
注意:X0只是举例,实际实现可能是数组的某一个部分,会是别的变量。请参看思维的变量实现部分,和stm32的位操作。

2、LDI指令。
例如:
        LDI X0;
实际就是将X0取反,然后送入栈中。
实现方式:push(!X0)即可。

注意:如果用严格意义的堆栈操作。实现方式如下;
先将X0直接送入栈中:push(x0);
然后取反。抽象堆栈机(假想的)运行过程中,将X0取走(push(stack_top);),然后取反(not();),将运算结构送回栈中(push(not());)。
如果大家对堆栈机这种类型CPU有兴趣,请上网搜索 stack computer,这是除冯,诺曼,哈佛结构,即寄存器结构,另外一种以纯堆栈为基础的CPU形式。

3、AND指令。
例如:
        LD X0;
        AND X1;
对抽象堆栈机来说,这是个双目运算,需要栈顶有一个数据。
因此实现起来,首先判断栈中是否有一个数据,如果小于1,就报错。即栈下溢出。(请参考《数据结构》有关书籍)
实现方式:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        push(pop() AND x1);pop取栈顶值,即X0,与X1与运算以后,运算结果返回栈中。               
}

4、ani指令
例如:
        LD X0;
        ANI X1;
这个与and指令类似,只是多了一步取反运算;它也是双目运算。所以也需要判断栈中至少有一个数据。
实现方式:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        push(pop() AND !x1);pop取栈顶值,即X0,与X1的反进行与运算以后,运算结果返回栈中。               
}

5、OR和ORi指令
跟and实现方式类似:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        push(pop() OR x1);pop取栈顶值,即X0,与X1或运算以后,运算结果返回栈中。               
}

ORI:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        push(pop() OR x1);pop取栈顶值,即X0,与X1的反进行或运算以后,运算结果返回栈中。               
}

6、ANB,ORB指令
例如:
        LD X0
        OR X1
        LD x2
        OR X3
        ANDB       
ANDB指令,指令后面不带任何变量,实际也是个双目运算指令,需要栈顶,和栈顶-1,即stack_top,stack_top-1都有数据。
实现:
if(2>stack_top-stack_base)
{
        出错处理;
}
else
{
        push(pop() and pop());第一个POP取栈顶数据,第二个pop取栈顶-1的数据,进行与运算以后,将结果push回栈中。               
}

ORB指令,也是不带参数的,也是双目运算,
实现如下:
if(2>stack_top-stack_base)
{
        出错处理;
}
else
{
        push(pop() OR pop());第一个POP取栈顶数据,第二个pop取栈顶-1的数据,进行与运算以后,将结果push回栈中。               
}

7、inv指令。
这个是单目指令,即取反。
实现如下:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        push(!pop());pop取栈顶值,该值取反后返回栈中。               
}

8、OUT指令。
相当于C语言的赋值语句。
将栈顶的值赋给后面的参数。
例如:
        LD X0
        OUT Y1;
实现如下;
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        Y1=POP();//将栈顶的值赋给Y1,注意实际实现是Y1为oUT后面的参数指针。这部分牵涉到思维PLC数据变量的操作。等阿力公布!!
                       
}

9、SET,RST指令。
这条指令,各种plc有些不同,有些PLC具有锁存功能,即SET置位以后,用OUT指令赋值是无效的。
例如:
        LD x0
        SET Y0
这里只实现简单的方式:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        Y0=pop() or Y0;将栈顶值与y0或运算,赋给Y0;                       
}

RST类似:
if(stack_top==stack_base)
{
        出错处理;
}
else
{
        Y0=!POP() and Y0;将栈顶值取反和Y0与运算,赋给Y0;

10、MC,MCR指令。
公共点指令,成对出现。
其原理,就是从MC开始的回路的值要与MC的值进行比较,如果MC中的运算结果是1,则结果取决于后面的结果。如果位零,后面的回路是不通的。
其实现方式有很多种,为了与思维1号free统一,这里我没有阿力的实现方式,请阿力补充。

11、nop
这个指令???????大家都知道。

12、end
这个指令,通知解释器,后面没有指令了,可以休息了,直到这个扫描周期到了以后,返回第一条PLC指令处执行。这个指令是和解释器打交道的,等阿力回答吧。                       

本人才疏学浅,能力有限,有些地方可能荒谬,误导观众实在对不起。
欢迎,阿力,炳哥,manbkk(这里谢谢他在ouravr发的三菱PLC,松下PLC的原理图,太谢谢你了。)拍砖。
aleyn (2008-12-09 14:09:00)
好,精品!
bkkman (2008-12-09 23:20:29)
顶一把!
zxqq (2008-12-14 22:50:21)
建议把MC,MCR指令确定下
xiaotian426 (2009-1-12 21:41:53)
受益匪浅!!
期待……升级!