📄 rtc.lst
字号:
(0164) 函数名称: DS1302_check
(0165) 功 能: 检测DS1302是否正常工作
(0166) 参 数: 无
(0167) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0168) /********************************************/
(0169) uchar DS1302_check(void)
(0170) {
(0171) uchar exist;
(0172) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
02AD 2722 CLR R18
02AE E80E LDI R16,0x8E
02AF DF89 RCALL _DS1302_writeD
(0173) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
02B0 EA25 LDI R18,0xA5
02B1 EC00 LDI R16,0xC0
02B2 DF86 RCALL _DS1302_writeD
(0174) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
02B3 EC01 LDI R16,0xC1
02B4 DFA4 RCALL _DS1302_readD
02B5 2F40 MOV R20,R16
(0175) if(exist==0xA5)
02B6 3A05 CPI R16,0xA5
02B7 F411 BNE 0x02BA
(0176) {
(0177) exist=TRUE; //如果读取值与写入值相等,返回TRUE
02B8 E041 LDI R20,1
(0178) }
02B9 C001 RJMP 0x02BB
(0179) else
(0180) {
(0181) exist=FALSE; //如果读取值与写入值不相等,返回FALSE
02BA 2744 CLR R20
(0182) }
(0183) return exist;
02BB 2F04 MOV R16,R20
02BC 940E06EB CALL pop_gset1
02BE 9508 RET
(0184) }
(0185) /*******************************************
(0186) 函数名称: DS1302_init
(0187) 功 能: 初始化DS1302
(0188) 参 数: 无
(0189) 返回值 : 无
(0190) /********************************************/
(0191) void DS1302_init(void)
(0192) {
(0193) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
_DS1302_init:
02BF 2722 CLR R18
02C0 E80E LDI R16,0x8E
02C1 DF77 RCALL _DS1302_writeD
(0194) DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
02C2 2722 CLR R18
02C3 E800 LDI R16,0x80
02C4 DF74 RCALL _DS1302_writeD
(0195) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
02C5 E820 LDI R18,0x80
02C6 E80E LDI R16,0x8E
(0196) }
02C7 CF71 RJMP _DS1302_writeD
_BCD_ASCII:
ptasc --> R20
BCD --> R22
02C8 940E06FF CALL push_gset2
02CA 01A9 MOVW R20,R18
02CB 2F60 MOV R22,R16
(0197) /*******************************************
(0198) 函数名称: BCD_ASCII
(0199) 功 能: 将压缩BCD码转换成ascii码
(0200) 参 数: BCD--将要转换的压缩BCD码
(0201) ptasc--转换后的ASCII码数组指针
(0202) 返回值 : 无
(0203) /********************************************/
(0204) void BCD_ASCII(uchar BCD,uchar *ptasc)
(0205) {
(0206) *ptasc=BCD/16|0x30; //转换十位
02CC E110 LDI R17,0x10
02CD 2F06 MOV R16,R22
02CE 940E06C6 CALL div8u
02D0 2F80 MOV R24,R16
02D1 6380 ORI R24,0x30
02D2 01FA MOVW R30,R20
02D3 8380 STD R24,0+Z
(0207) *(ptasc+1)=BCD&0x0F|0x30; //转换个位
02D4 2F86 MOV R24,R22
02D5 708F ANDI R24,0xF
02D6 6380 ORI R24,0x30
02D7 8381 STD R24,1+Z
(0208) }
02D8 940E0707 CALL pop_gset2
02DA 9508 RET
_Disp_time:
line1 --> Y+11
line2 --> Y+2
asc --> Y+0
i --> R20
time --> R22
02DB 940E06FF CALL push_gset2
02DD 01B8 MOVW R22,R16
02DE 9766 SBIW R28,0x16
(0209) /*******************************************
(0210) 函数名称: Disp_time
(0211) 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
(0212) 参 数: time[]--时间数组
(0213) 返回值 : 无
(0214) /********************************************/
(0215) void Disp_time(uchar time[])
(0216) {
(0217) uchar i,asc[2];
(0218) uchar line1[11]={0,0,'-',0,0,'-',0,0,' ',0,'\0'};//显示第1行的字符数组
02DF E78A LDI R24,0x7A
02E0 E090 LDI R25,0
02E1 01FE MOVW R30,R28
02E2 963B ADIW R30,0xB
02E3 E00B LDI R16,0xB
02E4 E010 LDI R17,0
02E5 93FA ST R31,-Y
02E6 93EA ST R30,-Y
02E7 939A ST R25,-Y
02E8 938A ST R24,-Y
02E9 940E070D CALL asgncblk
(0219) uchar line2[9]={0,0,':',0,0,':',0,0,'\0'}; //显示第2行的字符数组
02EB E885 LDI R24,0x85
02EC E090 LDI R25,0
02ED 01FE MOVW R30,R28
02EE 9632 ADIW R30,2
02EF E009 LDI R16,0x9
02F0 E010 LDI R17,0
02F1 93FA ST R31,-Y
02F2 93EA ST R30,-Y
02F3 939A ST R25,-Y
02F4 938A ST R24,-Y
02F5 940E070D CALL asgncblk
(0220) for(i=0;i<3;i++) //为第2行的字符数组赋值
02F7 2744 CLR R20
02F8 C01F RJMP 0x0318
(0221) {
(0222) BCD_ASCII(time[2-i],asc);
02F9 019E MOVW R18,R28
02FA 2E24 MOV R2,R20
02FB 2433 CLR R3
02FC E0E2 LDI R30,2
02FD E0F0 LDI R31,0
02FE 19E2 SUB R30,R2
02FF 09F3 SBC R31,R3
0300 0FE6 ADD R30,R22
0301 1FF7 ADC R31,R23
0302 8100 LDD R16,0+Z
0303 DFC4 RCALL _BCD_ASCII
(0223) line2[i*3]=asc[0]&0x7F;
0304 E083 LDI R24,3
0305 9F84 MUL R24,R20
0306 01F0 MOVW R30,R0
0307 01CE MOVW R24,R28
0308 9602 ADIW R24,2
0309 0FE8 ADD R30,R24
030A 1FF9 ADC R31,R25
030B 8188 LDD R24,0+Y
030C 778F ANDI R24,0x7F
030D 8380 STD R24,0+Z
(0224) line2[i*3+1]=asc[1];
030E E083 LDI R24,3
030F 9F84 MUL R24,R20
0310 01F0 MOVW R30,R0
0311 01CE MOVW R24,R28
0312 9603 ADIW R24,3
0313 0FE8 ADD R30,R24
0314 1FF9 ADC R31,R25
0315 8029 LDD R2,1+Y
0316 8220 STD R2,0+Z
0317 9543 INC R20
0318 3043 CPI R20,3
0319 F2F8 BCS 0x02F9
(0225) }
(0226) BCD_ASCII(time[6],asc); //为第1行的年赋值
031A 019E MOVW R18,R28
031B 01FB MOVW R30,R22
031C 8106 LDD R16,6+Z
031D DFAA RCALL _BCD_ASCII
(0227) line1[0]=asc[0];
031E 8028 LDD R2,0+Y
031F 862B STD R2,11+Y
(0228) line1[1]=asc[1];
0320 8029 LDD R2,1+Y
0321 862C STD R2,12+Y
(0229) BCD_ASCII(time[4],asc); //为第1行的月赋值
0322 019E MOVW R18,R28
0323 01FB MOVW R30,R22
0324 8104 LDD R16,4+Z
0325 DFA2 RCALL _BCD_ASCII
(0230) line1[3]=asc[0];
0326 8028 LDD R2,0+Y
0327 862E STD R2,14+Y
(0231) line1[4]=asc[1];
0328 8029 LDD R2,1+Y
0329 862F STD R2,15+Y
(0232) BCD_ASCII(time[3],asc); //为第1行的日赋值
032A 019E MOVW R18,R28
032B 01FB MOVW R30,R22
032C 8103 LDD R16,3+Z
032D DF9A RCALL _BCD_ASCII
(0233) line1[6]=asc[0];
032E 8028 LDD R2,0+Y
032F 8A29 STD R2,17+Y
(0234) line1[7]=asc[1];
0330 8029 LDD R2,1+Y
0331 8A2A STD R2,18+Y
(0235) BCD_ASCII(time[5],asc); //为第1行的星期赋值
0332 019E MOVW R18,R28
0333 01FB MOVW R30,R22
0334 8105 LDD R16,5+Z
0335 DF92 RCALL _BCD_ASCII
(0236) line1[9]=asc[1];
0336 8029 LDD R2,1+Y
0337 8A2C STD R2,20+Y
(0237)
(0238) while(LCD1602_readBF());
0338 DDDE RCALL _LCD1602_readBF
0339 2300 TST R16
033A F7E9 BNE 0x0338
(0239) LCD1602_gotoXY(1,2); //第1行从第3个位置开始显示
033B E022 LDI R18,2
033C E001 LDI R16,1
033D DDE7 RCALL _LCD1602_gotoXY
(0240) LCD1602_sendstr("20"); //将07年显示为2007的形式
033E E704 LDI R16,0x74
033F E010 LDI R17,0
0340 DDC0 RCALL _LCD1602_sendstr
(0241) LCD1602_sendstr(line1); //第1行显示
0341 018E MOVW R16,R28
0342 5F05 SUBI R16,0xF5
0343 4F1F SBCI R17,0xFF
0344 DDBC RCALL _LCD1602_sendstr
(0242) while(LCD1602_readBF());
0345 DDD1 RCALL _LCD1602_readBF
0346 2300 TST R16
0347 F7E9 BNE 0x0345
(0243) LCD1602_gotoXY(2,4); //第2行从第5个位置开始显示
0348 E024 LDI R18,4
0349 E002 LDI R16,2
034A DDDA RCALL _LCD1602_gotoXY
(0244) LCD1602_sendstr(line2); //第2行显示
034B 018E MOVW R16,R28
034C 5F0E SUBI R16,0xFE
034D 4F1F SBCI R17,0xFF
034E DDB2 RCALL _LCD1602_sendstr
(0245) }
034F 9666 ADIW R28,0x16
0350 940E0707 CALL pop_gset2
0352 9508 RET
_main:
settime --> Y+7
set_num --> Y+17
dis_y --> R14
dis_x --> R22
setadd --> R20
i --> Y+16
shift --> R10
gettime --> Y+0
RD_TFLAG --> Y+15
setdat --> Y+14
0353 9764 SBIW R28,0x14
(0246) /*******************************************
(0247) 函数名称: main
(0248) 功 能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
(0249) 参 数: 无
(0250) 返回值 : 无
(0251) /********************************************/
(0252) void main(void)
(0253) {
(0254) uchar i,RD_TFLAG=1,set_num=0;//i为键盘译码值
0354 2400 CLR R0
0355 9403 INC R0
0356 860F STD R0,15+Y
0357 2400 CLR R0
0358 8A09 STD R0,17+Y
(0255) //RD_TFLAG为是否设置时间的标志,为1是显示状态,不设置,为0时进入设置状态
(0256) //set_num是设置哪一位的标志,如为0的时候设置的是秒
(0257) uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器
(0258) //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
(0259) //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
(0260) uchar dis_x,dis_y; //存储1602液晶当前光标的位置
(0261) uchar settime[7]={0x15,0x58,0x13,0x01,0x01,0x06,0x07};//设置的秒,分,时,日,月,星期,年
0359 E88E LDI R24,0x8E
035A E090 LDI R25,0
035B 01FE MOVW R30,R28
035C 9637 ADIW R30,7
035D E007 LDI R16,7
035E E010 LDI R17,0
035F 93FA ST R31,-Y
0360 93EA ST R30,-Y
0361 939A ST R25,-Y
0362 938A ST R24,-Y
0363 940E070D CALL asgncblk
(0262) uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数组
0365 E985 LDI R24,0x95
0366 E090 LDI R25,0
0367 01FE MOVW R30,R28
0368 E007 LDI R16,7
0369 E010 LDI R17,0
036A 93FA ST R31,-Y
036B 93EA ST R30,-Y
036C 939A ST R25,-Y
036D 938A ST R24,-Y
036E 940E070D CALL asgncblk
(0263) Board_init(); //初始化开发板
0370 DD38 RCALL _Board_init
(0264) LCD1602_initial(); //初始化1602液晶
0371 DDC9 RCALL _LCD1602_initial
(0265) DS1302_portinit(); //初始化DS1302的三根数据线
0372 DE8F RCALL _DS1302_portinit
(0266) DS1302_init(); //启动振荡器,DS1302开始工作
0373 DF4B RCALL _DS1302_init
0374 C34C RJMP 0x06C1
(0267) //DS1302_setT(settime); //设置初始时间
(0268) //DS1302_init(); //启动振荡器,DS1302开始工作
(0269) while(1) //以下程序完成显示和设置时间
(0270) {
(0271) if(RD_TFLAG) //如果是设置模式则不更新时间显示
0375 840F LDD R0,15+Y
0376 2000 TST R0
0377 F021 BEQ 0x037C
(0272) {
(0273) DS1302_getT(gettime); //获得当前时间
0378 018E MOVW R16,R28
0379 DF1B RCALL _DS1302_getT
(0274) Disp_time(gettime); //显示当前时间
037A 018E MOVW R16,R28
037B DF5F RCALL _Disp_time
(0275) }
(0276) if(Mkey_press()) //是否有按键按下
037C DDD5 RCALL _Mkey_press
037D 2300 TST R16
037E F409 BNE 0x0380
037F C341 RJMP 0x06C1
(0277) {
(0278) i=Mkey_scan(); //扫描并反回翻译后的键码
0380 DDDF RCALL _Mkey_scan
0381 8B08 STD R16,16+Y
(0279) switch(i)
0382 88C8 LDD R12,16+Y
0383 24DD CLR R13
0384 20CC TST R12
0385 F419 BNE 0x0389
0386 20DD TST R13
0387 F409 BNE 0x0389
0388 C039 RJMP 0x03C2
0389 01C6 MOVW R24,R12
038A 3081 CPI R24,1
038B E0E0 LDI R30,0
038C 079E CPC R25,R30
038D F409 BNE 0x038F
038E C068 RJMP 0x03F7
038F 3082 CPI R24,2
0390 E0E0 LDI R30,0
0391 079E CPC R25,R30
0392 F409 BNE 0x0394
0393 C09A RJMP 0x042E
0394 3083 CPI R24,3
0395 E0E0 LDI R30,0
0396 079E CPC R25,R30
0397 F409 BNE 0x0399
0398 C0CC RJMP 0x0465
0399 3084 CPI R24,4
039A E0E0 LDI R30,0
039B 079E CPC R25,R30
039C F409 BNE 0x039E
039D C0FE RJMP 0x049C
039E 3085 CPI R24,5
039F E0E0 LDI R30,0
03A0 079E CPC R25,R30
03A1 F409 BNE 0x03A3
03A2 C130 RJMP 0x04D3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -