📄 ds1302.s
字号:
.module DS1302.c
.area code(ram, con, rel)
.area lit(rom, con, rel)
_table::
.word 63
.word 6
.word 91
.word 79
.word 102
.word 109
.word 125
.word 7
.word 127
.word 111
.word 119
.word 124
.word 57
.word 94
.word 121
.word 113
.dbfile D:\卜凡涛单片机\卜凡涛做板\DS1302/xianshi.C
.dbsym e table _table A[32:16]kI
.area text(rom, con, rel)
.dbfile D:\卜凡涛单片机\卜凡涛做板\DS1302/xianshi.C
.dbfunc e delay _delay fV
; i -> R20,R21
; j -> R22,R23
; ms -> R16,R17
.even
_delay::
xcall push_gset2
.dbline -1
.dbline 9
; #include <iom16v.h> //包含型号头文件
; #include <macros.h> //包含"位"操作头文件
; #define uchar unsigned char
; #define uint unsigned int
;
; #define TRUE 1
; #define FALSE 0
; #include "xianshi.C" //包含1602液晶函数文件
;
.dbline 11
; /******************RTC常量******************/
; #define RTC_CLK PC7
clr R20
clr R21
xjmp L5
L2:
.dbline 12
; #define RTC_DATA PC6
.dbline 13
clr R22
clr R23
xjmp L9
L6:
.dbline 13
L7:
.dbline 13
subi R22,255 ; offset = 1
sbci R23,255
L9:
.dbline 13
cpi R22,117
ldi R30,4
cpc R23,R30
brlo L6
.dbline 14
L3:
.dbline 11
subi R20,255 ; offset = 1
sbci R21,255
L5:
.dbline 11
cp R20,R16
cpc R21,R17
brlo L2
.dbline -2
L1:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r j 22 i
.dbsym r ms 16 i
.dbend
.dbfunc e show _show fV
; j -> R20
; i -> R22
.even
_show::
xcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 17
; #define RTC_CS PC1
; //命令
; #define RD 0x01
; #define WR 0x00
; #define C_SEC 0x80 //秒
.dbline 17
ldi R24,255
out 0x17,R24
.dbline 18
; #define C_MIN 0x82 //分
ldi R24,60
out 0x11,R24
.dbline 19
; #define C_HR 0x84 //时
ldi R24,2
mul R24,R22
movw R30,R0
ldi R24,<_table
ldi R25,>_table
add R30,R24
adc R31,R25
lpm R0,Z+
lpm R1,Z
movw R30,R0
out 0x18,R30
.dbline 22
; #define C_DAY 0x86 //日
; #define C_MTH 0x88 //月
; #define C_WK 0x8A //星期 DATE
mov R17,R20
subi R17,254 ; addi 2
ldi R16,1
xcall lsl8
mov R2,R16
com R2
in R3,0x12
and R3,R2
out 0x12,R3
.dbline 23
; #define C_YR 0x8C //年
ldi R16,1
ldi R17,0
xcall _delay
.dbline -2
L10:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r j 20 c
.dbsym r i 22 c
.dbend
.dbfile D:\卜凡涛单片机\卜凡涛做板\DS1302\DS1302.c
.dbfunc e Delayus _Delayus fV
; i -> R20,R21
; US -> R22,R23
.even
_Delayus::
xcall push_gset2
movw R22,R16
.dbline -1
.dbline 41
; #define C_WP 0x8E //控制(写保护)
; #define C_CHARGE 0x90 //涓流充电
; #define C_BURST 0xBE //时钟多字节
; //配置
; #define CLK_HALT 0x80 //停止时钟控制位 SECOND bit7
; #define CLK_START 0x00 //启动时钟
; #define M12_24 0x80 //12/24小时值选择位 HOUR bit7
; #define PROTECT 0x80 //写保护控制位 CONTROL bit7
; #define UPROTECT 0x00 //写保护控制位 CONTROL bit7
; //涓流充电控制常量
; #define TC_D1R2 0xA5 //high 1 Diode +2K Resistors
; #define TC_D2R8 0xAB //low 2 Diodes+8K Resistors
; #define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00)
; //RAM 命令
; #define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位
;
; void Delayus(uint US)
; {
.dbline 43
; uint i;
; US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
ldi R16,5
ldi R17,0
movw R18,R22
xcall empy16s
movw R22,R16
lsr R23
ror R22
lsr R23
ror R22
.dbline 44
clr R20
clr R21
xjmp L15
L12:
.dbline 44
L13:
.dbline 44
subi R20,255 ; offset = 1
sbci R21,255
L15:
.dbline 44
; for( i=0;i<US;i++);
cp R20,R22
cpc R21,R23
brlo L12
.dbline -2
L11:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r US 22 i
.dbend
.dbfunc e Delayms _Delayms fV
; i -> R20,R21
; j -> R22,R23
; MS -> R16,R17
.even
_Delayms::
xcall push_gset2
.dbline -1
.dbline 47
; }
; void Delayms(uint MS)
; {
.dbline 49
; uint i,j;
; for( i=0;i<MS;i++)
clr R20
clr R21
xjmp L20
L17:
.dbline 50
clr R22
clr R23
xjmp L24
L21:
.dbline 50
L22:
.dbline 50
subi R22,255 ; offset = 1
sbci R23,255
L24:
.dbline 50
cpi R22,117
ldi R30,4
cpc R23,R30
brlo L21
L18:
.dbline 49
subi R20,255 ; offset = 1
sbci R21,255
L20:
.dbline 49
cp R20,R16
cpc R21,R17
brlo L17
.dbline -2
L16:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r j 22 i
.dbsym r MS 16 i
.dbend
.dbfunc e DS1302_portinit _DS1302_portinit fV
.even
_DS1302_portinit::
.dbline -1
.dbline 62
; for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
; }
;
;
;
; /*******************************************
; 函数名称: DS1302_init
; 功 能: 初始化DS1302的数据接口
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void DS1302_portinit(void)
; {
.dbline 63
; DDRC|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
in R24,0x14
ori R24,194
out 0x14,R24
.dbline -2
L25:
.dbline 0 ; func end
ret
.dbend
.dbfunc e DS1302_writeB _DS1302_writeB fV
; i -> R20
; byte -> R22
.even
_DS1302_writeB::
xcall push_gset2
mov R22,R16
.dbline -1
.dbline 72
; }
; /*******************************************
; 函数名称: DS1302_writeB
; 功 能: 向DS1302写入一个字节数据(没有RST操作)
; 参 数: byte--要写入的数据
; 返回值 : 无
; /********************************************/
; void DS1302_writeB(uchar byte)
; {
.dbline 74
; uchar i;
; for(i=0;i<8;i++) //8位数据计数
clr R20
xjmp L30
L27:
.dbline 75
; {
.dbline 76
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 77
; if(byte&0x01) //当前位是否是1
sbrs R22,0
rjmp L31
.dbline 78
; {
.dbline 79
; PORTC|=BIT(RTC_DATA); //当前位是1,拉高数据端
sbi 0x15,6
.dbline 80
; }
xjmp L32
L31:
.dbline 82
; else
; {
.dbline 83
; PORTC&=~BIT(RTC_DATA); //当前位是0,拉低数据端
cbi 0x15,6
.dbline 84
; }
L32:
.dbline 85
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 86
sbi 0x15,7
.dbline 87
lsr R22
.dbline 88
L28:
.dbline 74
inc R20
L30:
.dbline 74
cpi R20,8
brlo L27
.dbline -2
L26:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r byte 22 c
.dbend
.dbfunc e DS1302_readB _DS1302_readB fc
; i -> R20
; byte -> R22
.even
_DS1302_readB::
xcall push_gset2
.dbline -1
.dbline 97
; Delayus(10); //调整时钟和脉冲宽度
; PORTC|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)
; byte>>=1; //数据右移1位,为送出新数据位做准备
; }
; }
; /*******************************************
; 函数名称: DS1302_readB
; 功 能: 从DS1302读出一个字节数据(没有RST操作)
; 参 数: 无
; 返回值 : byte--读出的数据
; /********************************************/
; uchar DS1302_readB(void)
; {
.dbline 98
; uchar i,byte=0;
clr R22
.dbline 99
; DDRC&=~BIT(RTC_DATA); //将数据端口设置为输入
cbi 0x14,6
.dbline 100
; PORTC&=~BIT(RTC_DATA); //无上拉电阻
cbi 0x15,6
.dbline 101
; for(i=0;i<8;i++) //8位数据计数
clr R20
xjmp L37
L34:
.dbline 102
; {
.dbline 103
; byte>>=1; //保存读入的数据位
lsr R22
.dbline 104
; PORTC|=BIT(RTC_CLK); //时钟上升沿
sbi 0x15,7
.dbline 105
; Delayus(10); //延时,调整时钟脉冲宽度
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 106
; PORTC&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位
cbi 0x15,7
.dbline 107
; Delayus(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 108
; if(PINC&BIT(RTC_DATA)) //当前位是否是高电平
sbis 0x13,6
rjmp L38
.dbline 109
; {
.dbline 110
; byte|=BIT(PC7); //是高电平就将返回数据的当前位置1
ori R22,128
.dbline 111
; }
xjmp L39
L38:
.dbline 113
; else
; {
.dbline 114
; byte&=~BIT(PC7); //是低电平就将返回数据的当前位置0
andi R22,127
.dbline 115
; }
L39:
.dbline 116
L35:
.dbline 101
inc R20
L37:
.dbline 101
cpi R20,8
brlo L34
.dbline 117
; }
; DDRC|=BIT(RTC_DATA); //最后将数据端口设置为输出
sbi 0x14,6
.dbline 119
;
; byte=byte/16*10+byte%16; //BCD码转为二进制
ldi R17,16
mov R16,R22
xcall mod8u
mov R24,R22
swap R24
andi R24,#0x0F
ldi R25,10
mul R25,R24
mov R22,R0
add R22,R16
.dbline 121
;
; return byte; //返回读出的数据
mov R16,R22
.dbline -2
L33:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r byte 22 c
.dbend
.dbfunc e DS1302_writeD _DS1302_writeD fV
; data -> R20
; addr -> R22
.even
_DS1302_writeD::
xcall push_gset2
mov R20,R18
mov R22,R16
.dbline -1
.dbline 131
; }
; /*******************************************
; 函数名称: DS1302_writeD
; 功 能: 向DS1302的某个地址写入一个字节数据
; 参 数: addr--地址值(寄存器或RAM)
; data--要写入的地址
; 返回值 : 无
; /********************************************/
; void DS1302_writeD(uchar addr,uchar data)
; {
.dbline 132
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline 133
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 134
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 135
; PORTC|=BIT(RTC_CS); //拉高片选端
sbi 0x15,1
.dbline 136
; Delayus(10); //调整片选脉冲
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 137
; DS1302_writeB(addr); //写入操作命令(地址)
mov R16,R22
xcall _DS1302_writeB
.dbline 138
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 139
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 140
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 141
; DS1302_writeB(data); //写入数据
mov R16,R20
xcall _DS1302_writeB
.dbline 142
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 143
; Delayus(10); //调整片选脉冲
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 144
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline -2
L40:
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 153
; }
; /*******************************************
; 函数名称: DS1302_readD
; 功 能: 从DS1302的某个地址读出一个字节数据
; 参 数: addr--地址值(寄存器或RAM)
; 返回值 : data--读出的数据
; /********************************************/
; uchar DS1302_readD(uchar addr)
; {
.dbline 155
; uchar data;
; PORTC&=~BIT(RTC_CS); //拉低片选端
cbi 0x15,1
.dbline 156
; PORTC&=~BIT(RTC_CLK); //拉低时钟端
cbi 0x15,7
.dbline 157
; Delayus(10);
ldi R16,10
ldi R17,0
xcall _Delayus
.dbline 158
; PORTC|=BIT(RTC_CS); //拉高片选端
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -