📄 ds1302.lst
字号:
(0195) addr+=2;
(0196) }*/
(0197) ////////////////////////////////////////////////////
(0198) /////////下面是多字节读取///////////////
(0199) PORTB&=~BIT(RTC_CS); //拉低片选端
01F7 98C4 CBI 0x18,4
(0200) Delayus(10);
01F8 E00A LDI R16,0xA
01F9 E010 LDI R17,0
01FA DF4E RCALL _Delayus
(0201) PORTB|=BIT(RTC_CS); //拉高片选端
01FB 9AC4 SBI 0x18,4
(0202) Delayus(10); //调整片选脉冲
01FC E00A LDI R16,0xA
01FD E010 LDI R17,0
01FE DF4A RCALL _Delayus
(0203) DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
01FF EB0F LDI R16,0xBF
0200 DF64 RCALL _DS1302_writeB
(0204) for (i=0;i<8;i++) //时间数据的存放格式是:
0201 2744 CLR R20
0202 C007 RJMP 0x020A
(0205) { //秒,分,时,日,月,星期,年,控制
(0206) time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
0203 DF77 RCALL _DS1302_readB
0204 2FE4 MOV R30,R20
0205 27FF CLR R31
0206 0FE6 ADD R30,R22
0207 1FF7 ADC R31,R23
0208 8300 STD Z+0,R16
0209 9543 INC R20
020A 3048 CPI R20,0x8
020B F3B8 BCS 0x0203
(0207) }
(0208)
(0209) PORTB&=~BIT(RTC_CS); //拉低片选端
020C 98C4 CBI 0x18,4
(0210) ///////////////////////////////////////////////
(0211) PORTB&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
020D 98C7 CBI 0x18,7
020E 940E02BF CALL pop_gset2
0210 9508 RET
(0212) }
(0213) /*******************************************
(0214) 函数名称: DS1302_check
(0215) 功 能: 检测DS1302是否正常工作
(0216) 参 数: 无
(0217) 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0218) /********************************************/
(0219) /*uchar DS1302_check(void)
(0220) {
(0221) uchar exist;
(0222) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
(0223) DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
(0224) exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
(0225) if(exist==0xA5)
(0226) {
(0227) exist=TRUE; //如果读取值与写入值相等,返回TRUE
(0228) }
(0229) else
(0230) {
(0231) exist=FALSE; //如果读取值与写入值不相等,返回FALSE
(0232) }
(0233) return exist;
(0234) }*/
(0235) /*******************************************
(0236) 函数名称: DS1302_init
(0237) 功 能: 初始化DS1302
(0238) 参 数: 无
(0239) 返回值 : 无
(0240) /********************************************/
(0241) void DS1302_init(void)
(0242) {
(0243) DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
_DS1302_init:
0211 2722 CLR R18
0212 E80E LDI R16,0x8E
0213 DF84 RCALL _DS1302_writeD
(0244) DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
0214 2722 CLR R18
0215 E800 LDI R16,0x80
0216 DF81 RCALL _DS1302_writeD
(0245) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
0217 E820 LDI R18,0x80
0218 E80E LDI R16,0x8E
0219 DF7E RCALL _DS1302_writeD
021A 9508 RET
(0246) }
(0247) /*******************************************
(0248) 函数名称: BCD_ASCII
(0249) 功 能: 将压缩BCD码转换成ascii码
(0250) 参 数: BCD--将要转换的压缩BCD码
(0251) ptasc--转换后的ASCII码数组指针
(0252) 返回值 : 无
(0253) /********************************************/
(0254) void BCD_ASCII(uchar BCD,uchar ptasc[])
(0255) {
(0256) ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
_BCD_ASCII:
ptasc --> R18
BCD --> R16
021B 2F80 MOV R24,R16
021C 9582 SWAP R24
021D 708F ANDI R24,0xF
021E 6380 ORI R24,0x30
021F 01F9 MOVW R30,R18
0220 8380 STD Z+0,R24
(0257) ptasc[1]=BCD&0x0F|0x30; //转换个位
0221 2F80 MOV R24,R16
0222 708F ANDI R24,0xF
0223 6380 ORI R24,0x30
0224 8381 STD Z+1,R24
0225 9508 RET
_Disp_time:
line1 --> Y+11
line2 --> Y+2
asc --> Y+0
i --> R20
time --> R22
0226 940E02CB CALL push_gset2
0228 01B8 MOVW R22,R16
0229 9766 SBIW R28,0x16
(0258) }
(0259) /*******************************************
(0260) 函数名称: Disp_time
(0261) 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
(0262) 参 数: time[]--时间数组
(0263) 返回值 : 无
(0264) /********************************************/
(0265) void Disp_time(uchar time[])
(0266) {
(0267) uchar i,asc[2];
(0268) uchar line1[11]={0,0,'-',0,0,'-',0,0,' ',0,'\0'};//显示第1行的字符数组
022A E584 LDI R24,0x54
022B E090 LDI R25,0
022C 01FE MOVW R30,R28
022D 963B ADIW R30,0xB
022E E00B LDI R16,0xB
022F E010 LDI R17,0
0230 93FA ST R31,-Y
0231 93EA ST R30,-Y
0232 939A ST R25,-Y
0233 938A ST R24,-Y
0234 940E02E4 CALL asgncblk
(0269) uchar line2[9]={0,0,':',0,0,':',0,0,'\0'}; //显示第2行的字符数组
0236 E58F LDI R24,0x5F
0237 E090 LDI R25,0
0238 01FE MOVW R30,R28
0239 9632 ADIW R30,2
023A E009 LDI R16,0x9
023B E010 LDI R17,0
023C 93FA ST R31,-Y
023D 93EA ST R30,-Y
023E 939A ST R25,-Y
023F 938A ST R24,-Y
0240 940E02E4 CALL asgncblk
(0270) for(i=0;i<3;i++) //为第2行的字符数组赋值
0242 2744 CLR R20
0243 C01E RJMP 0x0262
(0271) {
(0272) BCD_ASCII(time[2-i],asc);
0244 019E MOVW R18,R28
0245 2E24 MOV R2,R20
0246 2433 CLR R3
0247 E0E2 LDI R30,2
0248 E0F0 LDI R31,0
0249 19E2 SUB R30,R2
024A 09F3 SBC R31,R3
024B 0FE6 ADD R30,R22
024C 1FF7 ADC R31,R23
024D 8100 LDD R16,Z+0
024E DFCC RCALL _BCD_ASCII
(0273) line2[i*3]=asc[0];
024F E083 LDI R24,3
0250 9F84 MUL R24,R20
0251 01F0 MOVW R30,R0
0252 01CE MOVW R24,R28
0253 9602 ADIW R24,2
0254 0FE8 ADD R30,R24
0255 1FF9 ADC R31,R25
0256 8028 LDD R2,Y+0
0257 8220 STD Z+0,R2
(0274) line2[i*3+1]=asc[1];
0258 E083 LDI R24,3
0259 9F84 MUL R24,R20
025A 01F0 MOVW R30,R0
025B 01CE MOVW R24,R28
025C 9603 ADIW R24,3
025D 0FE8 ADD R30,R24
025E 1FF9 ADC R31,R25
025F 8029 LDD R2,Y+1
0260 8220 STD Z+0,R2
0261 9543 INC R20
0262 3043 CPI R20,3
0263 F300 BCS 0x0244
(0275) }
(0276) BCD_ASCII(time[6],asc); //为第1行的年赋值
0264 019E MOVW R18,R28
0265 01FB MOVW R30,R22
0266 8106 LDD R16,Z+6
0267 DFB3 RCALL _BCD_ASCII
(0277) line1[0]=asc[0];
0268 8028 LDD R2,Y+0
0269 862B STD Y+11,R2
(0278) line1[1]=asc[1];
026A 8029 LDD R2,Y+1
026B 862C STD Y+12,R2
(0279) BCD_ASCII(time[4],asc); //为第1行的月赋值
026C 019E MOVW R18,R28
026D 01FB MOVW R30,R22
026E 8104 LDD R16,Z+4
026F DFAB RCALL _BCD_ASCII
(0280) line1[3]=asc[0];
0270 8028 LDD R2,Y+0
0271 862E STD Y+14,R2
(0281) line1[4]=asc[1];
0272 8029 LDD R2,Y+1
0273 862F STD Y+15,R2
(0282) BCD_ASCII(time[3],asc); //为第1行的日赋值
0274 019E MOVW R18,R28
0275 01FB MOVW R30,R22
0276 8103 LDD R16,Z+3
0277 DFA3 RCALL _BCD_ASCII
(0283) line1[6]=asc[0];
0278 8028 LDD R2,Y+0
0279 8A29 STD Y+17,R2
(0284) line1[7]=asc[1];
027A 8029 LDD R2,Y+1
027B 8A2A STD Y+18,R2
(0285) BCD_ASCII(time[5],asc); //为第1行的星期赋值
027C 019E MOVW R18,R28
027D 01FB MOVW R30,R22
027E 8105 LDD R16,Z+5
027F DF9B RCALL _BCD_ASCII
(0286) line1[9]=asc[1];
0280 8029 LDD R2,Y+1
0281 8A2C STD Y+20,R2
(0287)
(0288) LCD_write_string(0X82,"20"); //第1行从第3个位置开始显示,将07年显示为2007的形式
0282 E620 LDI R18,0x60
0283 E030 LDI R19,0
0284 E802 LDI R16,0x82
0285 DE66 RCALL _LCD_write_string
(0289)
(0290) LCD_write_string(0X84,line1);
0286 019E MOVW R18,R28
0287 5F25 SUBI R18,0xF5
0288 4F3F SBCI R19,0xFF
0289 E804 LDI R16,0x84
028A DE61 RCALL _LCD_write_string
(0291)
(0292) LCD_write_string(0X80+0X44,line2); //第2行从第5个位置开始显示,/第2行显示
028B 019E MOVW R18,R28
028C 5F2E SUBI R18,0xFE
028D 4F3F SBCI R19,0xFF
028E EC04 LDI R16,0xC4
028F DE5C RCALL _LCD_write_string
0290 9666 ADIW R28,0x16
0291 940E02BF CALL pop_gset2
0293 9508 RET
_main:
dis_y --> Y+1
dis_x --> Y+1
shift --> Y+1
setdat --> Y+1
setadd --> Y+1
settime --> Y+7
gettime --> Y+0
0294 972E SBIW R28,0xE
(0293) }
(0294) /*******************************************
(0295) 函数名称: main
(0296) 功 能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
(0297) 参 数: 无
(0298) 返回值 : 无
(0299) /********************************************/
(0300) void main(void)
(0301) {
(0302)
(0303) uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器
(0304) //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
(0305) //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
(0306)
(0307) uchar dis_x,dis_y; //存储1602液晶当前光标的位置
(0308) uchar settime[7]={0x50,0x59,0x23,0x01,0x01,0x06,0x07};//设置的秒,分,时,日,月,星期,年
0295 E688 LDI R24,0x68
0296 E090 LDI R25,0
0297 01FE MOVW R30,R28
0298 9637 ADIW R30,7
0299 E007 LDI R16,7
029A E010 LDI R17,0
029B 93FA ST R31,-Y
029C 93EA ST R30,-Y
029D 939A ST R25,-Y
029E 938A ST R24,-Y
029F 940E02E4 CALL asgncblk
(0309) uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数
02A1 E68F LDI R24,0x6F
02A2 E090 LDI R25,0
02A3 01FE MOVW R30,R28
02A4 E007 LDI R16,7
02A5 E010 LDI R17,0
02A6 93FA ST R31,-Y
02A7 93EA ST R30,-Y
02A8 939A ST R25,-Y
02A9 938A ST R24,-Y
02AA 940E02E4 CALL asgncblk
(0310) //初始化液晶
(0311) DDRC=0xff;
02AC EF8F LDI R24,0xFF
02AD BB84 OUT 0x14,R24
(0312) PORTC=0x00;
02AE 2422 CLR R2
02AF BA25 OUT 0x15,R2
(0313) LCD_init();
02B0 DE5F RCALL _LCD_init
(0314)
(0315) DS1302_portinit(); //初始化DS1302的三根数据线
02B1 DEAF RCALL _DS1302_portinit
(0316) DS1302_init(); //启动振荡器,DS1302开始工作
02B2 DF5E RCALL _DS1302_init
(0317) DS1302_setT(settime); //设置初始时间
02B3 018E MOVW R16,R28
02B4 5F09 SUBI R16,0xF9
02B5 4F1F SBCI R17,0xFF
02B6 DF1D RCALL _DS1302_setT
02B7 C004 RJMP 0x02BC
(0318)
(0319) while(1) //以下程序完成显示和设置时间
(0320) {
(0321) DS1302_getT(gettime); //获得当前时间
02B8 018E MOVW R16,R28
02B9 DF3A RCALL _DS1302_getT
(0322) Disp_time(gettime); //显示当前时间
FILE: <library>
02BA 018E MOVW R16,R28
02BB DF6A RCALL _Disp_time
02BC CFFB RJMP 0x02B8
02BD 962E ADIW R28,0xE
02BE 9508 RET
pop_gset2:
02BF E0E2 LDI R30,2
02C0 940C02D1 JMP pop
pop_gset3:
02C2 E0E4 LDI R30,4
02C3 940C02D1 JMP pop
push_gset5:
02C5 92FA ST R15,-Y
02C6 92EA ST R14,-Y
push_gset4:
02C7 92DA ST R13,-Y
02C8 92CA ST R12,-Y
push_gset3:
02C9 92BA ST R11,-Y
02CA 92AA ST R10,-Y
push_gset2:
02CB 937A ST R23,-Y
02CC 936A ST R22,-Y
push_gset1:
02CD 935A ST R21,-Y
02CE 934A ST R20,-Y
02CF 9508 RET
pop_gset1:
02D0 E0E1 LDI R30,1
pop:
02D1 9149 LD R20,Y+
02D2 9159 LD R21,Y+
02D3 FDE0 SBRC R30,0
02D4 9508 RET
02D5 9169 LD R22,Y+
02D6 9179 LD R23,Y+
02D7 FDE1 SBRC R30,1
02D8 9508 RET
02D9 90A9 LD R10,Y+
02DA 90B9 LD R11,Y+
02DB FDE2 SBRC R30,2
02DC 9508 RET
02DD 90C9 LD R12,Y+
02DE 90D9 LD R13,Y+
02DF FDE3 SBRC R30,3
02E0 9508 RET
02E1 90E9 LD R14,Y+
02E2 90F9 LD R15,Y+
02E3 9508 RET
asgncblk:
02E4 93AA ST R26,-Y
02E5 93BA ST R27,-Y
02E6 93EA ST R30,-Y
02E7 93FA ST R31,-Y
02E8 920A ST R0,-Y
02E9 81AF LDD R26,Y+7
02EA 85B8 LDD R27,Y+8
02EB 81ED LDD R30,Y+5
02EC 81FE LDD R31,Y+6
02ED 3000 CPI R16,0
02EE 0701 CPC R16,R17
02EF F031 BEQ 0x02F6
02F0 95C8 LPM
02F1 920D ST R0,X+
02F2 9631 ADIW R30,1
02F3 5001 SUBI R16,1
02F4 4010 SBCI R17,0
02F5 CFF7 RJMP 0x02ED
02F6 9009 LD R0,Y+
02F7 91F9 LD R31,Y+
02F8 91E9 LD R30,Y+
02F9 91B9 LD R27,Y+
02FA 91A9 LD R26,Y+
02FB 9624 ADIW R28,4
02FC 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -