以下代码在串口调试助手上显示:
······(省略一部分)
11-12-17 00:35:57
11-12-17 00:35:57
11-12-17 00:35:58
11-12-17 00:35:58
11-12-17 00:35:58
······(省略一部分)
以上是正确的读出数据
但是,假如下面那行红色的代码去掉,就会变成:
······(省略一部分)
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-?? 00:??:02
11-12-17 ??:00:03
11-12-17 ??:00:03
11-12-17 ??:00:03
11-12-17 ??:00:03
11-12-17 ??:00:03
······(省略)
该显示部分居然出现问号
请大神帮帮忙解决下,就一句代码不理解,3Q,代码如下:
# include <reg52.h>
# define WRITE_ADDRESS 0x80
# define READ_ADDRESS 0x81
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit SDA = P3^4;
sbit SCK = P3^5;
sbit RST = P1^7;
uint8 Time[] = {0,0,0,17,12,7,11}; //设置DS1302的初始值,分别为:秒,分,时,日,月,周,年
void delay(uint16 counter)
{
while(--counter);
}
void DS1302_Initial()
{
RST = 0;
SCK = 0;
RST = 1;
}
void DS1302_InputByte(uint8 BYTE) //写一个字节
{
uint8 i;
for(i = 0;i < 8;i++)
{
BYTE >>= 1;
SDA = CY;
SCK = 1;
SCK = 0;
}
}
void Write_DS1302(uint8 ADDRESS,uint8 BYTE)
{
DS1302_Initial();
DS1302_InputByte(ADDRESS);
DS1302_InputByte(BYTE);
RST = 0; //该句前面不用对SDA进行处理,不懂!!
}
uint8 DS1302_OutputByte() //读一个字节
{
uint8 i;
for(i = 0;i < 8;i++)
{
ACC >>= 1;
if(SDA)
ACC |= 0x80;
SCK = 1;
SCK = 0;
}
return ACC;
}
uint8 Read_DS1302(ADDRESS) //读时间子函数
{
DS1302_Initial();
DS1302_InputByte(ADDRESS);
ACC = DS1302_OutputByte();
SDA = 0; //罪魁祸首,就这句如果删了就出现错误了,大大们看看为什么?
RST = 0;
return ACC;
}
void Read_Time() //读时间
{
uint8 i,addr;
addr = READ_ADDRESS;
for(i = 0;i < 7;i++) //读7次,存入Time数组
{
Time = Read_DS1302(addr);
addr += 2;
}
}
void DS1302_If_Protece(bit Flag) //设置写保护或者清写保护
{
if(Flag)
{
Write_DS1302(0x8e,0x80);
}
else
{
Write_DS1302(0x8e,0);
}
}
void DS1302_SetTime() //设置初始时间
{
uint8 i,temp;
for(i = 0;i < 7;i++) //转换成BCD码
{
temp = Time/10;
Time = Time%10;
Time = Time + temp * 16;
}
temp = WRITE_ADDRESS;
DS1302_If_Protece(0);
for(i = 0;i < 7;i++) //写入DS1302
{
Write_DS1302(temp,Time);
temp += 2;
}
DS1302_If_Protece(1);
}
void Serial_Initial() //串口初始化
{
TMOD = 0x20;
SCON = 0x40;
TH1 = 0xfd;
TL1 = TH1;
TR1 = 1;
}
void Serial_OutputByte(uint8 Byte)
{
SBUF = Byte;
while(!TI);
TI = 0;
}
void Serial_OutputTime(uint8 Data)
{
Serial_OutputByte(Data/16+'0'); //读回来的数据转换成字符送调试助手显示
Serial_OutputByte(Data%16+'0');
}
void main()
{
Serial_Initial();
DS1302_SetTime();
while(1)
{
Read_Time();
Serial_OutputTime(Time[6]);
Serial_OutputByte('-');
Serial_OutputTime(Time[4]);
Serial_OutputByte('-');
Serial_OutputTime(Time[3]);
Serial_OutputByte(' ');
Serial_OutputTime(Time[2]);
Serial_OutputByte(':');
Serial_OutputTime(Time[1]);
Serial_OutputByte(':');
Serial_OutputTime(Time[0]);
Serial_OutputByte('\r');
Serial_OutputByte('\n');
delay(10000);
}
}
给个写入读取数据的方法
在SCLK为高电平时,DATA线是不能变化的;在SCLK为低电平时,DATA线是可以变化的;所以,写数据的时候,先关数据,再给SCLK上升沿;读数据时,在SCLK下降沿之前读