📄 ds1302.lst
字号:
00FB 2F86 MOV R24,R22
00FC 9582 SWAP R24
00FD 708F ANDI R24,0xF
00FE E09A LDI R25,0xA
00FF 9F98 MUL R25,R24
0100 2D60 MOV R22,R0
0101 0F60 ADD R22,R16
(0120)
(0121) return byte; //返回读出的数据
0102 2F06 MOV R16,R22
0103 940E0284 CALL pop_gset2
0105 9508 RET
_DS1302_writeD:
data --> R20
addr --> R22
0106 940E0290 CALL push_gset2
0108 2F42 MOV R20,R18
0109 2F60 MOV R22,R16
(0122) }
(0123) /*******************************************
(0124) 函数名称: DS1302_writeD
(0125) 功 能: 向DS1302的某个地址写入一个字节数据
(0126) 参 数: addr--地址值(寄存器或RAM)
(0127) data--要写入的地址
(0128) 返回值 : 无
(0129) /********************************************/
(0130) void DS1302_writeD(uchar addr,uchar data)
(0131) {
(0132) PORTC&=~BIT(RTC_CS); //拉低片选端
010A 98A9 CBI 0x15,1
(0133) PORTC&=~BIT(RTC_CLK); //拉低时钟端
010B 98AF CBI 0x15,7
(0134) Delayus(10);
010C E00A LDI R16,0xA
010D E010 LDI R17,0
010E DF87 RCALL _Delayus
(0135) PORTC|=BIT(RTC_CS); //拉高片选端
010F 9AA9 SBI 0x15,1
(0136) Delayus(10); //调整片选脉冲
0110 E00A LDI R16,0xA
0111 E010 LDI R17,0
0112 DF83 RCALL _Delayus
(0137) DS1302_writeB(addr); //写入操作命令(地址)
0113 2F06 MOV R16,R22
0114 DFB3 RCALL _DS1302_writeB
(0138) Delayus(10);
0115 E00A LDI R16,0xA
0116 E010 LDI R17,0
0117 DF7E RCALL _Delayus
(0139) PORTC&=~BIT(RTC_CLK); //拉低时钟端
0118 98AF CBI 0x15,7
(0140) Delayus(10);
0119 E00A LDI R16,0xA
011A E010 LDI R17,0
011B DF7A RCALL _Delayus
(0141) DS1302_writeB(data); //写入数据
011C 2F04 MOV R16,R20
011D DFAA RCALL _DS1302_writeB
(0142) PORTC&=~BIT(RTC_CLK); //拉低时钟端
011E 98AF CBI 0x15,7
(0143) Delayus(10); //调整片选脉冲
011F E00A LDI R16,0xA
0120 E010 LDI R17,0
0121 DF74 RCALL _Delayus
(0144) PORTC&=~BIT(RTC_CS); //拉低片选端
0122 98A9 CBI 0x15,1
0123 940E0284 CALL pop_gset2
0125 9508 RET
_DS1302_readD:
data --> R20
addr --> R20
0126 940E0292 CALL push_gset1
0128 2F40 MOV R20,R16
(0145) }
(0146) /*******************************************
(0147) 函数名称: DS1302_readD
(0148) 功 能: 从DS1302的某个地址读出一个字节数据
(0149) 参 数: addr--地址值(寄存器或RAM)
(0150) 返回值 : data--读出的数据
(0151) /********************************************/
(0152) uchar DS1302_readD(uchar addr)
(0153) {
(0154) uchar data;
(0155) PORTC&=~BIT(RTC_CS); //拉低片选端
0129 98A9 CBI 0x15,1
(0156) PORTC&=~BIT(RTC_CLK); //拉低时钟端
012A 98AF CBI 0x15,7
(0157) Delayus(10);
012B E00A LDI R16,0xA
012C E010 LDI R17,0
012D DF68 RCALL _Delayus
(0158) PORTC|=BIT(RTC_CS); //拉高片选端
012E 9AA9 SBI 0x15,1
(0159) Delayus(10); //调整片选脉冲
012F E00A LDI R16,0xA
0130 E010 LDI R17,0
0131 DF64 RCALL _Delayus
(0160) DS1302_writeB(addr); //写入操作命令(地址)
0132 2F04 MOV R16,R20
0133 DF94 RCALL _DS1302_writeB
(0161) Delayus(10);
0134 E00A LDI R16,0xA
0135 E010 LDI R17,0
0136 DF5F RCALL _Delayus
(0162) data=DS1302_readB(); //读出数据
0137 DFA6 RCALL _DS1302_readB
0138 2F40 MOV R20,R16
(0163) Delayus(10);
0139 E00A LDI R16,0xA
013A E010 LDI R17,0
013B DF5A RCALL _Delayus
(0164) PORTC&=~BIT(RTC_CLK); //拉低时钟端
013C 98AF CBI 0x15,7
(0165) PORTC&=~BIT(RTC_CS); //拉低片选端
013D 98A9 CBI 0x15,1
(0166) return data; //返回读出的数据
013E 2F04 MOV R16,R20
013F 940E0295 CALL pop_gset1
0141 9508 RET
_DS1302_setT:
addr --> R20
i --> R22
ptTimeD --> R10
0142 940E028E CALL push_gset3
0144 0158 MOVW R10,R16
(0167) }
(0168) /*******************************************
(0169) 函数名称: DS1302_setT
(0170) 功 能: 设置DS1302的时间
(0171) 参 数: ptTimeD--设置时间数组指针
(0172) 返回值 : 无
(0173) /********************************************/
(0174) void DS1302_setT(uchar ptTimeD[])
(0175) {
(0176) uchar i;
(0177) uchar addr = 0x80; //写入地址从秒寄存器开始
0145 E840 LDI R20,0x80
(0178) DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
0146 2722 CLR R18
0147 E80E LDI R16,0x8E
0148 DFBD RCALL _DS1302_writeD
(0179) Delayms(5);
0149 E005 LDI R16,5
014A E010 LDI R17,0
014B DF62 RCALL _Delayms
(0180) for(i=0;i<2;i++)
014C 2766 CLR R22
014D C00C RJMP 0x015A
(0181) {
(0182) DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
014E 2FE6 MOV R30,R22
014F 27FF CLR R31
0150 0DEA ADD R30,R10
0151 1DFB ADC R31,R11
0152 8120 LDD R18,Z+0
0153 2F04 MOV R16,R20
0154 DFB1 RCALL _DS1302_writeD
(0183) addr+=2;
0155 5F4E SUBI R20,0xFE
(0184) Delayms(1);
0156 E001 LDI R16,1
0157 E010 LDI R17,0
0158 DF55 RCALL _Delayms
0159 9563 INC R22
015A 3062 CPI R22,2
015B F390 BCS 0x014E
(0185) }
(0186) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
015C E820 LDI R18,0x80
015D E80E LDI R16,0x8E
015E DFA7 RCALL _DS1302_writeD
015F 940E0287 CALL pop_gset3
0161 9508 RET
_DS1302_getT:
i --> R20
time --> R22
0162 940E0290 CALL push_gset2
0164 01B8 MOVW R22,R16
(0187) }
(0188) /*******************************************
(0189) 函数名称: DS1302_getT
(0190) 功 能: 读取DS1302的当前时间
(0191) 参 数: time[]--读取的时间数组
(0192) 返回值 : 无
(0193) /********************************************/
(0194) void DS1302_getT(uchar time[])
(0195) {
(0196) uchar i;
(0197) PORTC&=~BIT(RTC_CS); //拉低片选端
0165 98A9 CBI 0x15,1
(0198) Delayus(10);
0166 E00A LDI R16,0xA
0167 E010 LDI R17,0
0168 DF2D RCALL _Delayus
(0199) PORTC|=BIT(RTC_CS); //拉高片选端
0169 9AA9 SBI 0x15,1
(0200) Delayus(10); //调整片选脉冲
016A E00A LDI R16,0xA
016B E010 LDI R17,0
016C DF29 RCALL _Delayus
(0201) DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
016D EB0F LDI R16,0xBF
016E DF59 RCALL _DS1302_writeB
(0202) for (i=0;i<2;i++) //时间数据的存放格式是:
016F 2744 CLR R20
0170 C007 RJMP 0x0178
(0203) { //秒,分,时,日,月,星期,年,控制
(0204) time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
0171 DF6C RCALL _DS1302_readB
0172 2FE4 MOV R30,R20
0173 27FF CLR R31
0174 0FE6 ADD R30,R22
0175 1FF7 ADC R31,R23
0176 8300 STD Z+0,R16
0177 9543 INC R20
0178 3042 CPI R20,2
0179 F3B8 BCS 0x0171
(0205) }
(0206)
(0207) PORTC&=~BIT(RTC_CS); //拉低片选端
017A 98A9 CBI 0x15,1
(0208) PORTC&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
017B 98AF CBI 0x15,7
017C 940E0284 CALL pop_gset2
017E 9508 RET
_DS1302_check:
exist --> R20
017F 940E0292 CALL push_gset1
(0209) }
(0210) /*******************************************
(0211) 函数名称: DS1302_check
(0212) 功 能: 检测DS1302是否正常工作
(0213) 参 数: 无
(0214) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0215) /********************************************/
(0216) uchar DS1302_check(void)
(0217) {
(0218) uchar exist;
(0219) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
0181 2722 CLR R18
0182 E80E LDI R16,0x8E
0183 DF82 RCALL _DS1302_writeD
(0220) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
0184 EA25 LDI R18,0xA5
0185 EC00 LDI R16,0xC0
0186 DF7F RCALL _DS1302_writeD
(0221) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
0187 EC01 LDI R16,0xC1
0188 DF9D RCALL _DS1302_readD
0189 2F40 MOV R20,R16
(0222) if(exist==0xA5)
018A 3A05 CPI R16,0xA5
018B F411 BNE 0x018E
(0223) {
(0224) exist=TRUE; //如果读取值与写入值相等,返回TRUE
018C E041 LDI R20,1
(0225) }
018D C001 RJMP 0x018F
(0226) else
(0227) {
(0228) exist=FALSE; //如果读取值与写入值不相等,返回FALSE
018E 2744 CLR R20
(0229) }
(0230) return exist;
018F 2F04 MOV R16,R20
0190 940E0295 CALL pop_gset1
0192 9508 RET
(0231) }
(0232) /*******************************************
(0233) 函数名称: DS1302_init
(0234) 功 能: 初始化DS1302
(0235) 参 数: 无
(0236) 返回值 : 无
(0237) /********************************************/
(0238) void DS1302_init(void)
(0239) {
(0240) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
_DS1302_init:
0193 2722 CLR R18
0194 E80E LDI R16,0x8E
0195 DF70 RCALL _DS1302_writeD
(0241) DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
0196 2722 CLR R18
0197 E800 LDI R16,0x80
0198 DF6D RCALL _DS1302_writeD
(0242) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
0199 E820 LDI R18,0x80
019A E80E LDI R16,0x8E
019B DF6A RCALL _DS1302_writeD
019C 9508 RET
(0243) }
(0244) /*******************************************
(0245) 函数名称: BCD_ASCII
(0246) 功 能: 将压缩BCD码转换成ascii码
(0247) 参 数: BCD--将要转换的压缩BCD码
(0248) ptasc--转换后的ASCII码数组指针
(0249) 返回值 : 无
(0250) /********************************************/
(0251) void BCD_ASCII(uchar BCD,uchar ptasc[])
(0252) {
(0253) ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
_BCD_ASCII:
ptasc --> R18
BCD --> R16
019D 2F80 MOV R24,R16
019E 9582 SWAP R24
019F 708F ANDI R24,0xF
01A0 6380 ORI R24,0x30
01A1 01F9 MOVW R30,R18
01A2 8380 STD Z+0,R24
(0254) ptasc[1]=BCD&0x0F|0x30; //转换个位
01A3 2F80 MOV R24,R16
01A4 708F ANDI R24,0xF
01A5 6380 ORI R24,0x30
01A6 8381 STD Z+1,R24
01A7 9508 RET
_Disp_time:
dm --> Y+0
n --> R20
m --> R22
i --> R10
time --> R20
01A8 940E028E CALL push_gset3
01AA 01A8 MOVW R20,R16
01AB 9728 SBIW R28,0x8
(0255) }
(0256) /*******************************************
(0257) 函数名称: Disp_time
(0258) 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
(0259) 参 数: time[]--时间数组
(0260) 返回值 : 无
(0261) /********************************************/
(0262) void Disp_time(uchar time[])
(0263) { uint dm[4];
(0264) uchar i,m,n;
(0265)
(0266)
(0267) m=(uint)time[0];
01AC 01FA MOVW R30,R20
01AD 8160 LDD R22,Z+0
(0268) n=(uint)time[1];
01AE 8141 LDD R20,Z+1
(0269)
(0270) for(i=1;i<3;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -