按位运算问题
由于之前用的单片机买不到货了,第一次使用STC15W408AS,程序移植过去之后发现触摸按键不响应。该触摸芯片是用单片机IO模拟I2C时序读取数据的,折腾了大半天发现是按位运算无法使用,之前的程序是这样的:unsigned short key2byte;
...
key2byte=0;
for(bitnum=0;bitnum<16;bitnum++)
{
SCL1=0;
delay();
SCL1=1;
delay();
if(SDA1==1)
{
key2byte=key2byte|(0x0001<<bitnum);
}
}
奇怪的是key2byte这个变量一直不变化,但是看管脚波形和传输的数据又是对的,百思不得其解。后来把程序改成下面就正常了。
unsigned short key2byte;
...
key2byte=0;
for(bitnum=0;bitnum<16;bitnum++)
{
SCL1=0;
delay();
SCL1=1;
delay();
if(SDA1==1)
{
if(bitnum==0) key2byte=key2byte+0x0001;
else if(bitnum==1) key2byte=key2byte+0x0002;
...
else if(bitnum==15) key2byte=key2byte+0x8000;
else ;
}
}
而且奇怪的是key2byte还不能定义为局部变量(在函数当中定义)
有没有高手帮忙分析一下是什么问题?没弄清楚以后使用感觉心里没底
奇怪,C语言位运算是编译器实现的,应当没问题。
要不楼主再看看SCL、SDA的波形,看SDA是在什么时候变化。
另有个建议,0x0001<<bitnum可能在某些时候会耗时较长,建议改成令一个变量初值为1,每个循环左移一次,
或采用移位寄存器的方式,即只让key2byte移位。
参考代码:
//------------------------------------------------
//IIC读取一字节数据
//------------------------------------------------
U8 IICRByte(void)//reentrant
{
U8 ret,i;
PSDA_H;
for(i=0;i<8;i++)//之前PSCL=0;
{
ret<<=1;
IICDelay(IIC_CT);//NOP();
PSCL_H;
IICDelay(IIC_CT);//NOP();
if(PINSDA)ret|=1;
PSCL_L;
}
return ret;
} 楼主,C51运算没问题的,是不是你的变量长度的问题? C51 使用unsigned char, unsigned int, unsigned long来定义无符号的8位、16位、32位整数,你看下是否定义对了。 应该是其它地方的问题吧,位移的写法是可以的 本帖最后由 fmfen 于 2021-4-19 10:01 编辑
感谢大家的回复,这个程序是从之前单片机移植过来的,那个是台湾产的,也是51内核,我就是很好奇为啥挪过来就无法使用,而且位移操作改为加法就可以了,现在暂时这样出货了,我会再仔细查找下原因的,特别感谢给出代码提供建议的大神,谢谢大家! coody 发表于 2021-4-18 23:27
楼主,C51运算没问题的,是不是你的变量长度的问题? C51 使用unsigned char, unsigned int, unsigned long ...
这个我也试过,刚开始是用unsigned int定义的,后面改为unsigned short也是一样的 本帖最后由 fmfen 于 2021-4-19 10:10 编辑
ayb_ice 发表于 2021-4-19 08:29
应该是其它地方的问题吧,位移的写法是可以的
是,我现在也怀疑是其它地方的问题,因为我把key2byte这个变量定义为局部变量函数传递出来的数据都不对了。 fmfen 发表于 2021-4-19 10:09
是,我现在也怀疑是其它地方的问题,因为我把key2byte这个变量定义为局部变量函数传递出来的数据都不对了 ...
可以看反汇编代码,确定生成的代码,判断问题
局部变量可能被其它函数破坏了(KEIL是静态分配局部变量),把编译警告打开,确保没有警告 问题原因找到了,函数当中定义太多局部变量了。
unsigned char temp,addr;
unsigned char bitnum;
unsigned short key2byte;
把后面两个定义为全局变量就可以了
页:
[1]