ds1302时序怎么写( 二 )


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
【ds1302时序怎么写】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
4.如何读出DS1302里面的时钟数据一个例子 重点看DS1302_Read() #include #include #define uchar unsigned char #define uint unsigned int #define SECOND 0x81 #define MINUTE 0x83 #define HOUR 0x85 sbit rs=P2^0; sbit rw=P2^1; sbit ep=P2^2; sbit DS1302_SCLK = P1^0; sbit DS1302_IO= P1^1; sbit DS1302_RST = P1^2; sbit M=P3^2; sbit U=P3^3; sbit D=P3^4; unsigned char sel=0; uchar code DIS1[]={“abcdef"}; uchar code DIS2[]={"abcdef"}; /////////////////////////延时//////////////////////////////// void delay(uint ms) { unsigned int a,b; for(a=0;a>1; } } //////////////////////////////////////////////////////////// uchar DS1302_Read() { uchar TempDat=0,i; for(i=0;i<8;i++) { TempDat>>=1; if(DS1302_IO) TempDat=TempDat|0x80; DS1302_SCLK=1; DS1302_SCLK=0; } return TempDat; } //////////////////////////////////////////////////////////// void WDS1302(uchar ucAddr, uchar ucDat) { DS1302_RST = 0; DS1302_SCLK = 0; DS1302_RST = 1; DS1302_Write(ucAddr); DS1302_Write(ucDat); DS1302_SCLK = 1; DS1302_RST = 0; } //////////////////////////////////////////////////////////// uchar RDS1302(uchar ucAddr) { uchar ucDat; DS1302_RST = 0; DS1302_SCLK = 0; DS1302_RST = 1; DS1302_Write(ucAddr); ucDat=DS1302_Read(); DS1302_SCLK = 1; DS1302_RST = 0; return ucDat; } ////////////////////////////////////////////////////////// void init_1302() { WDS1302(0x8e,0x00);//开保护寄存器 WDS1302(0x80,0x55);//秒 WDS1302(0x82,0x59);//分 WDS1302(0x84,0x23);//时 WDS1302(0x8A,0x07);//星期 WDS1302(0x86,0x02);//日 WDS1302(0x88,0x08);//月 WDS1302(0x8C,0x09);//年 WDS1302(0x90,0xab);//卷电流充电 WDS1302(0x8e,0x80);//关保护寄存器 } ////////////////////////////////////////////////////////// /************************1602驱动************************/ ////////////////////////////////////////////////////////// bit lcd_bz() { bit result; rs = 0; rw = 1; ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); result = (bit)(P0 & 0x80); ep = 0; return result; } //////////////////////////////////////////////////////// void lcd_wcmd(unsigned char cmd) { while(lcd_bz()); rs = 0; rw = 0; ep = 0; _nop_(); _nop_(); P0 = cmd; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep= 0; } ///////////////////////////////////////////////////////// void lcd_pos(unsigned char pos) { lcd_wcmd(pos | 0x80); } ///////////////////////////////////////////////////////// void lcd_wdat(unsigned char dat) { while(lcd_bz()); rs = 1; rw = 0; ep = 0; P0 = dat; _nop_(); _nop_(); _nop_(); _nop_(); ep = 1; _nop_(); _nop_(); _nop_(); _nop_(); ep = 0; } ////////////////////////////////////////////////////////// void lcd_init() { lcd_wcmd(0x38); delay(1); lcd_wcmd(0x0c); delay(1); lcd_wcmd(0x06); delay(1); lcd_wcmd(0x01); delay(1); } ///////////////////////////////////////////////////////// /*********************调时函数*************************/ ///////////////////////////////////////////////////////// void set_time() { signed char address,item; signed char max,mini; if(M==0) { sel++; delay(300); if(sel==6) sel=0; if(sel==2) {address=0x82; max=59;mini=0; } if(sel==1) {address=0x84; max=23;mini=0; } if(sel==3) {address=0x8c; max=99;mini=9;} if(sel==4) {address=0x88; max=12;mini=1; } if(sel==5) {address=0x86; max=31;mini=1; } M=1; } item=((RDS1302(address+1))/16)*10 + (RDS1302(address+1))%16; if(U == 0) { delay(200); U=1; item++; } if(D == 0) { delay(200); D=1; item--; } if(item>max) item=mini; if(item