关于keil中for循环的问题,有遇到的朋友进贴大家讨论

2020-02-01 16:22发布

for(i=0; i<8; i++)和for(i=8; i>0; i--)在使用中有什么区别呢,都是执行八次,但是实际上在keil编译后下载运行的效果却不同,有时两个都可以,有时这个可以那个不可以,有时那个可以这个却出了问题。而这个问题我目前遇到的大多都出现在1302时钟芯片上,其他到没有什么。
void DS1302WriteByte(uchar Dat)
{
  char i;
  ACC = Dat;
  DS1302_CLK = 0;                                                                        //初始化时钟线为低电平
  for(i=0; i<8; i++)
  {            
    DS1302_DAT = ACC0;                   //送数据到数据线
    DS1302_CLK = 0;

    DS1302_CLK = 1;                                                                //上升沿时钟,送数据到DS1302
    ACC = ACC >> 1;                                                         //ACC右移一位,准备传输下一位数据
  }
}
uchar DS1302ReadByte()
{
  unsigned char i;
  ACC = 0;
       
  for(i = 0;i < 8;i++)
  {
    ACC = ACC >> 1;                                                                 //先右移一位
    DS1302_CLK = 0;                                                                 //拉低,这时DS1302准备好数据在数据线上
    ACC7 = DS1302_DAT;                                                        //读取数据线上的数据
    DS1302_CLK = 1;                                                                 //拉高,结束本次数据传输,准备传输下一位
                          
  }

  return (ACC);                                                                                 //返回        读出的数据
}
这两个函数用for(i=8; i>0; i--)正常,但是用for(i=0; i<8; i++)就不正常了。有遇到这类情况且知道原因的么?
难道是跟keil的优化有关系?
先查看反汇编看看,有大侠知道的告诉下,不甚感激!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
takashiki
1楼-- · 2020-02-02 20:48
dashashi 发表于 2013-1-7 14:24
有时这个可以那个不可以,有时那个可以这个却出了问题
出问题的时候都是一模一样的代码跟编译配置么- - ...

仔细看看我上面说的第二条,然后我给你改一下,你自己编译看有没有问题:
  1. void DS1302WriteByte(uchar Dat)
  2. {
  3.   char i;
  4.   DS1302_CLK = 0;                                                                        //初始化时钟线为低电平
  5.   for(i=0; i<8; i++)
  6.   {            
  7.     DS1302_DAT = (bit)(Dat & 1);                                               //送数据到数据线
  8.     DS1302_CLK = 0;

  9.     DS1302_CLK = 1;                                                                //上升沿时钟,送数据到DS1302
  10.     Dat >>= 1;                                                                        //右移一位,准备传输下一位数据
  11.   }
  12. }

  13. uchar DS1302ReadByte()
  14. {
  15.   unsigned char i;
  16.   uchar Dat = 0;
  17.         
  18.   for(i = 0;i < 8;i++)
  19.   {
  20.     Dat >>= 1;                                                                         //先右移一位
  21.     DS1302_CLK = 0;                                                                 //拉低,这时DS1302准备好数据在数据线上
  22.     if(DS1302_DAT) Dat |= 0x80;                                                 //读取数据线上的数据
  23.     DS1302_CLK = 1;                                                                 //拉高,结束本次数据传输,准备传输下一位                           
  24.   }

  25.   return (Dat);                                                                           //返回读出的数据
  26. }
复制代码如果为了效率的考虑,可以将ACC全部改成B,函数入口时_push_(B),函数返回时_pop_(B),当然这样仍然有风险,但具体到你这个问题,是没有风险的。
wshrww
2楼-- · 2020-02-02 21:00
 精彩回答 2  元偷偷看……
wshrww
3楼-- · 2020-02-03 01:24
不使用ACC没问题了,使用位运算吧,移植性也好,具体情况具体分析吧,要求不严格位运算很好。
dashashi
4楼-- · 2020-02-03 07:11
6L说的很有道理
wshrww
5楼-- · 2020-02-03 13:09
dashashi 发表于 2013-1-7 16:15
6L说的很有道理

6楼正解!

一周热门 更多>