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