本帖最后由 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);
}
}
} |