📄 ds1302.lst
字号:
00FA 0757 CPC R21,R23
00FB F3D8 BCS 0x00F7
(0045) }
00FC 940E02D6 CALL pop_gset2
00FE 9508 RET
_Delayms:
i --> R20
j --> R22
MS --> R16
00FF 940E02CE CALL push_gset2
(0046) void Delayms(uint MS)
(0047) {
(0048) uint i,j;
(0049) for( i=0;i<MS;i++)
0101 2744 CLR R20
0102 2755 CLR R21
0103 C00B RJMP 0x010F
(0050) for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
0104 2766 CLR R22
0105 2777 CLR R23
0106 C002 RJMP 0x0109
0107 5F6F SUBI R22,0xFF
0108 4F7F SBCI R23,0xFF
0109 3765 CPI R22,0x75
010A E0E4 LDI R30,4
010B 077E CPC R23,R30
010C F3D0 BCS 0x0107
010D 5F4F SUBI R20,0xFF
010E 4F5F SBCI R21,0xFF
010F 1740 CP R20,R16
0110 0751 CPC R21,R17
0111 F390 BCS 0x0104
(0051) }
0112 940E02D6 CALL pop_gset2
0114 9508 RET
(0052)
(0053)
(0054)
(0055) /*******************************************
(0056) 函数名称: DS1302_init
(0057) 功 能: 初始化DS1302的数据接口
(0058) 参 数: 无
(0059) 返回值 : 无
(0060) /********************************************/
(0061) void DS1302_portinit(void)
(0062) {
(0063) DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
_DS1302_portinit:
0115 B387 IN R24,P17
0116 6A80 ORI R24,0xA0
0117 BB87 OUT P17,R24
(0064) }
0118 9508 RET
_DS1302_writeB:
i --> R20
byte --> R22
0119 940E02CE CALL push_gset2
011B 2F60 MOV R22,R16
(0065) /*******************************************
(0066) 函数名称: DS1302_writeB
(0067) 功 能: 向DS1302写入一个字节数据(没有RST操作)
(0068) 参 数: byte--要写入的数据
(0069) 返回值 : 无
(0070) /********************************************/
(0071) void DS1302_writeB(uchar byte)
(0072) {
(0073) uchar i;
(0074) for(i=0;i<8;i++) //8位数据计数
011C 2744 CLR R20
011D C00C RJMP 0x012A
(0075) {
(0076) PORTB&=~BIT(RTC_CLK); //拉低时钟端
011E 98C7 CBI P18,7
(0077) if(byte&0x01) //当前位是否是1
011F FF60 SBRS R22,0
0120 C002 RJMP 0x0123
(0078) {
(0079) PORTB|=BIT(RTC_DATA); //当前位是1,拉高数据端
0121 9AC5 SBI P18,5
(0080) }
0122 C001 RJMP 0x0124
(0081) else
(0082) {
(0083) PORTB&=~BIT(RTC_DATA); //当前位是0,拉低数据端
0123 98C5 CBI P18,5
(0084) }
(0085) Delayus(10); //调整时钟和脉冲宽度
0124 E00A LDI R16,0xA
0125 E010 LDI R17,0
0126 DFC0 RCALL _Delayus
(0086) PORTB|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)
0127 9AC7 SBI P18,7
(0087) byte>>=1; //数据右移1位,为送出新数据位做准备
0128 9566 LSR R22
0129 9543 INC R20
012A 3048 CPI R20,0x8
012B F390 BCS 0x011E
(0088) }
(0089) }
012C 940E02D6 CALL pop_gset2
012E 9508 RET
_DS1302_readB:
i --> R20
byte --> R22
012F 940E02CE CALL push_gset2
(0090) /*******************************************
(0091) 函数名称: DS1302_readB
(0092) 功 能: 从DS1302读出一个字节数据(没有RST操作)
(0093) 参 数: 无
(0094) 返回值 : byte--读出的数据
(0095) /********************************************/
(0096) uchar DS1302_readB(void)
(0097) {
(0098) uchar i,byte=0;
0131 2766 CLR R22
(0099) DDRB&=~BIT(RTC_DATA); //将数据端口设置为输入
0132 98BD CBI P17,5
(0100) PORTB&=~BIT(RTC_DATA); //无上拉电阻
0133 98C5 CBI P18,5
(0101) for(i=0;i<8;i++) //8位数据计数
0134 2744 CLR R20
0135 C00F RJMP 0x0145
(0102) {
(0103) byte>>=1; //保存读入的数据位
0136 9566 LSR R22
(0104) PORTB|=BIT(RTC_CLK); //时钟上升沿
0137 9AC7 SBI P18,7
(0105) Delayus(10); //延时,调整时钟脉冲宽度
0138 E00A LDI R16,0xA
0139 E010 LDI R17,0
013A DFAC RCALL _Delayus
(0106) PORTB&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位
013B 98C7 CBI P18,7
(0107) Delayus(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
013C E00A LDI R16,0xA
013D E010 LDI R17,0
013E DFA8 RCALL _Delayus
(0108) if(PINB&BIT(RTC_DATA)) //当前位是否是高电平
013F 9BB5 SBIS P16,5
0140 C002 RJMP 0x0143
(0109) {
(0110) byte|=BIT(PB7); //是高电平就将返回数据的当前位置1
0141 6860 ORI R22,0x80
(0111) }
0142 C001 RJMP 0x0144
(0112) else
(0113) {
(0114) byte&=~BIT(PB7); //是低电平就将返回数据的当前位置0
0143 776F ANDI R22,0x7F
0144 9543 INC R20
0145 3048 CPI R20,0x8
0146 F378 BCS 0x0136
(0115) }
(0116) }
(0117) DDRB|=BIT(RTC_DATA); //最后将数据端口设置为输出
0147 9ABD SBI P17,5
(0118) return byte; //返回读出的数据
0148 2F06 MOV R16,R22
0149 940E02D6 CALL pop_gset2
014B 9508 RET
_DS1302_writeD:
data --> R20
addr --> R22
014C 940E02CE CALL push_gset2
014E 2F42 MOV R20,R18
014F 2F60 MOV R22,R16
(0119) }
(0120) /*******************************************
(0121) 函数名称: DS1302_writeD
(0122) 功 能: 向DS1302的某个地址写入一个字节数据
(0123) 参 数: addr--地址值(寄存器或RAM)
(0124) data--要写入的地址
(0125) 返回值 : 无
(0126) /********************************************/
(0127) void DS1302_writeD(uchar addr,uchar data)
(0128) {
(0129) PORTC&=~BIT(RTC_CS); //拉低片选端
0150 98AF CBI P15,7
(0130) PORTB&=~BIT(RTC_CLK); //拉低时钟端
0151 98C7 CBI P18,7
(0131) Delayus(10);
0152 E00A LDI R16,0xA
0153 E010 LDI R17,0
0154 DF92 RCALL _Delayus
(0132) PORTC|=BIT(RTC_CS); //拉高片选端
0155 9AAF SBI P15,7
(0133) Delayus(10); //调整片选脉冲
0156 E00A LDI R16,0xA
0157 E010 LDI R17,0
0158 DF8E RCALL _Delayus
(0134) DS1302_writeB(addr); //写入操作命令(地址)
0159 2F06 MOV R16,R22
015A DFBE RCALL _DS1302_writeB
(0135) Delayus(10);
015B E00A LDI R16,0xA
015C E010 LDI R17,0
015D DF89 RCALL _Delayus
(0136) PORTB&=~BIT(RTC_CLK); //拉低时钟端
015E 98C7 CBI P18,7
(0137) Delayus(10);
015F E00A LDI R16,0xA
0160 E010 LDI R17,0
0161 DF85 RCALL _Delayus
(0138) DS1302_writeB(data); //写入数据
0162 2F04 MOV R16,R20
0163 DFB5 RCALL _DS1302_writeB
(0139) PORTB&=~BIT(RTC_CLK); //拉低时钟端
0164 98C7 CBI P18,7
(0140) Delayus(10); //调整片选脉冲
0165 E00A LDI R16,0xA
0166 E010 LDI R17,0
0167 DF7F RCALL _Delayus
(0141) PORTC&=~BIT(RTC_CS); //拉低片选端
0168 98AF CBI P15,7
(0142) }
0169 940E02D6 CALL pop_gset2
016B 9508 RET
_DS1302_readD:
data --> R20
addr --> R20
016C 940E02B7 CALL push_gset1
016E 2F40 MOV R20,R16
(0143) /*******************************************
(0144) 函数名称: DS1302_readD
(0145) 功 能: 从DS1302的某个地址读出一个字节数据
(0146) 参 数: addr--地址值(寄存器或RAM)
(0147) 返回值 : data--读出的数据
(0148) /********************************************/
(0149) uchar DS1302_readD(uchar addr)
(0150) {
(0151) uchar data;
(0152) PORTC&=~BIT(RTC_CS); //拉低片选端
016F 98AF CBI P15,7
(0153) PORTB&=~BIT(RTC_CLK); //拉低时钟端
0170 98C7 CBI P18,7
(0154) Delayus(10);
0171 E00A LDI R16,0xA
0172 E010 LDI R17,0
0173 DF73 RCALL _Delayus
(0155) PORTC|=BIT(RTC_CS); //拉高片选端
0174 9AAF SBI P15,7
(0156) Delayus(10); //调整片选脉冲
0175 E00A LDI R16,0xA
0176 E010 LDI R17,0
0177 DF6F RCALL _Delayus
(0157) DS1302_writeB(addr); //写入操作命令(地址)
0178 2F04 MOV R16,R20
0179 DF9F RCALL _DS1302_writeB
(0158) Delayus(10);
017A E00A LDI R16,0xA
017B E010 LDI R17,0
017C DF6A RCALL _Delayus
(0159) data=DS1302_readB(); //读出数据
017D DFB1 RCALL _DS1302_readB
017E 2F40 MOV R20,R16
(0160) Delayus(10);
017F E00A LDI R16,0xA
0180 E010 LDI R17,0
0181 DF65 RCALL _Delayus
(0161) PORTB&=~BIT(RTC_CLK); //拉低时钟端
0182 98C7 CBI P18,7
(0162) PORTC&=~BIT(RTC_CS); //拉低片选端
0183 98AF CBI P15,7
(0163) return data; //返回读出的数据
0184 2F04 MOV R16,R20
0185 940E02BA CALL pop_gset1
0187 9508 RET
_DS1302_setT:
addr --> R20
i --> R22
ptTimeD --> R10
0188 940E02D2 CALL push_gset3
018A 0158 MOVW R10,R16
(0164) }
(0165) /*******************************************
(0166) 函数名称: DS1302_setT
(0167) 功 能: 设置DS1302的时间
(0168) 参 数: ptTimeD--设置时间数组指针
(0169) 返回值 : 无
(0170) /********************************************/
(0171) void DS1302_setT(uchar ptTimeD[])
(0172) {
(0173) uchar i;
(0174) uchar addr = 0x80; //写入地址从秒寄存器开始
018B E840 LDI R20,0x80
(0175) DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
018C 2722 CLR R18
018D E80E LDI R16,0x8E
018E DFBD RCALL _DS1302_writeD
(0176) Delayms(5);
018F E005 LDI R16,5
0190 E010 LDI R17,0
0191 DF6D RCALL _Delayms
(0177) for(i=0;i<7;i++)
0192 2766 CLR R22
0193 C00C RJMP 0x01A0
(0178) {
(0179) DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
0194 2FE6 MOV R30,R22
0195 27FF CLR R31
0196 0DEA ADD R30,R10
0197 1DFB ADC R31,R11
0198 8120 LDD R18,0+Z
0199 2F04 MOV R16,R20
019A DFB1 RCALL _DS1302_writeD
(0180) addr+=2;
019B 5F4E SUBI R20,0xFE
(0181) Delayms(1);
019C E001 LDI R16,1
019D E010 LDI R17,0
019E DF60 RCALL _Delayms
019F 9563 INC R22
01A0 3067 CPI R22,7
01A1 F390 BCS 0x0194
(0182) }
(0183) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
01A2 E820 LDI R18,0x80
01A3 E80E LDI R16,0x8E
01A4 DFA7 RCALL _DS1302_writeD
(0184) }
01A5 940E02D9 CALL pop_gset3
01A7 9508 RET
_DS1302_getT:
i --> R20
time --> R22
01A8 940E02CE CALL push_gset2
01AA 01B8 MOVW R22,R16
(0185) /*******************************************
(0186) 函数名称: DS1302_getT
(0187) 功 能: 读取DS1302的当前时间
(0188) 参 数: time[]--读取的时间数组
(0189) 返回值 : 无
(0190) /********************************************/
(0191) void DS1302_getT(uchar time[])
(0192) {
(0193) uchar i;
(0194) ////////下面的是单次读写//////////////////////////
(0195) /* uchar addr = 0x80; //读取地址从秒寄存器开始
(0196) for(i=0;i<7;i++)
(0197) {
(0198) time[i]=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
(0199) addr+=2;
(0200) }*/
(0201) ////////////////////////////////////////////////////
(0202) /////////下面是多字节读取///////////////
(0203) PORTC&=~BIT(RTC_CS); //拉低片选端
01AB 98AF CBI P15,7
(0204) Delayus(10);
01AC E00A LDI R16,0xA
01AD E010 LDI R17,0
01AE DF38 RCALL _Delayus
(0205) PORTC|=BIT(RTC_CS); //拉高片选端
01AF 9AAF SBI P15,7
(0206) Delayus(10); //调整片选脉冲
01B0 E00A LDI R16,0xA
01B1 E010 LDI R17,0
01B2 DF34 RCALL _Delayus
(0207) DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
01B3 EB0F LDI R16,0xBF
01B4 DF64 RCALL _DS1302_writeB
(0208) for (i=0;i<8;i++) //时间数据的存放格式是:
01B5 2744 CLR R20
01B6 C007 RJMP 0x01BE
(0209) { //秒,分,时,日,月,星期,年,控制
(0210) time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
01B7 DF77 RCALL _DS1302_readB
01B8 2FE4 MOV R30,R20
01B9 27FF CLR R31
01BA 0FE6 ADD R30,R22
01BB 1FF7 ADC R31,R23
01BC 8300 STD R16,0+Z
01BD 9543 INC R20
01BE 3048 CPI R20,0x8
01BF F3B8 BCS 0x01B7
(0211) }
(0212)
(0213) PORTC&=~BIT(RTC_CS); //拉低片选端
01C0 98AF CBI P15,7
(0214) ///////////////////////////////////////////////
(0215) PORTB&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
01C1 98C7 CBI P18,7
(0216) }
01C2 940E02D6 CALL pop_gset2
01C4 9508 RET
_DS1302_check:
exist --> R20
01C5 940E02B7 CALL push_gset1
(0217) /*******************************************
(0218) 函数名称: DS1302_check
(0219) 功 能: 检测DS1302是否正常工作
(0220) 参 数: 无
(0221) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0222) /********************************************/
(0223) uchar DS1302_check(void)
(0224) {
(0225) uchar exist;
(0226) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
01C7 2722 CLR R18
01C8 E80E LDI R16,0x8E
01C9 DF82 RCALL _DS1302_writeD
(0227) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
01CA EA25 LDI R18,0xA5
01CB EC00 LDI R16,0xC0
01CC DF7F RCALL _DS1302_writeD
(0228) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
01CD EC01 LDI R16,0xC1
01CE DF9D RCALL _DS1302_readD
01CF 2F40 MOV R20,R16
(0229) if(exist==0xA5)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -