STC89C52读取DS1302的问题,各位高手救命啊!俺都搞了一个礼拜了不成功啊!!!
俺的程序如下,麻烦各位兄弟姐妹们帮我看看我的程序有没有问题啊,我检查N次了实在找不出那里错了,但下载到板子上数码管上一直显示00实在不知道怎么办了,现在搞的我对学习单片机...
俺的程序如下,麻烦各位兄弟姐妹们帮我看看我的程序有没有问题啊,我检查N次了实在找不出那里错了,但下载到板子上数码管上一直显示 00 实在不知道怎么办了,现在搞的我对学习单片机都快兴趣了,先送一半分数,解决了我把俺在知道上的分全部送给您!!!!摆脱你们了。(我的DS1302上接的电容是30pf的应该对读数据没影响吧,各位先帮我看看程序有没有问题,没问题我就去买个DS1302再试试)
#include<reg52.h>
#define wp 0x8e
#define xie_shi 0x84
#define xie_fen 0x82
#define xie_miao 0x80
#define du_shi 0x85
#define du_fen 0x83
#define du_miao 0x81
sbit RST=P3^7;
sbit SCLK=P3^5;
sbit IO=P3^4;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit leda=P1^4; // 秒LED的高位
sbit ledb=P1^5; // 秒LED的低位
void int1302(); // 声明初始化函数
void xieds1302(unsigned char dizhi,shuju); //声明写DS1302函数
unsigned char duds1302(unsigned char dizhi); //声明读DS1302函数
void display(unsigned char num); // 声明显示函数
void delay(unsigned char xms); // 声明延迟函数
unsigned char code table[]= // 数码管显示数组(共阳极)0-9
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90
};
// 主函数体
void main()
{
unsigned char k_1,k_2,k_3,miao_gao,miao_di,kkk; // 定义变量用于存储时,分,秒
int1302(); //初始化DS1302
while(1)
{
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
kkk=duds1302(du_miao);
k_1=kkk; // 把ACC中的值取出来方便下次使用
k_2=kkk; // 把ACC中的值取出来方便下次使用
miao_gao=k_1>>4;
miao_di=k_2&0x0f;
display(miao_gao);
leda=0;
delay(5);
leda=1;
display(miao_di);
ledb=0;
delay(5);
ledb=1;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
}
}
// 初始化函数
void int1302()
{
xieds1302(wp,0x00);
xieds1302(xie_shi,0x23);
xieds1302(xie_fen,0x30);
xieds1302(xie_miao,0X44);
xieds1302(wp,0x80);
}
// 写DS1302函数
void xieds1302(unsigned char dizhi,shuju)
{
unsigned char i,j;
SCLK=0; // 时钟线为0
RST=0; // 片选为0
RST=1; // 片选为1准备发送地址,主要是RST在置1之前时钟线必须为低电平所以SCLK才先为0再RST为1
for(i=0;i<8;i++)
{
ACC=dizhi;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
};
for(j=0;j<8;j++)
{
ACC=shuju;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
RST=0;
}
// 读DS1302函数
unsigned char duds1302(unsigned char dizhi)
{
unsigned char i,j;
SCLK=0;
RST=0;
RST=1;
for(i=0;i<8;i++)
{
ACC=dizhi;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
ACC=0X00;
for(j=0;j<8;j++)
{
ACC=ACC>>1;
IO=1;
SCLK=0;
ACC7=IO;
SCLK=1;
}
RST=0;
return ACC;
}
我这里就写秒读妙其他位先不管程序就没必要发了就是让你们帮我看下我写的写入和读出函数有没有错 展开
#include<reg52.h>
#define wp 0x8e
#define xie_shi 0x84
#define xie_fen 0x82
#define xie_miao 0x80
#define du_shi 0x85
#define du_fen 0x83
#define du_miao 0x81
sbit RST=P3^7;
sbit SCLK=P3^5;
sbit IO=P3^4;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit leda=P1^4; // 秒LED的高位
sbit ledb=P1^5; // 秒LED的低位
void int1302(); // 声明初始化函数
void xieds1302(unsigned char dizhi,shuju); //声明写DS1302函数
unsigned char duds1302(unsigned char dizhi); //声明读DS1302函数
void display(unsigned char num); // 声明显示函数
void delay(unsigned char xms); // 声明延迟函数
unsigned char code table[]= // 数码管显示数组(共阳极)0-9
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90
};
// 主函数体
void main()
{
unsigned char k_1,k_2,k_3,miao_gao,miao_di,kkk; // 定义变量用于存储时,分,秒
int1302(); //初始化DS1302
while(1)
{
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
kkk=duds1302(du_miao);
k_1=kkk; // 把ACC中的值取出来方便下次使用
k_2=kkk; // 把ACC中的值取出来方便下次使用
miao_gao=k_1>>4;
miao_di=k_2&0x0f;
display(miao_gao);
leda=0;
delay(5);
leda=1;
display(miao_di);
ledb=0;
delay(5);
ledb=1;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
}
}
// 初始化函数
void int1302()
{
xieds1302(wp,0x00);
xieds1302(xie_shi,0x23);
xieds1302(xie_fen,0x30);
xieds1302(xie_miao,0X44);
xieds1302(wp,0x80);
}
// 写DS1302函数
void xieds1302(unsigned char dizhi,shuju)
{
unsigned char i,j;
SCLK=0; // 时钟线为0
RST=0; // 片选为0
RST=1; // 片选为1准备发送地址,主要是RST在置1之前时钟线必须为低电平所以SCLK才先为0再RST为1
for(i=0;i<8;i++)
{
ACC=dizhi;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
};
for(j=0;j<8;j++)
{
ACC=shuju;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
RST=0;
}
// 读DS1302函数
unsigned char duds1302(unsigned char dizhi)
{
unsigned char i,j;
SCLK=0;
RST=0;
RST=1;
for(i=0;i<8;i++)
{
ACC=dizhi;
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
ACC=0X00;
for(j=0;j<8;j++)
{
ACC=ACC>>1;
IO=1;
SCLK=0;
ACC7=IO;
SCLK=1;
}
RST=0;
return ACC;
}
我这里就写秒读妙其他位先不管程序就没必要发了就是让你们帮我看下我写的写入和读出函数有没有错 展开
展开全部
以前做过显示用LCD1602的DS1302时钟,我就发一个DS1302的头文件给你吧?你好好研究一下它们之间的函数吧?看懂了DS1302编程基本上难不倒你。你上面给的程序乱七八糟的我不敢恭维,显示部分电路也不知道什么回事。我也懒得看,下面是比较标准的DS1302头文件。
///////////////////////////////////////////////////////////////////////////////////////////////////////
//File : DS1302.H
//Author : NULL
//Created: 2008/6/18
#ifndef __DS1302_A_H__
#define __DS1302_A_H__
//引脚及位的定义
sbit DS1302_CLK = P3^6; //时钟引脚
sbit DS1302_IO = P3^4; //数据引脚
sbit DS1302_RST = P3^5; //复位引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
//宏定义便于理解
#define unchar unsigned char
#define unint unsigned int
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算RAM地址的宏运算
//定义时间类型
typedef struct _SYSTEMTIME_
{
unchar Second;
unchar Minute;
unchar Hour;
unchar Week;
unchar Day;
unchar Month;
unchar Year;
unchar DateString[9];
unchar TimeString[9];
}SYSTEMTIME;
//函数声明
void DS1302_InputByte(unchar Data); //写入一个字节(内部函数)
unchar DS1302_OutputByte(void); //读取一个字节(内部函数)
void Write1302(unchar Address, unchar Data); //在指定地址写入指定的数据
unchar Read1302(unchar Address); //读取DS1302指定地址中的数据
void DS1302_SetProtect(bit Flag); //DS1302是否写入保护
void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数
void DS1302_GetTime(SYSTEMTIME *Time); //读出时间
void DateToStr(SYSTEMTIME *Time); //日期转化成字符
void TimeToStr(SYSTEMTIME *Time); //时间转化成字符
void DS1302_Initial (void); //DS1302初始化
//写入一个字节(内部函数)
void DS1302_InputByte(unchar Data)
{
unchar i;
ACC = Data;
for(i=8; i>0; i--)
{
DS1302_CLK = 0;
DS1302_IO = ACC0; //由低位到高位
DS1302_CLK = 1; //上升沿写入数据
ACC >>= 1;
}
}
//读取一个字节(内部函数)
unchar DS1302_OutputByte(void)
{
unchar i;
for(i=8; i>0; i--)
{
DS1302_CLK = 0; //下降沿读出DS1302的数据
ACC >>= 1; //读出由低到高位,只能移7次有效位!!!
ACC7 = DS1302_IO; //第一个数据
DS1302_CLK = 1;
}
return (ACC);
}
//在指定地址写入指定的数据
void Write1302(unchar Address, unchar Data)
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_InputByte(Address);
DS1302_InputByte(Data);
DS1302_CLK = 1;
DS1302_RST = 0;
}
//读取1302指定地址中的数据
unchar Read1302(unchar Address)
{
unchar Data;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //RST拉高,启动数据传送
DS1302_InputByte(Address|0x01);//读取指定地址数据指令
Data = DS1302_OutputByte();
DS1302_CLK = 1;
DS1302_RST = 0;
return (Data);
}
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
if(Flag)
Write1302(0x8E,0x80); //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
else
Write1302(0x8E,0x00); //WP=0 允许数据写入DS1302
}
//设置时间函数
void DS1302_SetTime(unchar Address, unchar Value)
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
DS1302_SetProtect(1);
}
//读出时间
void DS1302_GetTime(SYSTEMTIME *Time)
{
unchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
//日期转化成字符
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
//时间转化成字符
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->TimeString[8] = '\0';
}
//初始化DS1302
void DS1302_Initial (void)
{
unchar Second=Read1302(DS1302_SECOND);
if(Second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
DS1302_SetTime(DS1302_SECOND,0);
}
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
你把上面保存为DS1302.h,在主程序那里加进去就行了。显示部分的函数你自己编写一下。
///////////////////////////////////////////////////////////////////////////////////////////////////////
//File : DS1302.H
//Author : NULL
//Created: 2008/6/18
#ifndef __DS1302_A_H__
#define __DS1302_A_H__
//引脚及位的定义
sbit DS1302_CLK = P3^6; //时钟引脚
sbit DS1302_IO = P3^4; //数据引脚
sbit DS1302_RST = P3^5; //复位引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
//宏定义便于理解
#define unchar unsigned char
#define unint unsigned int
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算RAM地址的宏运算
//定义时间类型
typedef struct _SYSTEMTIME_
{
unchar Second;
unchar Minute;
unchar Hour;
unchar Week;
unchar Day;
unchar Month;
unchar Year;
unchar DateString[9];
unchar TimeString[9];
}SYSTEMTIME;
//函数声明
void DS1302_InputByte(unchar Data); //写入一个字节(内部函数)
unchar DS1302_OutputByte(void); //读取一个字节(内部函数)
void Write1302(unchar Address, unchar Data); //在指定地址写入指定的数据
unchar Read1302(unchar Address); //读取DS1302指定地址中的数据
void DS1302_SetProtect(bit Flag); //DS1302是否写入保护
void DS1302_SetTime(unchar Address, unchar Value);//设置时间函数
void DS1302_GetTime(SYSTEMTIME *Time); //读出时间
void DateToStr(SYSTEMTIME *Time); //日期转化成字符
void TimeToStr(SYSTEMTIME *Time); //时间转化成字符
void DS1302_Initial (void); //DS1302初始化
//写入一个字节(内部函数)
void DS1302_InputByte(unchar Data)
{
unchar i;
ACC = Data;
for(i=8; i>0; i--)
{
DS1302_CLK = 0;
DS1302_IO = ACC0; //由低位到高位
DS1302_CLK = 1; //上升沿写入数据
ACC >>= 1;
}
}
//读取一个字节(内部函数)
unchar DS1302_OutputByte(void)
{
unchar i;
for(i=8; i>0; i--)
{
DS1302_CLK = 0; //下降沿读出DS1302的数据
ACC >>= 1; //读出由低到高位,只能移7次有效位!!!
ACC7 = DS1302_IO; //第一个数据
DS1302_CLK = 1;
}
return (ACC);
}
//在指定地址写入指定的数据
void Write1302(unchar Address, unchar Data)
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302_InputByte(Address);
DS1302_InputByte(Data);
DS1302_CLK = 1;
DS1302_RST = 0;
}
//读取1302指定地址中的数据
unchar Read1302(unchar Address)
{
unchar Data;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //RST拉高,启动数据传送
DS1302_InputByte(Address|0x01);//读取指定地址数据指令
Data = DS1302_OutputByte();
DS1302_CLK = 1;
DS1302_RST = 0;
return (Data);
}
//是否写入保护
void DS1302_SetProtect(bit Flag)
{
if(Flag)
Write1302(0x8E,0x80); //0x8e控制字节地址,bit7=WP WP=1 禁止数据写入DS1302
else
Write1302(0x8E,0x00); //WP=0 允许数据写入DS1302
}
//设置时间函数
void DS1302_SetTime(unchar Address, unchar Value)
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
DS1302_SetProtect(1);
}
//读出时间
void DS1302_GetTime(SYSTEMTIME *Time)
{
unchar ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0f);
}
//日期转化成字符
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
//时间转化成字符
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->TimeString[8] = '\0';
}
//初始化DS1302
void DS1302_Initial (void)
{
unchar Second=Read1302(DS1302_SECOND);
if(Second&0x80)//bit7=CH CH=0 振荡器允许工作,CH=1振荡器停止工作
DS1302_SetTime(DS1302_SECOND,0);
}
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
你把上面保存为DS1302.h,在主程序那里加进去就行了。显示部分的函数你自己编写一下。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询