打印
[STC单片机]

按位运算问题

[复制链接]
1134|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fmfen|  楼主 | 2021-4-18 10:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
由于之前用的单片机买不到货了,第一次使用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还不能定义为局部变量(在函数当中定义)
有没有高手帮忙分析一下是什么问题?没弄清楚以后使用感觉心里没底

使用特权

评论回复

相关帖子

沙发
LcwSwust| | 2021-4-18 15:29 | 只看该作者
奇怪,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;
}

使用特权

评论回复
板凳
coody| | 2021-4-18 23:27 | 只看该作者
楼主,C51运算没问题的,是不是你的变量长度的问题? C51 使用unsigned char, unsigned int, unsigned long来定义无符号的8位、16位、32位整数,你看下是否定义对了。

使用特权

评论回复
地板
ayb_ice| | 2021-4-19 08:29 | 只看该作者
应该是其它地方的问题吧,位移的写法是可以的

使用特权

评论回复
5
fmfen|  楼主 | 2021-4-19 09:59 | 只看该作者
本帖最后由 fmfen 于 2021-4-19 10:01 编辑

感谢大家的回复,这个程序是从之前单片机移植过来的,那个是台湾产的,也是51内核,我就是很好奇为啥挪过来就无法使用,而且位移操作改为加法就可以了,现在暂时这样出货了,我会再仔细查找下原因的,特别感谢给出代码提供建议的大神,谢谢大家!

使用特权

评论回复
6
fmfen|  楼主 | 2021-4-19 10:04 | 只看该作者
coody 发表于 2021-4-18 23:27
楼主,C51运算没问题的,是不是你的变量长度的问题? C51 使用unsigned char, unsigned int, unsigned long ...

这个我也试过,刚开始是用unsigned int定义的,后面改为unsigned short也是一样的

使用特权

评论回复
7
fmfen|  楼主 | 2021-4-19 10:09 | 只看该作者
本帖最后由 fmfen 于 2021-4-19 10:10 编辑
ayb_ice 发表于 2021-4-19 08:29
应该是其它地方的问题吧,位移的写法是可以的

是,我现在也怀疑是其它地方的问题,因为我把key2byte这个变量定义为局部变量函数传递出来的数据都不对了。

使用特权

评论回复
8
ayb_ice| | 2021-4-19 11:54 | 只看该作者
fmfen 发表于 2021-4-19 10:09
是,我现在也怀疑是其它地方的问题,因为我把key2byte这个变量定义为局部变量函数传递出来的数据都不对了 ...

可以看反汇编代码,确定生成的代码,判断问题
局部变量可能被其它函数破坏了(KEIL是静态分配局部变量),把编译警告打开,确保没有警告

使用特权

评论回复
9
fmfen|  楼主 | 2021-4-20 16:20 | 只看该作者
问题原因找到了,函数当中定义太多局部变量了。
unsigned char temp,addr;
unsigned char bitnum;
unsigned short key2byte;

把后面两个定义为全局变量就可以了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

5

帖子

0

粉丝