📄 ds1302.s
字号:
sbi 0x15,1
.dbline 159
; Delayus(10); //调整片选脉冲
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 160
; DS1302_writeB(addr); //写入操作命令(地址)
mov R16,R20
xcall _DS1302_writeB
.dbline 161
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 162
; data=DS1302_readB(); //读出数据
xcall _DS1302_readB
mov R20,R16
.dbline 163
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 164
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 165
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline 166
; return data; //返回读出的数据
mov R16,R20
.dbline -2
L41:
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 175
; }
; /*******************************************
; 函数名称: DS1302_setT
; 功 能: 设置DS1302的时间
; 参 数: ptTimeD--设置时间数组指针
; 返回值 : 无
; /********************************************/
; void DS1302_setT(uchar ptTimeD[])
; {
.dbline 177
; uchar i;
; uchar addr = 0x80; //写入地址从秒寄存器开始
ldi R20,128
.dbline 178
; DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 179
; Delayms(5);
ldi R16,5
ldi R17,0
xcall _Delayms
.dbline 180
; for(i=0;i<2;i++)
clr R22
xjmp L46
L43:
.dbline 181
.dbline 182
mov R30,R22
clr R31
add R30,R10
adc R31,R11
ldd R18,z+0
mov R16,R20
xcall _DS1302_writeD
.dbline 183
subi R20,254 ; addi 2
.dbline 184
ldi R16,1
ldi R17,0
xcall _Delayms
.dbline 185
L44:
.dbline 180
inc R22
L46:
.dbline 180
cpi R22,2
brlo L43
.dbline 186
; {
; 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
L42:
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 195
; }
; /*******************************************
; 函数名称: DS1302_getT
; 功 能: 读取DS1302的当前时间
; 参 数: time[]--读取的时间数组
; 返回值 : 无
; /********************************************/
; void DS1302_getT(uchar time[])
; {
.dbline 197
; uchar i;
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline 198
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 199
; PORTC|=BIT(RTC_CS); //拉高片选端
sbi 0x15,1
.dbline 200
; Delayus(10); //调整片选脉冲
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 201
; DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令
ldi R16,191
xcall _DS1302_writeB
.dbline 202
; for (i=0;i<2;i++) //时间数据的存放格式是:
clr R20
xjmp L51
L48:
.dbline 203
.dbline 204
xcall _DS1302_readB
mov R30,R20
clr R31
add R30,R22
adc R31,R23
std z+0,R16
.dbline 205
L49:
.dbline 202
inc R20
L51:
.dbline 202
cpi R20,2
brlo L48
.dbline 207
; { //秒,分,时,日,月,星期,年,控制
; time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
; }
;
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline 208
; PORTC&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)
cbi 0x15,7
.dbline -2
L47:
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 217
; }
; /*******************************************
; 函数名称: DS1302_check
; 功 能: 检测DS1302是否正常工作
; 参 数: 无
; 返回值 : exist--为TRUE为检测到DS1302,为FALSE为没检测到
; /********************************************/
; uchar DS1302_check(void)
; {
.dbline 219
; uchar exist;
; DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 220
; DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5
ldi R18,165
ldi R16,192
xcall _DS1302_writeD
.dbline 221
; exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0
ldi R16,193
xcall _DS1302_readD
mov R20,R16
.dbline 222
; if(exist==0xA5)
cpi R16,165
brne L53
.dbline 223
; {
.dbline 224
; exist=TRUE; //如果读取值与写入值相等,返回TRUE
ldi R20,1
.dbline 225
; }
xjmp L54
L53:
.dbline 227
; else
; {
.dbline 228
; exist=FALSE; //如果读取值与写入值不相等,返回FALSE
clr R20
.dbline 229
; }
L54:
.dbline 230
; return exist;
mov R16,R20
.dbline -2
L52:
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 239
; }
; /*******************************************
; 函数名称: DS1302_init
; 功 能: 初始化DS1302
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void DS1302_init(void)
; {
.dbline 240
; DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令
clr R18
ldi R16,142
xcall _DS1302_writeD
.dbline 241
; DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作
clr R18
ldi R16,128
xcall _DS1302_writeD
.dbline 242
; DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
ldi R18,128
ldi R16,142
xcall _DS1302_writeD
.dbline -2
L55:
.dbline 0 ; func end
ret
.dbend
.dbfunc e BCD_ASCII _BCD_ASCII fV
; ptasc -> R18,R19
; BCD -> R16
.even
_BCD_ASCII::
.dbline -1
.dbline 252
; }
; /*******************************************
; 函数名称: BCD_ASCII
; 功 能: 将压缩BCD码转换成ascii码
; 参 数: BCD--将要转换的压缩BCD码
; ptasc--转换后的ASCII码数组指针
; 返回值 : 无
; /********************************************/
; void BCD_ASCII(uchar BCD,uchar ptasc[])
; {
.dbline 253
; ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位
mov R24,R16
swap R24
andi R24,#0x0F
ori R24,48
movw R30,R18
std z+0,R24
.dbline 254
; ptasc[1]=BCD&0x0F|0x30; //转换个位
mov R24,R16
andi R24,15
ori R24,48
std z+1,R24
.dbline -2
L56:
.dbline 0 ; func end
ret
.dbsym r ptasc 18 pc
.dbsym r BCD 16 c
.dbend
.dbfunc e Disp_time _Disp_time fV
; dm -> y+0
; n -> R20
; m -> R22
; i -> R10
; time -> R20,R21
.even
_Disp_time::
xcall push_gset3
movw R20,R16
sbiw R28,8
.dbline -1
.dbline 263
; }
; /*******************************************
; 函数名称: Disp_time
; 功 能: 在1602液晶上显示当前时间(第1行格式:年-月-日 星期;第2行格式:时-分-秒)
; 参 数: time[]--时间数组
; 返回值 : 无
; /********************************************/
; void Disp_time(uchar time[])
; { uint dm[4];
.dbline 267
; uchar i,m,n;
;
;
; m=(uint)time[0];
movw R30,R20
ldd R22,z+0
.dbline 268
; n=(uint)time[1];
ldd R20,z+1
.dbline 270
;
; for(i=1;i<3;i++)
clr R10
inc R10
xjmp L61
L58:
.dbline 271
.dbline 271
ldi R17,4
sub R17,R10
ldi R16,2
muls R16,R17
movw R30,R0
movw R24,R28
add R30,R24
adc R31,R25
ldi R18,10
ldi R19,0
mov R16,R22
clr R17
xcall mod16s
std z+1,R17
std z+0,R16
.dbline 272
ldi R17,10
mov R16,R22
xcall div8u
mov R22,R16
.dbline 273
L59:
.dbline 270
inc R10
L61:
.dbline 270
mov R24,R10
cpi R24,3
brlo L58
.dbline 274
; { dm[4-i]=m%10;
; m=m/10;
; }
; for(i=3;i<5;i++)
ldi R24,3
mov R10,R24
xjmp L65
L62:
.dbline 275
.dbline 275
ldi R17,4
sub R17,R10
ldi R16,2
muls R16,R17
movw R30,R0
movw R24,R28
add R30,R24
adc R31,R25
ldi R18,10
ldi R19,0
mov R16,R20
clr R17
xcall mod16s
std z+1,R17
std z+0,R16
.dbline 276
ldi R17,10
mov R16,R20
xcall div8u
mov R20,R16
.dbline 277
L63:
.dbline 274
inc R10
L65:
.dbline 274
mov R24,R10
cpi R24,5
brlo L62
.dbline 278
; { dm[4-i]=n%10;
; n=n/10;
; }
; for(i=0;i<4;i++)
clr R10
xjmp L69
L66:
.dbline 279
.dbline 279
mov R18,R10
ldi R24,2
mul R24,R10
movw R30,R0
movw R24,R28
add R30,R24
adc R31,R25
ldd R16,z+0
xcall _show
.dbline 281
ldi R24,255
out 0x12,R24
.dbline 282
L67:
.dbline 278
inc R10
L69:
.dbline 278
mov R24,R10
cpi R24,4
brlo L66
.dbline -2
L57:
adiw R28,8
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym l dm 0 A[8:4]i
.dbsym r n 20 c
.dbsym r m 22 c
.dbsym r i 10 c
.dbsym r time 20 pc
.dbend
.area lit(rom, con, rel)
L71:
.byte 'Y,'P
L72:
.byte 0,0
.area text(rom, con, rel)
.dbfile D:\卜凡涛单片机\卜凡涛做板\DS1302\DS1302.c
.dbfunc e main _main fV
; shift -> <dead>
; setdat -> <dead>
; setadd -> <dead>
; settime -> y+2
; gettime -> y+0
.even
_main::
sbiw R28,4
.dbline -1
.dbline 294
; { show(dm[i],i);
;
; PORTD=0XFF;
; }
;
;
;
; }
; /*******************************************
; 函数名称: main
; 功 能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void main(void)
; {
.dbline 301
;
;
; uchar setadd,setdat,shift; //setadd指定将当前数值送入DS1302的哪个寄存器
; //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
; //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
; //uchar dis_x,dis_y; //存储1602液晶当前光标的位置
; uchar settime[2]={0X59,0X50};//设置的秒,分,时,日,月,星期,年
ldi R24,<L71
ldi R25,>L71
movw R30,R28
adiw R30,2
ldi R16,2
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 302
; uchar gettime[2]={0X00,0X00};//保存当前时间的数组
ldi R24,<L72
ldi R25,>L72
movw R30,R28
ldi R16,2
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
.dbline 304
; //LCD1602_initial(); //初始化1602液晶
; DS1302_portinit(); //初始化DS1302的三根数据线
xcall _DS1302_portinit
.dbline 305
; DS1302_init(); //启动振荡器,DS1302开始工作
xcall _DS1302_init
.dbline 306
; DS1302_setT(settime); //设置初始时间
movw R16,R28
subi R16,254 ; offset = 2
sbci R17,255
xcall _DS1302_setT
xjmp L74
L73:
.dbline 310
.dbline 311
movw R16,R28
xcall _DS1302_getT
.dbline 313
movw R16,R28
xcall _Disp_time
.dbline 314
L74:
.dbline 309
xjmp L73
X0:
.dbline -2
L70:
adiw R28,4
.dbline 0 ; func end
ret
.dbsym l shift 1 c
.dbsym l setdat 1 c
.dbsym l setadd 1 c
.dbsym l settime 2 A[2:2]c
.dbsym l gettime 0 A[2:2]c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -