这段时间一直在做工程控制项目,基于ProConOS平台开发。ProConOS早就在国内被广泛使用,但是网上的资源还是很少。项目已接近尾声,现在对项目试着做一些总结。
1、Modbus协议,网上资料很多了。但还没整理好自己的,占位。
2、位操作
(1)、modbus返回值是字节型,要将其转为short型。
short s=0;
char str[256];
s=str[9];
s<<=8; //s右移8位
s|=str[10];//按位或
一开始用的s+=str[10],结果某此操作时发现数据不对,比原来的值小。检查发现当str[10]最高位为1时s+=str[10]的结果不再是加而是减。于是改成上面的按位或(|)结果正常。
分析:计算机中数据都是按补码存储,即最高位表示符号位,当str[10]最高位为1时,s的结果不再是相加而是相减。
(2)、读DI、DO返回值
在做自己的modbus server接受client的读写时有个起始地址和读取个数。当起始地址是[0,7]中的某一个时意味着要得到的结果是拆分字节得到的,需要进行位操作。假设从第3个点开始读取9个DI点的返回值,
(i)、先要确定读取几个字节,读的是9个点,就是返回2个字节,(9+7)>>3,循环如下:
for(i=0; i<(num+7)>>3; i++)
{......}
(ii)、从第bit点开始读,意味着从某个字节的第三位起取6位,然后从下一个字节从再取两位:
str[i] = value[9+i]<<bit;
str[i] |= value[10+i]>>(8-bit);
假设bit为2
value[9] value[10] value[11]
11001011 01011010 10011100
| | |
001011 01 011010 10
即str[0]的值为0x2b,str[1]的值0x6a
(3)、置一个数的某一位为1,直接让该数或(|)上一个该位为1的数,置一个数某一位为0,与(&)上该为0其它为是1的数
int temp=0x32;
temp|=0x10; //置第四位为1
temp&=0xef; //置第四位为0
位操作很普遍,面试笔试中经常性就会碰到定义一个交换两个值的宏
#define SWAP(a,b)\
{\
(a)^=(b);\
(b)^=(a);\
(a)^=(b);\
}