求助:关于51单片机C编程中的for循环

[复制链接]
3525|8
手机看帖
扫描二维码
随时随地手机跟帖
xuesong10210|  楼主 | 2010-10-7 23:04 | 显示全部楼层 |阅读模式
本帖最后由 xuesong10210 于 2010-10-12 09:49 编辑

来位大虾给俺解答一下哈。。。问题如下:
我自己编了一个用89C52控制DS1302时钟芯片的C程序。其中在读写时钟芯片时用的for循环。如:void DS1302_InputByte(uchar Data)

{

uchar i;


ACC = Data;


for(i=0; i<8; i++)


{


DS1302_CLK = 0;


DS1302_IO = ACC0;
//
由低位到高位               


DS1302_CLK = 1;
//
上升沿写入数据


ACC >>= 1;


}

}
uchar DS1302_OutputByte(void)
{

uchar i;


for(i=0; i<8; i++)


{


DS1302_CLK = 0;
//
下降沿读出DS1302的数据


ACC >>= 1;
//
读出由低到高位,只能移7次有效位!!!


ACC7 = DS1302_IO;
//
第一个数据



DS1302_CLK = 1;



}


return (ACC);

}
程序在编译时没有错误,但是用实验板仿真时时钟不走时。当2个把for语句修改成
for(i=8; i>0; i--)时一切正常。麻烦大虾解释下这两个for有什么不一样的。他们不是都实现了8次循环吗?????
总程序如下:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define second 0x80
#define minute 0x82
#define hours 0x84
sbit rs=P3^5;
sbit sclk=P3^6;
sbit sda=P3^4;
sbit ACC7=ACC^7;
sbit ACC0=ACC^0;
uchar time[8];
uchar Sec,Min,Hour;
ds1302_inputbyte(uchar dat)
//
写数

{

uchar i;


ACC = dat;


for(i=8; i>0; i--)


{


sclk = 0;


sda = ACC0;
//
由低位到高位               


sclk = 1;
//
上升沿写入数据


ACC >>= 1;


}


}
ds1302_outputbyte()
{uchar i;

for(i=8; i>0; i--)


{


sclk = 0;
//
下降沿读出DS1302的数据


ACC >>= 1;
//
读出由低到高位,只能移7次有效位!!!


ACC7 = sda;
//
第一个数据



sclk = 1;



}


return (ACC);

}
write_ds1302(uchar address,uchar Data)
{

rs=0;


_nop_();


sclk=0;


rs=1;


ds1302_inputbyte(address);


ds1302_inputbyte(Data);


sclk=1;


rs=0;

}
read_ds1302(uchar address)
{
uchar Data;


rs=0;


sclk=0;


rs=1;


ds1302_inputbyte(address|0x01);


Data=ds1302_outputbyte();


sclk=1;


rs=0;


return(Data);

}

void DS1302_GetTime()

{

uchar ReadValue;


ReadValue = read_ds1302(0x80);


Sec= ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);


ReadValue =read_ds1302(0x82);


Min = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);


ReadValue = read_ds1302(0x84);


Hour
= ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);


}

timetostring()

{

time[0]=Hour/10+'0';


time[1]=Hour%10+'0';


time[2]=':';


time[3]=Min/10+'0';


time[4]=Min%10+'0';


time[5]=':';


time[6]=Sec/10+'0';


time[7]=Sec%10+'0';


time[8]='\0';

}

///////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

sbit LCD_RS = P2^6;

sbit LCD_RW = P2^5;
sbit LCD_EP = P2^7;


delay(int ms)
{
//
延时子程序

int i;
while(ms--)
{

for(i = 0; i< 250; i++)


{


_nop_();


_nop_();


_nop_();


_nop_();


}

}
}

bit lcd_bz()
{
//
测试LCD忙碌状态

bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EP = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);
LCD_EP = 0;
return result;
}

lcd_wcmd(uchar cmd)
{
//
写入指令数据到LCD

while(lcd_bz());
LCD_RS = 0;
LCD_RW = 0;
LCD_EP = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP = 0;

}

lcd_pos(uchar pos)
{
//
设定显示位置

lcd_wcmd(pos | 0x80);
}

lcd_wdat(uchar dat1)
{
//
写入字符显示数据到LCD

while(lcd_bz());
LCD_RS = 1;
LCD_RW = 0;
LCD_EP = 0;
P0 = dat1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP = 0;
}

lcd_init()
{
//LCD
初始化设定

lcd_wcmd(0x38);
//16*2
显示,5*7点阵,8位数据

delay(1);
lcd_wcmd(0x0c);
//
显示开,关光标

delay(1);
lcd_wcmd(0x06);
//
移动光标

delay(1);
lcd_wcmd(0x01);
//
清除LCD的显示内容

delay(1);
}

/////////////////////////////////////////////////////////////////////






////////////////////////////////////////////////////////////////////
void main()
{


uint i;


lcd_init();


delay(10);


write_ds1302(0x8e,0x00);


write_ds1302(0x80,0x80);


write_ds1302(0x82,0x00);


write_ds1302(0x84,0x00);


write_ds1302(0x80,0x00);


write_ds1302(0x8e,0x80);


while(1)


{


DS1302_GetTime();


timetostring();


lcd_pos(0);


for(i=0;i<8;i++)


{


lcd_wdat(time);

         

}


}

}

相关帖子

fzu_csc| | 2010-10-8 08:02 | 显示全部楼层
都是8次循环,没有区别。
不过单片机有判零跳转指令,说不定第二种更高效,具体看反汇编指令。

确认一下真是因为更改下for就OK了?那就太奇怪了。

使用特权

评论回复
xuesong10210|  楼主 | 2010-10-8 19:18 | 显示全部楼层
2# fzu_csc  我也觉得一样的。  可是程序在仿真是就是出错。我都试了好几次了。。

使用特权

评论回复
酒精考研| | 2010-10-8 22:13 | 显示全部楼层
我还遇到过for(i=7;i>=0;i--)死机,改成for(i=8;i>0;i--)或for(i=8;i>=1;i--)就OK的。

使用特权

评论回复
john_light| | 2010-10-9 08:46 | 显示全部楼层
for (i = 0; i < 8; i++)和for (i = 8; i > 0; i--)两个循环的次数一样,但循环体内i的变化范围不一样,前者0~7,后者8~1。如果i只拿来计数,两者没有区别。

当i为无符号数时,它的值永远不小于零,因此for (i = 7; i >= 0; i--)铁定是个死循环。

另外,既然用了C语言,就应该避免使用针对特殊内核的寄存器来做变量,如ACC,有百害而无一益。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
酒精考研 + 1
xuesong10210|  楼主 | 2010-10-9 18:35 | 显示全部楼层
你说的我明白,再循环体中没有用到i应该是一样的。但是这里的结果却不同。我也郁闷的很。。。。 5# john_light

使用特权

评论回复
xuesong10210|  楼主 | 2010-10-9 18:37 | 显示全部楼层
有仿真电路板的可以试试哈。。把问题写上了。。。。各位大侠谢谢了。。。。我用的是keil编译器。。。。

使用特权

评论回复
chenxiaocong| | 2010-10-10 22:36 | 显示全部楼层
LZ定义的i出现了很多的定义,有unchar,uint,int等;

使用特权

评论回复
老鱼探戈| | 2010-10-14 12:32 | 显示全部楼层
应该是一样的,是不是你的编译器有问题。

使用特权

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

本版积分规则

8

主题

40

帖子

0

粉丝