微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于51单片机一个一个字节读数据的写法

关于51单片机一个一个字节读数据的写法

时间:10-02 整理:3721RD 点击:
你好,请问aa>>=1,放在if(dsio==1) aa|=0x80;的前面和后面有什么不同?
unsigned char i;
for(i=0;i<8;i++)
{
     //aa>>=1;放在这边和放在后面有什么不同?
    if(dsio==1)
     aa|=0x80;
     aa>>=1;放在这边和放在前面有什么不同?
     dsclk=1;
     _nop_;
     dsclk=0;
     _nop_;
    return aa;
}
这个是DS1302的读字节函数?放在前后读出数据不一样?

  1. unsigned char i;
  2. for(i=0;i<8;i++)
  3. {
  4.      uchar bit=0;
  5.      bit=dsio;
  6.      aa|=(bit>>i);     
  7.      dsclk=1;
  8.      _nop_;
  9.      dsclk=0;
  10.      _nop_;
  11.     return aa;
  12. }

复制代码


你把程序改为这样试试,这样只移动7次。而你的程序不管是放在前面还是后面,都移动了8次。

aa>>=1; 等于 aa = aa >>1;
aa|=0x80 等于 aa = aa | 0x80;
这就是逻辑的问题了:
aa>>=1 在前边,会把 aa 整体右移一位,MSB 位(最高位)会变成 0,这是 如果 执行 aa|=0x80,又会把 MSB 位 置 1。
aa>>=1 在后边,如果 aa 的 MSB 位 为 0,执行 aa|=0x80 后 ,MSB 位 置 1;如果 aa 的 MSB 位 为 1,执行 aa|=0x80 后 ,对 aa 没影响,MSB 位 为 1 不变;再 执行 aa>>=1,把 aa 整体右移一位,MSB 位(最高位)变成 0。
总之,前后的最大差别是,执行完后,aa>>=1 在前边,MSB 位 可能为 1;aa>>=1 在后边,MSB 位 不 可能 为 1,必是 0 。

要放在后边,不能放在if前边程序精简之后变成这样:

  1. for(i=0;i<8;i++)
  2. {
  3.      aa>>=1;
  4.     if(dsio==1)
  5.     {
  6.         aa|=0x80;
  7.     }   
  8. }
  9. for(i=0;i<8;i++)
  10. {
  11.    
  12.     if(dsio==1)
  13.     {
  14.         aa|=0x80;
  15.     }
  16.      aa>>=1;
  17. }

复制代码


放在前边,第一次读取数据是正确的,第二次以后数据就是错的,解决方法是:将aa处理之后进行释放,给他赋值为0;推荐放在后边。

左移右移有时容易搞混!

"for(i=0;i<8;i++)
{
      //aa>>=1;
    if(dsio==1)
      aa|=0x80;
      aa>>=1;"       
"假设要读取的数据为IO=0101 1001
aa为任意八位数据,假定aa=1000 1110"       
原始数据        aa=1000 1110
i=0        0100 0111
i=1        0010 0011
i=2        0001 0001
i=3        0100 1000
i=4        0110 0100
i=5        0011 0010
i=6        0101 1001
i=7        0010 1100
用第二个是错的,会多出来一个移位,但是只有这样写才能读出数据,写在前面读不出数据?

"for(i=0;i<8;i++)
{
      //aa>>=1;
    if(dsio==1)
      aa|=0x80;
      aa>>=1;"       
"假设要读取的数据为IO=0101 1001
aa为任意八位数据,假定aa=1000 1110"       
原始数据        aa=1000 1110
i=0        0100 0111
i=1        0010 0011
i=2        0001 0001
i=3        0100 1000
i=4        0110 0100
i=5        0011 0010
i=6        0101 1001
i=7        0010 1100
用第二个是错的,会多出来一个移位,但是只有这样写才能读出数据,写在前面读不出数据?

写在后面是对的,写在前面是错的,但是我分析应该写在前面!此程序为DS1302读程序!

这个不懂  跟着高手学习一下

你好,如果这样的话,当i=0时,我假设bit=0000 0000(即第一个为低电平),而aa是未知的,如果aa=1001 1001那岂不是把bit这第一个字节给丢失了,这样每次读之前是不是应该给aa赋值即aa=0000 0000。
还有个问题:bit是第一个(假设高电平)传输时是等于0000 0001还是1000 0000,为什么第二个就变成0000 0010或者0100 0000.
DS1302这个我知道具体原因,但是没想明白,原因是传完地址以后,一个周期的传完地址以后下降沿立刻传输读数据,所以会出现那种现象,但是没想明白!

  1. void read()
  2. {
  3. unsigned char i,aa=0;
  4. for(i=0;i<8;i++)
  5. {
  6.      uchar bit=0;
  7.      bit=dsio;
  8.      aa|=(bit>>i);     
  9.      dsclk=1;
  10.      _nop_;
  11.      dsclk=0;
  12.      _nop_;

  13. }
  14.    return aa;
  15. }

复制代码

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top