怎么理解ds1302的读数据和写数据( 三 )

>4; lcdshow_u(6,0x30+x); y=y&0x0f; lcdshow_u(7,0x30+y); lcdshow_u(8,':'); x=RDS1302(MINUTE); y=x; x=x>>4; lcdshow_u(9,0x30+x); y=y&0x0f; lcdshow_u(0x0a,0x30+y); lcdshow_u(0x0b,':'); x=RDS1302(SECOND); y=x; x=x>>4; lcdshow_u(0x0c,0x30+x); y=y&0x0f; lcdshow_u(0x0d,0x30+y); x=RDS1302(0x8d); y=x; x=x>>4; lcdshow_d(8,0x30+x); y=y&0x0f; lcdshow_d(9,0x30+y); lcdshow_d(0x0a,'-'); x=RDS1302(0x89); y=x; x=x>>4; lcdshow_d(0x0b,0x30+x); y=y&0x0f; lcdshow_d(0x0c,0x30+y); lcdshow_d(0x0d,'-'); x=RDS1302(0x87); y=x; x=x>>4; lcdshow_d(0x0e, 。
4.怎么读时钟芯片DS1302的时间说明p1.2是用了非门按制RST脚 , 所以SETBP1.2;令=0
DS_READSETBP1.2;令=0 。
CLRP1.1;令SCLK=0 。
CLRP1.2;令=1 , 启动芯片 。
LCALLDS_WSUB;写8位地址 。
LCALLDS_RSUB;读出8位数据 。
RET
DS_WSUBMOVR7,#08H
WL00PRRCA;A为地址字节 。
MOVP1.0,C
SETBP1.1;在时钟上升沿
NOP;输入地址字节 。
CLRP1.1
DJNZR7WL00P
RET
DS_RSUBSETBP1.0;为读数据作准备 。
MOVR7#08H
RL00P:SETBP1.1
NOP
CLRP1.1;在第9个正脉冲的下
MOVC,P1.0;降沿开始输出数据 。
RRCA;A中为读出的数据 。
DJNZR7,RL00P
RET
若使用如下程序对DSl302的RAM1其内容为5AH 进行读操作
READ:MOVA#11000101B;RAM1单元的读地址 。
LCAllDS_READ;调用读子程序 。
则程序执行后A中的数据为2DH , 显然读出的数据不正确 。若再使用一条RLA指令调整后 , 则A中为5AH , 结果才正确 。由此说明:使用上述程序读出的RAM1单元中的第0位数据实为第1位数据 , 读出的第7位数据实为第0位数据 。
经笔者仔细研究时序图和多次试验得知 , 问题的原因在于:对于读操作时序 , 在SCLK出现第8个正脉冲时 , 上升沿输入地址字节的最后一位数据 , 而在此正脉冲的下降沿就要输出数据字节的第0位数据 。然而笔者的程序中是在第9个正脉冲的下降沿才误认为输出了数据字节的第0位数据 , 此位数据事实上是第二个下降沿输出的 , 故实为数据字节的第1位数据 。经笔者实验:只要RST保持为高电平 , 如果超过8个下降沿 , 它们将重新从第0位输出数据位 , 因程序中输出的最后一位数据位 , 是9个下降沿输出的数据位 , 故实为数据字节的第0位数据位 。
由此可见 , 单字节读操作的时序图如改为图2所示时序图 , 则读者较容易理解可避免发生上述编程错误 。
只要将上述的DS_RSUB子程序改为如下的子程序即可解决上述问题:
DS_RSUBl:SETBP1.0;为读数据作准备
MOVR7,#08H
RL00P:CLRP1.1;SCLK第8个正脉冲的
MOVC,P1.0;下降沿开始输出数据 。
RAC
SETBP1.1
DJNZR7,RL00P
RET
5.从DS1302中读出的数据用7段数码管显示程序如何编写楼上 , 人家是ds1302的 , 呵呵 , 给你个参考:#includesbitclock_clk=P2^7;sbitclock_dat=P2^6;sbitclock_rst=P2^5;sbitwei1=P2^0;sbitwei2=P2^1;sbitwei3=P2^2;sbitwei4=P2^3;sbitwei5=P2^4;sbitwei6=P3^3;sbita0=ACC^0;//为了编程方便定义的位变量sbita1=ACC^1;sbita2=ACC^2;sbita3=ACC^3;sbita4=ACC^4;sbita5=ACC^5;sbita6=ACC^6;sbita7=ACC^7;unsignedcharTab_Num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9数字voiddelay(intnum)//延时函数{while(num--);}voidclock_write(unsignedchardd)//写入一个字节 , DS1302时序{ACC=dd;clock_clk=0;clock_dat=a0;clock_clk=1;clock_clk=0;clock_dat=a1;clock_clk=1;clock_clk=0;clock_dat=a2;clock_clk=1;clock_clk=0;clock_dat=a3;clock_clk=1;clock_clk=0;clock_dat=a4;clock_clk=1;clock_clk=0;clock_dat=a5;clock_clk=1;clock_clk=0;clock_dat=a6;clock_clk=1;clock_clk=0;clock_dat=a7;clock_clk=1;}unsignedcharclock_read(void)//读出一个字节 , 时序{clock_clk=1;clock_clk=0;a0=clock_dat;clock_clk=1;clock_clk=0;a1=clock_dat;clock_clk=1;clock_clk=0;a2=clock_dat;clock_clk=1;clock_clk=0;a3=clock_dat;clock_clk=1;clock_clk=0;a4=clock_dat;clock_clk=1;clock_clk=0;a5=clock_dat;clock_clk=1;clock_clk=0;a6=clock_dat;clock_clk=1;clock_clk=0;a7=clock_dat;return(ACC);}unsignedcharread_clock(unsignedcharreg1)//从reg1寄存器读数据{unsignedchardd=0;clock_clk=0;clock_rst=0;clock_rst=1;clock_write(reg1);dd=clock_read();clock_rst=0;return(dd);}voidwrite_clock(unsignedcharreg2,unsignedchardate)//向reg2写入date数据{clock_clk=0;clock_rst=0;clock_rst=1;clock_write(reg2);clock_write(date);clock_rst=0;}voidshow(void)//显示和闪烁函数{unsignedchard,e;unsignedinti;for(i=0;i