📄 avrstudy.lst
字号:
data --> R20
addr --> R22
02E7 D827 RCALL push_gset2
02E8 2F42 MOV R20,R18
02E9 2F60 MOV R22,R16
(0129) }
(0130) /*******************************************
(0131) 函数名称: DS1302_writeD
(0132) 功 能: 向DS1302的某个地址写入一个字节数据
(0133) 参 数: addr--地址值(寄存器或RAM)
(0134) data--要写入的地址
(0135) 返回值 : 无
(0136) /********************************************/
(0137) void DS1302_writeD(uchar addr,uchar data)
(0138) {
(0139) {
(0140) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
02EA 98AB CBI 0x15,3
(0141) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端
02EB 98A9 CBI 0x15,1
(0142) Delayus(10);
02EC E00A LDI R16,0xA
02ED E010 LDI R17,0
02EE DF9C RCALL _Delayus
(0143) RTC_PORT|=BIT(RTC_CS); //拉高片选端
02EF 9AAB SBI 0x15,3
(0144) Delayus(10); //调整片选脉冲
02F0 E00A LDI R16,0xA
02F1 E010 LDI R17,0
02F2 DF98 RCALL _Delayus
(0145) DS1302_writeB(addr); //写入操作命令(地址)
02F3 2F06 MOV R16,R22
02F4 DFC3 RCALL _DS1302_writeB
(0146) Delayus(10);
02F5 E00A LDI R16,0xA
02F6 E010 LDI R17,0
02F7 DF93 RCALL _Delayus
(0147) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端
02F8 98A9 CBI 0x15,1
(0148) Delayus(10);
02F9 E00A LDI R16,0xA
02FA E010 LDI R17,0
02FB DF8F RCALL _Delayus
(0149) DS1302_writeB(data); //写入数据
02FC 2F04 MOV R16,R20
02FD DFBA RCALL _DS1302_writeB
(0150) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端
02FE 98A9 CBI 0x15,1
(0151) Delayus(10); //调整片选脉冲
02FF E00A LDI R16,0xA
0300 E010 LDI R17,0
0301 DF89 RCALL _Delayus
(0152) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
0302 98AB CBI 0x15,3
(0153) }
0303 D7FD RCALL pop_gset2
0304 9508 RET
_DS1302_readD:
data --> R20
addr --> R20
0305 D80B RCALL push_gset1
0306 2F40 MOV R20,R16
(0154) }
(0155) /*******************************************
(0156) 函数名称: DS1302_readD
(0157) 功 能: 从DS1302的某个地址读出一个字节数据
(0158) 参 数: addr--地址值(寄存器或RAM)
(0159) 返回值 : data--读出的数据
(0160) ********************************************/
(0161) uchar DS1302_readD(uchar addr)
(0162) {
(0163) uchar data;
(0164) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
0307 98AB CBI 0x15,3
(0165) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端
0308 98A9 CBI 0x15,1
(0166) Delayus(10);
0309 E00A LDI R16,0xA
030A E010 LDI R17,0
030B DF7F RCALL _Delayus
(0167) RTC_PORT|=BIT(RTC_CS); //拉高片选端
030C 9AAB SBI 0x15,3
(0168) Delayus(10); //调整片选脉冲
030D E00A LDI R16,0xA
030E E010 LDI R17,0
030F DF7B RCALL _Delayus
(0169) DS1302_writeB(addr); //写入操作命令(地址)
0310 2F04 MOV R16,R20
0311 DFA6 RCALL _DS1302_writeB
(0170) Delayus(10);
0312 E00A LDI R16,0xA
0313 E010 LDI R17,0
0314 DF76 RCALL _Delayus
(0171) data=DS1302_readB(); //读出数据
0315 DFB6 RCALL _DS1302_readB
0316 2F40 MOV R20,R16
(0172) Delayus(10);
0317 E00A LDI R16,0xA
0318 E010 LDI R17,0
0319 DF71 RCALL _Delayus
(0173) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端
031A 98A9 CBI 0x15,1
(0174) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
031B 98AB CBI 0x15,3
(0175) return data; //返回读出的数据
031C 2F04 MOV R16,R20
031D D7F6 RCALL pop_gset1
031E 9508 RET
_DS1302_setT:
addr --> R20
i --> R22
ptTimeD --> R10
031F D7ED RCALL push_gset3
0320 0158 MOVW R10,R16
(0176) }
(0177) /*******************************************
(0178) 函数名称: DS1302_setT
(0179) 功 能: 设置DS1302的时间
(0180) 参 数: ptTimeD--设置时间数组指针
(0181) 返回值 : 无
(0182) ********************************************/
(0183) void DS1302_setT(uchar ptTimeD[])
(0184) {
(0185) uchar i;
(0186) uchar addr = 0x80; //写入地址从秒寄存器开始
0321 E840 LDI R20,0x80
(0187) DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
0322 2722 CLR R18
0323 E80E LDI R16,0x8E
0324 DFC2 RCALL _DS1302_writeD
(0188) Delayms(5);
0325 E005 LDI R16,5
0326 E010 LDI R17,0
0327 DF78 RCALL _Delayms
(0189) for(i=0;i<7;i++)
0328 2766 CLR R22
0329 C00C RJMP 0x0336
(0190) {
(0191) DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
032A 2FE6 MOV R30,R22
032B 27FF CLR R31
032C 0DEA ADD R30,R10
032D 1DFB ADC R31,R11
032E 8120 LDD R18,Z+0
032F 2F04 MOV R16,R20
0330 DFB6 RCALL _DS1302_writeD
(0192) addr+=2;
0331 5F4E SUBI R20,0xFE
(0193) Delayms(1);
0332 E001 LDI R16,1
0333 E010 LDI R17,0
0334 DF6B RCALL _Delayms
0335 9563 INC R22
0336 3067 CPI R22,7
0337 F390 BCS 0x032A
(0194) }
(0195) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
0338 E820 LDI R18,0x80
0339 E80E LDI R16,0x8E
033A DFAC RCALL _DS1302_writeD
033B D7C7 RCALL pop_gset3
033C 9508 RET
_DS1302_getT:
i --> R20
time --> R22
033D D7D1 RCALL push_gset2
033E 01B8 MOVW R22,R16
(0196) }
(0197) /*******************************************
(0198) 函数名称: DS1302_getT
(0199) 功 能: 读取DS1302的当前时间
(0200) 参 数: time[]--读取的时间数组
(0201) 返回值 : 无
(0202) ********************************************/
(0203) void DS1302_getT(uchar time[])
(0204) {
(0205) uchar i;
(0206) /*=======下面的是单次读写===================
(0207) uchar addr = 0x80; //读取地址从秒寄存器开始
(0208) for(i=0;i<7;i++)
(0209) {
(0210) time[i]=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
(0211) addr+=2;
(0212) }
(0213) ===========================================*/
(0214) //=========下面是多字节读取================
(0215) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
033F 98AB CBI 0x15,3
(0216) Delayus(10);
0340 E00A LDI R16,0xA
0341 E010 LDI R17,0
0342 DF48 RCALL _Delayus
(0217) RTC_PORT|=BIT(RTC_CS); //拉高片选端
0343 9AAB SBI 0x15,3
(0218) Delayus(10); //调整片选脉冲
0344 E00A LDI R16,0xA
0345 E010 LDI R17,0
0346 DF44 RCALL _Delayus
(0219) DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
0347 EB0F LDI R16,0xBF
0348 DF6F RCALL _DS1302_writeB
(0220) for (i=0;i<8;i++) //时间数据的存放格式是:
0349 2744 CLR R20
034A C007 RJMP 0x0352
(0221) { //秒,分,时,日,月,星期,年,控制
(0222) time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
034B DF80 RCALL _DS1302_readB
034C 2FE4 MOV R30,R20
034D 27FF CLR R31
034E 0FE6 ADD R30,R22
034F 1FF7 ADC R31,R23
0350 8300 STD Z+0,R16
0351 9543 INC R20
0352 3048 CPI R20,0x8
0353 F3B8 BCS 0x034B
(0223) }
(0224) RTC_PORT&=~BIT(RTC_CS); //拉低片选端
0354 98AB CBI 0x15,3
(0225) //======================================
(0226) RTC_PORT&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
0355 98A9 CBI 0x15,1
0356 D7AA RCALL pop_gset2
0357 9508 RET
_DS1302_check:
exist --> R20
0358 D7B8 RCALL push_gset1
(0227) }
(0228) /*******************************************
(0229) 函数名称: DS1302_check
(0230) 功 能: 检测DS1302是否正常工作
(0231) 参 数: 无
(0232) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0233) /********************************************/
(0234) uchar DS1302_check(void)
(0235) {
(0236) uchar exist;
(0237) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
0359 2722 CLR R18
035A E80E LDI R16,0x8E
035B DF8B RCALL _DS1302_writeD
(0238) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
035C EA25 LDI R18,0xA5
035D EC00 LDI R16,0xC0
035E DF88 RCALL _DS1302_writeD
(0239) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
035F EC01 LDI R16,0xC1
0360 DFA4 RCALL _DS1302_readD
0361 2F40 MOV R20,R16
(0240) if(exist==0xA5)
0362 3A05 CPI R16,0xA5
0363 F411 BNE 0x0366
(0241) {
(0242) exist=TRUE; //如果读取值与写入值相等,返回TRUE
0364 E041 LDI R20,1
(0243) }
0365 C001 RJMP 0x0367
(0244) else
(0245) {
(0246) exist=FALSE; //如果读取值与写入值不相等,返回FALSE
0366 2744 CLR R20
(0247) }
(0248) return exist;
0367 2F04 MOV R16,R20
0368 D7AB RCALL pop_gset1
0369 9508 RET
(0249) }
(0250) /*******************************************
(0251) 函数名称: DS1302_init
(0252) 功 能: 初始化DS1302
(0253) 参 数: 无
(0254) 返回值 : 无
(0255) ********************************************/
(0256) void DS1302_init(void)
(0257) {
(0258) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
_DS1302_init:
036A 2722 CLR R18
036B E80E LDI R16,0x8E
036C DF7A RCALL _DS1302_writeD
(0259) DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
036D 2722 CLR R18
036E E800 LDI R16,0x80
036F DF77 RCALL _DS1302_writeD
(0260) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
0370 E820 LDI R18,0x80
0371 E80E LDI R16,0x8E
0372 DF74 RCALL _DS1302_writeD
0373 9508 RET
(0261) }
(0262) /*******************************************
(0263) 函数名称: BCD_ASCII
(0264) 功 能: 将压缩BCD码转换成ascii码
(0265) 参 数: BCD--将要转换的压缩BCD码
(0266) ptasc--转换后的ASCII码数组指针
(0267) 返回值 : 无
(0268) /********************************************/
(0269) void BCD_ASCII(uchar BCD,uchar ptasc[])
(0270) {
(0271) ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
_BCD_ASCII:
ptasc --> R18
BCD --> R16
0374 2F80 MOV R24,R16
0375 9582 SWAP R24
0376 708F ANDI R24,0xF
0377 6380 ORI R24,0x30
0378 01F9 MOVW R30,R18
0379 8380 STD Z+0,R24
(0272) ptasc[1]=BCD&0x0F|0x30; //转换个位
037A 2F80 MOV R24,R16
037B 708F ANDI R24,0xF
037C 6380 ORI R24,0x30
037D 8381 STD Z+1,R24
037E 9508 RET
_Disp_time:
vstr --> Y+0
vstrtemp --> R20
i --> R22
time --> R10
037F D78D RCALL push_gset3
0380 0158 MOVW R10,R16
0381 9760 SBIW R28,0x10
(0273) }
(0274) /*******************************************
(0275) 函数名称: Disp_time
(0276) 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
(0277) 参 数: time[]--时间数组
(0278) 返回值 : 无
(0279) /********************************************/
(0280) void Disp_time(uchar time[])
(0281) {
(0282) unsigned int vstrtemp,i;
(0283) unsigned int vstr[8];
(0284) vstr[0] = time[3]/16+0x30;
0382 E120 LDI R18,0x10
0383 E030 LDI R19,0
0384 01F5 MOVW R30,R10
0385 8103 LDD R16,Z+3
0386 2711 CLR R17
0387 D6C3 RCALL div16s
0388 01C8 MOVW R24,R16
0389 96C0 ADIW R24,0x30
038A 8399 STD Y+1,R25
038B 8388 STD Y+0,R24
(0285) vstr[1] = time[3]%16+0x30;
038C E120 LDI R18,0x10
038D E030 LDI R19,0
038E 01F5 MOVW R30,R10
038F 8103 LDD R16,Z+3
0390 2711 CLR R17
0391 D6B5 RCALL mod16s
0392 01C8 MOVW R24,R16
0393 96C0 ADIW R24,0x30
0394 839B STD Y+3,R25
0395 838A STD Y+2,R24
(0286) vstr[2] = '/';
0396 E28F LDI R24,0x2F
0397 E090 LDI R25,0
0398 839D STD Y+5,R25
0399 838C STD Y+4,R24
(0287) vstr[3] = time[4]/16+0x30;
039A E120 LDI R18,0x10
039B E030 LDI R19,0
039C 01F5 MOVW R30,R10
039D 8104 LDD R16,Z+4
039E 2711 CLR R17
039F D6AB RCALL div16s
03A0 01C8 MOVW R24,R16
03A1 96C0 ADIW R24,0x30
03A2 839F STD Y+7,R25
03A3 838E STD Y+6,R24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -