找回密码
 注册会员
img_loading
智能检测中
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

请教关于实时时钟芯片DS1302的读问题

[复制链接]
admin 发表于 2012-9-2 04:58:12 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
整个程序都没有问题,包括显示,和DS1302的写操作, 但是读操作出现了问题,不管是不是分寄存器额地址地址,我读出的十六进制数全是FF,显示为255,也就是I_O口的初始状态1,读出的全是1,8个1就是FF,我把I_O口的初始状态写成0则读出的全是0
,(我分寄存器里写入了40,应该读出40来)这说明DS1302没有响应读操作,但是我把这个读函数放到别人成功的实例程序里又是好用的不知道问题出在哪了,希望大神给指导一下。


/**************************************************
本函数只是实现写DS1302的分寄存器,并读出分位的值,送1602显示
**************************************************/
#include "at89x51.h"
#include "DS1302.h"
#include "1602LCD.h"
#define uchar unsigned char
void main()
{

uchar year,week,moth,day,hour,minute,sec,i;
uchar b,s,g;
reset();//复位
write_clock_time(0x82,0x40);//写分为40
minute=read_clock_time(0x83); //读分寄存器
b=minute/100;
s=minute%100/10;
g=minute%100%10;
init_lcd();
busy_lcd();
P0=0xC0+2;
cmd_wr();
busy_lcd();
show_lcd(0x30+b);//百位显示

busy_lcd();
P0=0xC0+3;
cmd_wr();
busy_lcd();
show_lcd(0x30+s);//十位显示
busy_lcd();
P0=0xC0+4;
cmd_wr();
busy_lcd();
show_lcd(0x30+g);//个位显示

}
/*****************************************************
DS1302.h
这里读出的分位,为十六进制的数,没有安分位的格式做十进制处理
******************************************************/
#define uchar unsigned char
sbit sclk=P1^3;
sbit I_O=P1^4;
sbit rstb=P1^5;
/*
复位函数
*/
void reset()
{
rstb=0;
sclk=0;
rstb=1;
}
/*
读函数
下降沿读数据
必须先发出时钟下降沿让DS1302发出数据,才能读I_O口,否则会误将I_O口的状态给读进来
*/
uchar read()
{
uchar i,j;
uchar R_byte;//最终读出的数据
uchar tembyte;//中间转换的数据
R_byte=0;//初始化
I_O=1;//初始化
for(i=0;i<8;i++)
{
sclk=1;
sclk=0;//先给下降沿
tembyte=(uchar)I_O;
if(tembyte==1)
R_byte|=(1<<i);
else
R_byte|=(0<<i);
}
return R_byte;
}
/*
写函数
上升沿写数据
必须先发出数据再给上升沿,如果先给上升沿,很可能会误将I_O的状态写出去
*/
void write(uchar W_byte)
{
uchar i;
for(i=0;i<8;i++)
{
I_O=0; //先发出数据0
if(W_byte & 0x01) //判断要发送的一字节数据第一位是不是1,若是1,I_O=1,发送1,不是则发送上面的0
I_O=1; //发送1
sclk=0;
sclk=1;
W_byte>>=1; //移位判断下一位是否为1
}

}
/*读时钟函数*/
uchar read_clock_time(uchar addr)
{
uchar j,i,s,g,time;//中间量i,分的十位s,个位g,分minute
write(addr);//时钟_分地址_写命令
i=read();//读出分的数据
time=i;
return time;
}
/*写时钟函数*/
void write_clock_time(uchar addr,uchar dat)
{
write(addr);//时钟_分地址_写命令
write(dat);//时钟_分地址_写命令
reset();
}


/********************************************************
1602显示函数
1602LCD.h
*********************************************************/
#define uchar unsigned char
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
/*判忙*/
uchar busy_lcd()
{
uchar a;
start:
RS=0;
RW=1;
E=0;
for(a=0;a<2;a++);
E=1;
P0=0xff;
if(P0_7==0)
return 0;
else
goto start;
}
/*写控制字*/
void cmd_wr()
{
RS=0;//写命令
RW=0;//写操作
E=0;
E=1;
}
void show_lcd(uchar i)
{
P0=i;
RS=1;//写数据
RW=0;
E=0;
E=1;
}

/*初始化*/
void init_lcd()
{
P0=0x38;//显示模式设置
cmd_wr();
busy_lcd();
P0=0x01;//清屏
cmd_wr();
busy_lcd();
P0=0x0f;
cmd_wr();
busy_lcd();

P0=0x06;//光标移动设置
cmd_wr();
busy_lcd();

P0=0x0c;//显示开及光标设置
cmd_wr();
busy_lcd();
}
您需要登录后才可以回帖 登录 | 注册会员

*滑块验证:
img_loading
智能检测中
本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2025-7-25 00:07 , Processed in 0.051608 second(s), 10 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表