|
楼主 |
发表于 2013-12-13 16:41:04
|
显示全部楼层
因为之前只理解LD和OUT,所以省去了很多相关代码,现在需要把PLC指令逐步添加,就有必要重新理解Code_scan函数了。
先把散转列表复习一下,
code (*key_list[16])()={
CMDFNC , // 0 (FNC应用指令)
CMDP , // 1 (P 应用指令)
LD , // 2 (LD指令, 2000+ppp, 扩展 Mp除外)
LDI , // 3 (LDI指令, 3000+ppp, 扩展 Mp除外)
AND , // 4 (AND指令, 4000+ppp, 扩展 Mp除外)
ANI , // 5 (ANI指令, 5000+ppp, 扩展 Mp除外)
OR , // 6 (OR指令, 6000+ppp, 扩展 Mp除外)
ORI , // 7 (ORI指令, 7000+ppp, 扩展 Mp除外)
CMDER , // 8 (多字指令,第二字及以后有效)
CMDER , // 9
CMDER , // A (多字指令,第二字及以后有效, 仅对M1536-M3071有效,需加偏移量200)
CMDER , // B (Pn指令, 仅对CJ,CALL有效)
OUTYM , // C (OUT指令, 仅对Y,M有效)
SETYM , // D (SET指令, 仅对Y,M有效)
RSTYM , // E (RST指令, 仅对Y,M有效)
CMDCH }; // F (纯单字指令)
************************************************************
void CODE_scan (void)
{
unsigned char pa, pb;
CODE_p = (unsigned char code *)CODE_START;
do{
orderL = *CODE_p;
CODE_p++;
orderH = *CODE_p;
CODE_p++;
ppp = order & 0xfff;
分别取出偏移地址和命令码(散转表数组下标)
继续,
if ((orderH>>4) <= 0x1)
{
if (ppp == 0x00f) // (END指令, 000F )
{
END();
}
(orderH>>4) <= 0x1,即命令码是0或者1,CMDFNC或CMDP命令,或者是END命令。因为END指令 00 0f,这时再通过验证偏移地址来确认是否是END指令。
继续,
else if (ppp <= 0x00e)
{
pa = (unsigned char)ppp;
if ((pa <= 0x001) || (pa == 0x00e)) ;
else if ((pa == 0x00a) || (pa == 0x00d))
{
CODE_p += 4;
}
else
{
CODE_p++;
CODE_p++;
}
}
原因不知道(还需要确认一下),肯定没有相对应的指令,跳过4个字节或2个字节,应该类似空行。
else if ((ppp >= 0x1c0) && (ppp <= 0x1cf))
{
pa = (unsigned char)(ppp - 0x1c0);
if ((pa <= 0x001) || (pa == 0x008) || (pa == 0x009)) ;
else
{
CODE_p++;
CODE_p++;
}
}
类似上面,继续执行或跳过2个字节
else if ((ppp >= 0x600) && (ppp < 0x800)) // 三字指令
{
CODE_p += 4;
}
判断出是三字指令,则指针+4。为什么?
看来要打断一下,找到原因再继续这里的理解。
http://www.amobbs.com/thread-3303497-1-1.html |
|