|
写mega128片内EEPROM(在CVAVR 1.24.4a版本中),乘法运算和左移有何区别?我刚发现一个现象:
首先,已定义ASCII码转二进制的函数:
byte atb(unsigned char a )
{
unsigned char b;
b=a-0x30;
if(b>=0xa)b=b-7;
return(b);
}
也定义了变量
unsigned long int lParameter;
eeprom unsigned long int eep_lConfig;
接着,要将一个4字节数写入EEPROM,代码如下:
lParameter=((unsigned long int)atb(rx_buffer[5]))<<28+
((unsigned long int)atb(rx_buffer[6]))<<24+
((unsigned long int)atb(rx_buffer[7]))<<20+
((unsigned long int)atb(rx_buffer[8]))<<16+
((unsigned long int)atb(rx_buffer[9]))<<12+
((unsigned long int)atb(rx_buffer[10]))<<8+
((unsigned long int)atb(rx_buffer[11]))<<4;
(unsigned long int)atb(rx_buffer[12]);
结果:(通过串口发送写EEPROM指令,传送8个字节的ASCII码做参数值,通过这段代码合成4个字节)写入EEPROM某值,并由上述变量lParameter赋值给片内EEPROM变量eep_lConfig,再读出,发现返回值错误,全变成了零。
又改代码如下:
lParameter=((unsigned long int)atb(rx_buffer[5]))*268435456+
((unsigned long int)atb(rx_buffer[6]))*16777216+
((unsigned long int)atb(rx_buffer[7]))*1048576+
((unsigned long int)atb(rx_buffer[8]))*65536+
((unsigned long int)atb(rx_buffer[9]))*4096+
((unsigned long int)atb(rx_buffer[10]))*256+
((unsigned long int)atb(rx_buffer[11]))*16+
(unsigned long int)atb(rx_buffer[12]);
写入EEPROM某值,并由上述变量lParameter赋值给片内EEPROM变量eep_lConfig,再读出,返回值正确。
各位网友,为什么啊?难道写片内EEPROM时,乘法和左移操作不一样吗?困惑中......
我又简化代码做了测试,发现汇编确实不一样:
lParameter=((unsigned long int)atb(rx_buffer[11]))<<4;
__GETB1MN _rx_buffer,11
CALL SUBOPT_0x33
MOVW R26,R30
MOVW R24,R22
LDI R30,LOW(4)
CALL __LSLD12
STS _lParameter,R30
STS _lParameter+1,R31
STS _lParameter+2,R22
STS _lParameter+3,R23
lParameter=((unsigned long int)atb(rx_buffer[11]))*16;
__GETB1MN _rx_buffer,11
CALL SUBOPT_0x33
__GETD2N 0x10
CALL __MULD12U
STS _lParameter,R30
STS _lParameter+1,R31
STS _lParameter+2,R22
STS _lParameter+3,R23
请各位老师解惑,不胜感激!!!!
(本想查cvavr的帮助文档,但在我的系统win7下打不开) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|