📄 yj12864.lst
字号:
(0029) /*******************************************
(0030) 函数名称: DS1302_writeB
(0031) 功 能: 向DS1302写入一个字节数据(没有RST操作)
(0032) 参 数: byte--要写入的数据
(0033) 返回值 : 无
(0034) /********************************************/
(0035) void DS1302_writeB(uchar byte)
(0036) {
(0037) uchar i;
(0038) for(i=0;i<8;i++) //8位数据计数
0549 2744 CLR R20
054A C00C RJMP 0x0557
(0039) {
(0040) PORTB&=~BIT(RTC_CLK); //拉低时钟端
054B 98C7 CBI 0x18,7
(0041) if(byte&0x01) //当前位是否是1
054C FF60 SBRS R22,0
054D C002 RJMP 0x0550
(0042) {
(0043) PORTB|=BIT(RTC_DATA); //当前位是1,拉高数据端
054E 9AC5 SBI 0x18,5
(0044) }
054F C001 RJMP 0x0551
(0045) else
(0046) {
(0047) PORTB&=~BIT(RTC_DATA); //当前位是0,拉低数据端
0550 98C5 CBI 0x18,5
(0048) }
(0049) Delayus(10); //调整时钟和脉冲宽度
0551 E00A LDI R16,0xA
0552 E010 LDI R17,0
0553 DDD3 RCALL _Delayus
(0050) PORTB|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)
0554 9AC7 SBI 0x18,7
(0051) byte>>=1; //数据右移1位,为送出新数据位做准备
0555 9566 LSR R22
0556 9543 INC R20
0557 3048 CPI R20,0x8
0558 F390 BCS 0x054B
0559 940E0A6F CALL pop_gset2
055B 9508 RET
_DS1302_readB:
i --> R20
byte --> R22
055C 940E0A7E CALL push_gset2
(0052) }
(0053) }
(0054) /*******************************************
(0055) 函数名称: DS1302_readB
(0056) 功 能: 从DS1302读出一个字节数据(没有RST操作)
(0057) 参 数: 无
(0058) 返回值 : byte--读出的数据
(0059) /********************************************/
(0060) uchar DS1302_readB(void)
(0061) {
(0062) uchar i,byte=0;
055E 2766 CLR R22
(0063) DDRB&=~BIT(RTC_DATA); //将数据端口设置为输入
055F 98BD CBI 0x17,5
(0064) PORTB&=~BIT(RTC_DATA); //无上拉电阻
0560 98C5 CBI 0x18,5
(0065) for(i=0;i<8;i++) //8位数据计数
0561 2744 CLR R20
0562 C00F RJMP 0x0572
(0066) {
(0067) byte>>=1; //保存读入的数据位
0563 9566 LSR R22
(0068) PORTB|=BIT(RTC_CLK); //时钟上升沿
0564 9AC7 SBI 0x18,7
(0069) Delayus(10); //延时,调整时钟脉冲宽度
0565 E00A LDI R16,0xA
0566 E010 LDI R17,0
0567 DDBF RCALL _Delayus
(0070) PORTB&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位
0568 98C7 CBI 0x18,7
(0071) Delayus(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
0569 E00A LDI R16,0xA
056A E010 LDI R17,0
056B DDBB RCALL _Delayus
(0072) if(PINB&BIT(RTC_DATA)) //当前位是否是高电平
056C 9BB5 SBIS 0x16,5
056D C002 RJMP 0x0570
(0073) {
(0074) byte|=BIT(PB7); //是高电平就将返回数据的当前位置1
056E 6860 ORI R22,0x80
(0075) }
056F C001 RJMP 0x0571
(0076) else
(0077) {
(0078) byte&=~BIT(PB7); //是低电平就将返回数据的当前位置0
0570 776F ANDI R22,0x7F
0571 9543 INC R20
0572 3048 CPI R20,0x8
0573 F378 BCS 0x0563
(0079) }
(0080) }
(0081) DDRB|=BIT(RTC_DATA); //最后将数据端口设置为输出
0574 9ABD SBI 0x17,5
(0082) return byte; //返回读出的数据
0575 2F06 MOV R16,R22
0576 940E0A6F CALL pop_gset2
0578 9508 RET
_DS1302_writeD:
data --> R20
addr --> R22
0579 940E0A7E CALL push_gset2
057B 2F42 MOV R20,R18
057C 2F60 MOV R22,R16
(0083) }
(0084) /*******************************************
(0085) 函数名称: DS1302_writeD
(0086) 功 能: 向DS1302的某个地址写入一个字节数据
(0087) 参 数: addr--地址值(寄存器或RAM)
(0088) data--要写入的地址
(0089) 返回值 : 无
(0090) /********************************************/
(0091) void DS1302_writeD(uchar addr,uchar data)
(0092) {
(0093) PORTC&=~BIT(RTC_CS); //拉低片选端
057D 98AF CBI 0x15,7
(0094) PORTB&=~BIT(RTC_CLK); //拉低时钟端
057E 98C7 CBI 0x18,7
(0095) Delayus(10);
057F E00A LDI R16,0xA
0580 E010 LDI R17,0
0581 DDA5 RCALL _Delayus
(0096) PORTC|=BIT(RTC_CS); //拉高片选端
0582 9AAF SBI 0x15,7
(0097) Delayus(10); //调整片选脉冲
0583 E00A LDI R16,0xA
0584 E010 LDI R17,0
0585 DDA1 RCALL _Delayus
(0098) DS1302_writeB(addr); //写入操作命令(地址)
0586 2F06 MOV R16,R22
0587 DFBE RCALL _DS1302_writeB
(0099) Delayus(10);
0588 E00A LDI R16,0xA
0589 E010 LDI R17,0
058A DD9C RCALL _Delayus
(0100) PORTB&=~BIT(RTC_CLK); //拉低时钟端
058B 98C7 CBI 0x18,7
(0101) Delayus(10);
058C E00A LDI R16,0xA
058D E010 LDI R17,0
058E DD98 RCALL _Delayus
(0102) DS1302_writeB(data); //写入数据
058F 2F04 MOV R16,R20
0590 DFB5 RCALL _DS1302_writeB
(0103) PORTB&=~BIT(RTC_CLK); //拉低时钟端
0591 98C7 CBI 0x18,7
(0104) Delayus(10); //调整片选脉冲
0592 E00A LDI R16,0xA
0593 E010 LDI R17,0
0594 DD92 RCALL _Delayus
(0105) PORTC&=~BIT(RTC_CS); //拉低片选端
0595 98AF CBI 0x15,7
0596 940E0A6F CALL pop_gset2
0598 9508 RET
_DS1302_readD:
data --> R20
addr --> R20
0599 940E0A80 CALL push_gset1
059B 2F40 MOV R20,R16
(0106) }
(0107) /*******************************************
(0108) 函数名称: DS1302_readD
(0109) 功 能: 从DS1302的某个地址读出一个字节数据
(0110) 参 数: addr--地址值(寄存器或RAM)
(0111) 返回值 : data--读出的数据
(0112) /********************************************/
(0113) uchar DS1302_readD(uchar addr)
(0114) {
(0115) uchar data;
(0116) PORTC&=~BIT(RTC_CS); //拉低片选端
059C 98AF CBI 0x15,7
(0117) PORTB&=~BIT(RTC_CLK); //拉低时钟端
059D 98C7 CBI 0x18,7
(0118) Delayus(10);
059E E00A LDI R16,0xA
059F E010 LDI R17,0
05A0 DD86 RCALL _Delayus
(0119) PORTC|=BIT(RTC_CS); //拉高片选端
05A1 9AAF SBI 0x15,7
(0120) Delayus(10); //调整片选脉冲
05A2 E00A LDI R16,0xA
05A3 E010 LDI R17,0
05A4 DD82 RCALL _Delayus
(0121) DS1302_writeB(addr); //写入操作命令(地址)
05A5 2F04 MOV R16,R20
05A6 DF9F RCALL _DS1302_writeB
(0122) Delayus(10);
05A7 E00A LDI R16,0xA
05A8 E010 LDI R17,0
05A9 DD7D RCALL _Delayus
(0123) data=DS1302_readB(); //读出数据
05AA DFB1 RCALL _DS1302_readB
05AB 2F40 MOV R20,R16
(0124) Delayus(10);
05AC E00A LDI R16,0xA
05AD E010 LDI R17,0
05AE DD78 RCALL _Delayus
(0125) PORTB&=~BIT(RTC_CLK); //拉低时钟端
05AF 98C7 CBI 0x18,7
(0126) PORTC&=~BIT(RTC_CS); //拉低片选端
05B0 98AF CBI 0x15,7
(0127) return data; //返回读出的数据
05B1 2F04 MOV R16,R20
05B2 940E0A83 CALL pop_gset1
05B4 9508 RET
_DS1302_setT:
addr --> R20
i --> R22
ptTimeD --> R10
05B5 940E0A7C CALL push_gset3
05B7 0158 MOVW R10,R16
(0128) }
(0129) /*******************************************
(0130) 函数名称: DS1302_setT
(0131) 功 能: 设置DS1302的时间
(0132) 参 数: ptTimeD--设置时间数组指针
(0133) 返回值 : 无
(0134) /********************************************/
(0135) void DS1302_setT(uchar ptTimeD[])
(0136) {
(0137) uchar i;
(0138) uchar addr = 0x80; //写入地址从秒寄存器开始
05B8 E840 LDI R20,0x80
(0139) DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
05B9 2722 CLR R18
05BA E80E LDI R16,0x8E
05BB DFBD RCALL _DS1302_writeD
(0140) Delayms(5);
05BC E005 LDI R16,5
05BD E010 LDI R17,0
05BE DD80 RCALL _Delayms
(0141) for(i=0;i<7;i++)
05BF 2766 CLR R22
05C0 C00C RJMP 0x05CD
(0142) {
(0143) DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
05C1 2FE6 MOV R30,R22
05C2 27FF CLR R31
05C3 0DEA ADD R30,R10
05C4 1DFB ADC R31,R11
05C5 8120 LDD R18,Z+0
05C6 2F04 MOV R16,R20
05C7 DFB1 RCALL _DS1302_writeD
(0144) addr+=2;
05C8 5F4E SUBI R20,0xFE
(0145) Delayms(1);
05C9 E001 LDI R16,1
05CA E010 LDI R17,0
05CB DD73 RCALL _Delayms
05CC 9563 INC R22
05CD 3067 CPI R22,7
05CE F390 BCS 0x05C1
(0146) }
(0147) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
05CF E820 LDI R18,0x80
05D0 E80E LDI R16,0x8E
05D1 DFA7 RCALL _DS1302_writeD
05D2 940E0A72 CALL pop_gset3
05D4 9508 RET
_DS1302_getT:
addr --> R20
i --> R22
time --> R10
05D5 940E0A7C CALL push_gset3
05D7 0158 MOVW R10,R16
(0148) }
(0149) /*******************************************
(0150) 函数名称: DS1302_getT
(0151) 功 能: 读取DS1302的当前时间
(0152) 参 数: time[]--读取的时间数组
(0153) 返回值 : 无
(0154) /********************************************/
(0155) void DS1302_getT(uchar time[])
(0156) {
(0157) uchar i;
(0158) uchar addr = 0x80; //读取地址从秒寄存器开始
05D8 E840 LDI R20,0x80
(0159) for(i=0;i<7;i++)
05D9 2766 CLR R22
05DA C00A RJMP 0x05E5
(0160) {
(0161) time[i]=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
05DB 2F04 MOV R16,R20
05DC 6001 ORI R16,1
05DD DFBB RCALL _DS1302_readD
05DE 2FE6 MOV R30,R22
05DF 27FF CLR R31
05E0 0DEA ADD R30,R10
05E1 1DFB ADC R31,R11
05E2 8300 STD Z+0,R16
(0162) addr+=2;
05E3 5F4E SUBI R20,0xFE
05E4 9563 INC R22
05E5 3067 CPI R22,7
05E6 F3A0 BCS 0x05DB
(0163) }
(0164) PORTB&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
05E7 98C7 CBI 0x18,7
05E8 940E0A72 CALL pop_gset3
05EA 9508 RET
_DS1302_check:
exist --> R20
05EB 940E0A80 CALL push_gset1
(0165) }
(0166) /*******************************************
(0167) 函数名称: DS1302_check
(0168) 功 能: 检测DS1302是否正常工作
(0169) 参 数: 无
(0170) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0171) /********************************************/
(0172) uchar DS1302_check(void)
(0173) {
(0174) uchar exist;
(0175) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
05ED 2722 CLR R18
05EE E80E LDI R16,0x8E
05EF DF89 RCALL _DS1302_writeD
(0176) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
05F0 EA25 LDI R18,0xA5
05F1 EC00 LDI R16,0xC0
05F2 DF86 RCALL _DS1302_writeD
(0177) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
05F3 EC01 LDI R16,0xC1
05F4 DFA4 RCALL _DS1302_readD
05F5 2F40 MOV R20,R16
(0178) if(exist==0xA5)
05F6 3A05 CPI R16,0xA5
05F7 F411 BNE 0x05FA
(0179) {
(0180) exist=TRUE; //如果读取值与写入值相等,返回TRUE
05F8 E041 LDI R20,1
(0181) }
05F9 C001 RJMP 0x05FB
(0182) else
(0183) {
(0184) exist=FALSE; //如果读取值与写入值不相等,返回FALSE
05FA 2744 CLR R20
(0185) }
(0186) return exist;
05FB 2F04 MOV R16,R20
05FC 940E0A83 CALL pop_gset1
05FE 9508 RET
(0187) }
(0188) /*******************************************
(0189) 函数名称: DS1302_init
(0190) 功 能: 初始化DS1302
(0191) 参 数: 无
(0192) 返回值 : 无
(0193) /********************************************/
(0194) void DS1302_init(void)
(0195) {
(0196) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -