📄 ds1302.s
字号:
.dbline 138
mov R16,R20
xcall _DS1302_writeB
.dbline 139
cbi 0x18,7
.dbline 140
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 141
cbi 0x15,7
.dbline -2
.dbline 142
L60:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbsym r addr 22 c
.dbend
.dbfunc e DS1302_readD _DS1302_readD fc
; data -> R20
; addr -> R20
.even
_DS1302_readD::
xcall push_gset1
mov R20,R16
.dbline -1
.dbline 150
.dbline 152
cbi 0x15,7
.dbline 153
cbi 0x18,7
.dbline 154
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 155
sbi 0x15,7
.dbline 156
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 157
mov R16,R20
xcall _DS1302_writeB
.dbline 158
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 159
xcall _DS1302_readB
mov R20,R16
.dbline 160
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 161
cbi 0x18,7
.dbline 162
cbi 0x15,7
.dbline 163
mov R16,R20
.dbline -2
L61:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbsym r addr 20 c
.dbend
.dbfunc e DS1302_setT _DS1302_setT fV
; addr -> R20
; i -> R22
; ptTimeD -> R10,R11
.even
_DS1302_setT::
xcall push_gset3
movw R10,R16
.dbline -1
.dbline 172
.dbline 174
; uchar i;
; uchar addr = 0x80; //写入地址从秒寄存器开始
ldi R20,128
.dbline 175
; DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 176
; Delayms(5);
ldi R16,5
ldi R17,0
xcall _Delayms
.dbline 177
; for(i=0;i<7;i++)
clr R22
xjmp L66
L63:
.dbline 178
.dbline 179
mov R30,R22
clr R31
add R30,R10
adc R31,R11
ldd R18,z+0
mov R16,R20
xcall _DS1302_writeD
.dbline 180
subi R20,254 ; addi 2
.dbline 181
ldi R16,1
ldi R17,0
xcall _Delayms
.dbline 182
L64:
.dbline 177
inc R22
L66:
.dbline 177
cpi R22,7
brlo L63
.dbline 183
; {
; DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
; addr+=2;
; Delayms(1);
; }
; DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
ldi R18,128
ldi R16,142
xcall _DS1302_writeD
.dbline -2
.dbline 184
; }
L62:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r addr 20 c
.dbsym r i 22 c
.dbsym r ptTimeD 10 pc
.dbend
.dbfunc e DS1302_getT _DS1302_getT fV
; i -> R20
; time -> R22,R23
.even
_DS1302_getT::
xcall push_gset2
movw R22,R16
.dbline -1
.dbline 192
; /*******************************************
; 函数名称: DS1302_getT
; 功 能: 读取DS1302的当前时间
; 参 数: time[]--读取的时间数组
; 返回值 : 无
; /********************************************/
; void DS1302_getT(uchar time[])
; {
.dbline 203
; uchar i;
; ////////下面的是单次读写//////////////////////////
; /* uchar addr = 0x80; //读取地址从秒寄存器开始
; for(i=0;i<7;i++)
; {
; time[i]=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
; addr+=2;
; }*/
; ////////////////////////////////////////////////////
; /////////下面是多字节读取///////////////
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,7
.dbline 204
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 205
; PORTC|=BIT(RTC_CS); //拉高片选端
sbi 0x15,7
.dbline 206
; Delayus(10); //调整片选脉冲
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 207
; DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
ldi R16,191
xcall _DS1302_writeB
.dbline 208
; for (i=0;i<8;i++) //时间数据的存放格式是:
clr R20
xjmp L71
L68:
.dbline 209
.dbline 210
xcall _DS1302_readB
mov R30,R20
clr R31
add R30,R22
adc R31,R23
std z+0,R16
.dbline 211
L69:
.dbline 208
inc R20
L71:
.dbline 208
cpi R20,8
brlo L68
.dbline 213
; { //秒,分,时,日,月,星期,年,控制
; time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
; }
;
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,7
.dbline 215
; ///////////////////////////////////////////////
; PORTB&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
cbi 0x18,7
.dbline -2
.dbline 216
; }
L67:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r time 22 pc
.dbend
.dbfunc e DS1302_check _DS1302_check fc
; exist -> R20
.even
_DS1302_check::
xcall push_gset1
.dbline -1
.dbline 224
; /*******************************************
; 函数名称: DS1302_check
; 功 能: 检测DS1302是否正常工作
; 参 数: 无
; 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
; /********************************************/
; uchar DS1302_check(void)
; {
.dbline 226
; uchar exist;
; DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 227
; DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
ldi R18,165
ldi R16,192
xcall _DS1302_writeD
.dbline 228
; exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
ldi R16,193
xcall _DS1302_readD
mov R20,R16
.dbline 229
; if(exist==0xA5)
cpi R16,165
brne L73
.dbline 230
; {
.dbline 231
; exist=TRUE; //如果读取值与写入值相等,返回TRUE
ldi R20,1
.dbline 232
; }
xjmp L74
L73:
.dbline 234
; else
; {
.dbline 235
; exist=FALSE; //如果读取值与写入值不相等,返回FALSE
clr R20
.dbline 236
; }
L74:
.dbline 237
; return exist;
mov R16,R20
.dbline -2
L72:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r exist 20 c
.dbend
.dbfunc e DS1302_init _DS1302_init fV
.even
_DS1302_init::
.dbline -1
.dbline 246
; }
; /*******************************************
; 函数名称: DS1302_init
; 功 能: 初始化DS1302
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void DS1302_init(void)
; {
.dbline 247
; DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 248
; DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
clr R18
ldi R16,128
xcall _DS1302_writeD
.dbline 249
; DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
ldi R18,128
ldi R16,142
.dbline -2
.dbline 250
; }
L75:
.dbline 0 ; func end
xjmp _DS1302_writeD
.dbend
.dbfunc e BCD_ASCII _BCD_ASCII fV
; ptasc -> R20,R21
; BCD -> R22
.even
_BCD_ASCII::
xcall push_gset2
movw R20,R18
mov R22,R16
.dbline -1
.dbline 259
; /*******************************************
; 函数名称: BCD_ASCII
; 功 能: 将压缩BCD码转换成ascii码
; 参 数: BCD--将要转换的压缩BCD码
; ptasc--转换后的ASCII码数组指针
; 返回值 : 无
; /********************************************/
; void BCD_ASCII(uchar BCD,uchar ptasc[])
; {
.dbline 260
; ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
ldi R17,16
mov R16,R22
xcall div8u
mov R24,R16
ori R24,48
movw R30,R20
std z+0,R24
.dbline 261
; ptasc[1]=BCD&0x0F|0x30; //转换个位
mov R24,R22
andi R24,15
ori R24,48
std z+1,R24
.dbline -2
.dbline 262
; }
L76:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r ptasc 20 pc
.dbsym r BCD 22 c
.dbend
.area lit(rom, con, rel)
L78:
.byte 0,0
.byte 45,0
.byte 0,45
.byte 0,0
.byte 32,0
.byte 0
L79:
.byte 0,0
.byte 58,0
.byte 0,58
.byte 0,0
.byte 0
.area text(rom, con, rel)
.dbfile I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\ds1302.c
.dbfunc e Disp_time _Disp_time fV
; line1 -> y+11
; line2 -> y+2
; asc -> y+0
; i -> R20
; time -> R22,R23
.even
_Disp_time::
xcall push_gset2
movw R22,R16
sbiw R28,22
.dbline -1
.dbline 270
; /*******************************************
; 函数名称: Disp_time
; 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
; 参 数: time[]--时间数组
; 返回值 : 无
; /********************************************/
; void Disp_time(uchar time[])
; {
.dbline 272
; uchar i,asc[2];
; uchar line1[11]={0,0,'-',0,0,'-',0,0,' ',0,'\0'};//显示第1行的字符数组
ldi R24,<L78
ldi R25,>L78
movw R30,R28
adiw R30,11
ldi R16,11
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 273
; uchar line2[9]={0,0,':',0,0,':',0,0,'\0'}; //显示第2行的字符数组
ldi R24,<L79
ldi R25,>L79
movw R30,R28
adiw R30,2
ldi R16,9
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 274
; for(i=0;i<3;i++) //为第2行的字符数组赋值
clr R20
xjmp L83
L80:
.dbline 275
.dbline 276
movw R18,R28
mov R2,R20
clr R3
ldi R30,2
ldi R31,0
sub R30,R2
sbc R31,R3
add R30,R22
adc R31,R23
ldd R16,z+0
xcall _BCD_ASCII
.dbline 277
ldi R24,3
mul R24,R20
movw R30,R0
movw R24,R28
adiw R24,2
add R30,R24
adc R31,R25
ldd R2,y+0
std z+0,R2
.dbline 278
ldi R24,3
mul R24,R20
movw R30,R0
movw R24,R28
adiw R24,3
add R30,R24
adc R31,R25
ldd R2,y+1
std z+0,R2
.dbline 279
L81:
.dbline 274
inc R20
L83:
.dbline 274
cpi R20,3
brlo L80
.dbline 280
; {
; BCD_ASCII(time[2-i],asc);
; line2[i*3]=asc[0];
; line2[i*3+1]=asc[1];
; }
; BCD_ASCII(time[6],asc); //为第1行的年赋值
movw R18,R28
movw R30,R22
ldd R16,z+6
xcall _BCD_ASCII
.dbline 281
; line1[0]=asc[0];
ldd R2,y+0
std y+11,R2
.dbline 282
; line1[1]=asc[1];
ldd R2,y+1
std y+12,R2
.dbline 283
; BCD_ASCII(time[4],asc); //为第1行的月赋值
movw R18,R28
movw R30,R22
ldd R16,z+4
xcall _BCD_ASCII
.dbline 284
; line1[3]=asc[0];
ldd R2,y+0
std y+14,R2
.dbline 285
; line1[4]=asc[1];
ldd R2,y+1
std y+15,R2
.dbline 286
; BCD_ASCII(time[3],asc); //为第1行的日赋值
movw R18,R28
movw R30,R22
ldd R16,z+3
xcall _BCD_ASCII
.dbline 287
; line1[6]=asc[0];
ldd R2,y+0
std y+17,R2
.dbline 288
; line1[7]=asc[1];
ldd R2,y+1
std y+18,R2
.dbline 289
; BCD_ASCII(time[5],asc); //为第1行的星期赋值
movw R18,R28
movw R30,R22
ldd R16,z+5
xcall _BCD_ASCII
.dbline 290
; line1[9]=asc[1];
ldd R2,y+1
std y+20,R2
L96:
.dbline 292
L97:
.dbline 292
;
; while(LCD1602_readBF());
xcall _LCD1602_readBF
tst R16
brne L96
.dbline 293
; LCD1602_gotoXY(1,2); //第1行从第3个位置开始显示
ldi R18,2
ldi R16,1
xcall _LCD1602_gotoXY
.dbline 294
; LCD1602_sendstr("20"); //将07年显示为2007的形式
ldi R16,<L99
ldi R17,>L99
xcall _LCD1602_sendstr
.dbline 295
; LCD1602_sendstr(line1); //第1行显示
movw R16,R28
subi R16,245 ; offset = 11
sbci R17,255
xcall _LCD1602_sendstr
L100:
.dbline 296
L101:
.dbline 296
; while(LCD1602_readBF());
xcall _LCD1602_readBF
tst R16
brne L100
.dbline 297
; LCD1602_gotoXY(2,4); //第2行从第5个位置开始显示
ldi R18,4
ldi R16,2
xcall _LCD1602_gotoXY
.dbline 298
; LCD1602_sendstr(line2); //第2行显示
movw R16,R28
subi R16,254 ; offset = 2
sbci R17,255
xcall _LCD1602_sendstr
.dbline -2
.dbline 299
; }
L77:
adiw R28,22
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym l line1 11 A[11:11]c
.dbsym l line2 2 A[9:9]c
.dbsym l asc 0 A[2:2]c
.dbsym r i 20 c
.dbsym r time 22 pc
.dbend
.area lit(rom, con, rel)
L104:
.byte 'P,'Y
.byte 35,1
.byte 1,6
.byte 7
L105:
.byte 0,0
.byte 0,0
.byte 0,0
.byte 0
.area text(rom, con, rel)
.dbfile I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\ds1302.c
.dbfunc e main _main fV
; dis_y -> <dead>
; dis_x -> <dead>
; shift -> <dead>
; setdat -> <dead>
; setadd -> <dead>
; settime -> y+7
; gettime -> y+0
.even
_main::
sbiw R28,14
.dbline -1
.dbline 307
; /*******************************************
; 函数名称: main
; 功 能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void main(void)
; {
.dbline 314
;
;
; uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器
; //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
; //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
; uchar dis_x,dis_y; //存储1602液晶当前光标的位置
; uchar settime[7]={0x50,0x59,0x23,0x01,0x01,0x06,0x07};//设置的秒,分,时,日,月,星期,年
ldi R24,<L104
ldi R25,>L104
movw R30,R28
adiw R30,7
ldi R16,7
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 315
; uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数组
ldi R24,<L105
ldi R25,>L105
movw R30,R28
ldi R16,7
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 316
; LCD1602_initial(); //初始化1602液晶
xcall _LCD1602_initial
.dbline 317
; DS1302_portinit(); //初始化DS1302的三根数据线
xcall _DS1302_portinit
.dbline 318
; DS1302_init(); //启动振荡器,DS1302开始工作
xcall _DS1302_init
.dbline 319
; DS1302_setT(settime); //设置初始时间
movw R16,R28
subi R16,249 ; offset = 7
sbci R17,255
xcall _DS1302_setT
xjmp L107
L106:
.dbline 321
.dbline 322
movw R16,R28
xcall _DS1302_getT
.dbline 324
movw R16,R28
xcall _Disp_time
.dbline 325
L107:
.dbline 320
xjmp L106
X1:
.dbline -2
.dbline 326
; while(1) //以下程序完成显示和设置时间
; {
; DS1302_getT(gettime); //获得当前时间
;
; Disp_time(gettime); //显示当前时间
; }
; }
L103:
adiw R28,14
.dbline 0 ; func end
ret
.dbsym l dis_y 1 c
.dbsym l dis_x 1 c
.dbsym l shift 1 c
.dbsym l setdat 1 c
.dbsym l setadd 1 c
.dbsym l settime 7 A[7:7]c
.dbsym l gettime 0 A[7:7]c
.dbend
.area data(ram, con, rel)
.dbfile I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\ds1302.c
L99:
.blkb 3
.area idata
.byte 50,48,0
.area data(ram, con, rel)
.dbfile I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\ds1302.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -