📄 ds1302.lst
字号:
__text_start:
__start:
2F E5CF LDI R28,0x5F
30 E0D4 LDI R29,4
31 BFCD OUT 0x3D,R28
32 BFDE OUT 0x3E,R29
33 51CE SUBI R28,0x1E
34 40D0 SBCI R29,0
35 EA0A LDI R16,0xAA
36 8308 STD Y+0,R16
37 2400 CLR R0
38 E6E9 LDI R30,0x69
39 E0F0 LDI R31,0
3A E010 LDI R17,0
3B 36E9 CPI R30,0x69
3C 07F1 CPC R31,R17
3D F011 BEQ 0x0040
3E 9201 ST R0,Z+
3F CFFB RJMP 0x003B
40 8300 STD Z+0,R16
41 E5E4 LDI R30,0x54
42 E0F0 LDI R31,0
43 E6A0 LDI R26,0x60
44 E0B0 LDI R27,0
45 E010 LDI R17,0
46 E000 LDI R16,0
47 BF0B OUT 0x3B,R16
48 35ED CPI R30,0x5D
49 07F1 CPC R31,R17
4A F021 BEQ 0x004F
4B 95C8 LPM
4C 9631 ADIW R30,1
4D 920D ST R0,X+
4E CFF9 RJMP 0x0048
4F 940E 02A7 CALL _main
_exit:
51 CFFF RJMP _exit
_ds1302_write_byte:
i --> R20
d --> R18
addr --> R16
52 934A ST R20,-Y
FILE: E:\16实验程序\ds1302\ds1302.h
(0001)
(0002) #include "iom16v.h"
(0003)
(0004) //复位脚
(0005) #define RST_CLR PORTC &= ~(1 << PC6)
(0006) #define RST_SET PORTC |= (1 << PC6)
(0007) #define RST_IN DDRC &= ~(1 << PC6)
(0008) #define RST_OUT DDRC |= (1 << PC6)
(0009)
(0010) //双向数据
(0011) #define IO_CLR PORTC &= ~(1 << PC1)
(0012) #define IO_SET PORTC |= (1 << PC1)
(0013) #define IO_R PINC & (1 << PC1)
(0014) #define IO_IN DDRC &= ~(1 << PC1)
(0015) #define IO_OUT DDRC |= (1 << PC1)
(0016)
(0017) //时钟信号
(0018) #define SCK_CLR PORTC &= ~(1 << PC0)
(0019) #define SCK_SET PORTC |= (1 << PC0)
(0020) #define SCK_IN DDRC &= ~(1 << PC0)
(0021) #define SCK_OUT DDRC |= (1 << PC0)
(0022)
(0023) #define ds1302_sec_add 0x80
(0024) #define ds1302_min_add 0x82
(0025) #define ds1302_hr_add 0x84
(0026) #define ds1302_date_add 0x86
(0027) #define ds1302_month_add 0x88
(0028) #define ds1302_day_add 0x8a
(0029) #define ds1302_year_add 0x8c
(0030) #define ds1302_control_add 0x8e
(0031) #define ds1302_charger_add 0x90
(0032) #define ds1302_clkburst_add 0xbe
(0033)
(0034)
(0035)
(0036) //向DS1302写入一字节数据
(0037) void ds1302_write_byte(unsigned char addr, unsigned char d) {
(0038)
(0039) unsigned char i;
(0040) RST_SET; //启动DS1302总线
53 9AAE SBI 0x15,6
(0041)
(0042) //写入目标地址:addr
(0043) IO_OUT;
54 9AA1 SBI 0x14,1
(0044) addr = addr & 0xFE;//最低位置零
55 7F0E ANDI R16,0xFE
(0045) for (i = 0; i < 8; i ++) {
56 2744 CLR R20
57 C009 RJMP 0x0061
(0046) if (addr & 0x01) {
58 FF00 SBRS R16,0
59 C002 RJMP 0x005C
(0047) IO_SET;
5A 9AA9 SBI 0x15,1
(0048) }
5B C001 RJMP 0x005D
(0049) else {
(0050) IO_CLR;
5C 98A9 CBI 0x15,1
(0051) }
(0052) SCK_SET;
5D 9AA8 SBI 0x15,0
(0053) SCK_CLR;
5E 98A8 CBI 0x15,0
(0054) addr = addr >> 1;
5F 9506 LSR R16
60 9543 INC R20
61 3048 CPI R20,0x8
62 F3A8 BCS 0x0058
(0055) }
(0056)
(0057) //写入数据
(0058) IO_OUT;
63 9AA1 SBI 0x14,1
(0059) for (i = 0; i < 8; i ++) {
64 2744 CLR R20
65 C009 RJMP 0x006F
(0060) if (d & 0x01) {
66 FF20 SBRS R18,0
67 C002 RJMP 0x006A
(0061) IO_SET;
68 9AA9 SBI 0x15,1
(0062) }
69 C001 RJMP 0x006B
(0063) else {
(0064) IO_CLR;
6A 98A9 CBI 0x15,1
(0065) }
(0066) SCK_SET;
6B 9AA8 SBI 0x15,0
(0067) SCK_CLR;
6C 98A8 CBI 0x15,0
(0068) d = d >> 1;
6D 9526 LSR R18
6E 9543 INC R20
6F 3048 CPI R20,0x8
70 F3A8 BCS 0x0066
(0069) }
(0070) RST_CLR; //禁止DS1302总线
71 98AE CBI 0x15,6
72 9149 LD R20,Y+
73 9508 RET
_ds1302_read_byte:
temp --> R20
i --> R22
addr --> R16
74 934A ST R20,-Y
75 936A ST R22,-Y
(0071) }
(0072)
(0073) //读出一个字节
(0074) unsigned char ds1302_read_byte(unsigned char addr) {
(0075)
(0076) unsigned char i;
(0077) unsigned char temp;
(0078) RST_SET; //启动DS1302总线
76 9AAE SBI 0x15,6
(0079)
(0080) //写入目标地址:addr
(0081) IO_OUT;
77 9AA1 SBI 0x14,1
(0082) addr = addr | 0x01; //最低位置高
78 6001 ORI R16,1
(0083) for (i = 0; i < 8; i ++) {
79 2766 CLR R22
7A C009 RJMP 0x0084
(0084) if (addr & 0x01) {
7B FF00 SBRS R16,0
7C C002 RJMP 0x007F
(0085) IO_SET;
7D 9AA9 SBI 0x15,1
(0086) }
7E C001 RJMP 0x0080
(0087) else {
(0088) IO_CLR;
7F 98A9 CBI 0x15,1
(0089) }
(0090) SCK_SET;
80 9AA8 SBI 0x15,0
(0091) SCK_CLR;
81 98A8 CBI 0x15,0
(0092) addr = addr >> 1;
82 9506 LSR R16
83 9563 INC R22
84 3068 CPI R22,0x8
85 F3A8 BCS 0x007B
(0093) }
(0094)
(0095) //输出数据
(0096) IO_IN;
86 98A1 CBI 0x14,1
(0097) for (i = 0; i < 8; i ++) {
87 2766 CLR R22
88 C009 RJMP 0x0092
(0098) temp = temp >> 1;
89 9546 LSR R20
(0099) if (IO_R) {
8A 9B99 SBIS 0x13,1
8B C002 RJMP 0x008E
(0100) temp |= 0x80;
8C 6840 ORI R20,0x80
(0101) }
8D C001 RJMP 0x008F
(0102) else {
(0103) temp &= 0x7F;
8E 774F ANDI R20,0x7F
(0104) }
(0105) SCK_SET;
8F 9AA8 SBI 0x15,0
(0106) SCK_CLR;
90 98A8 CBI 0x15,0
91 9563 INC R22
92 3068 CPI R22,0x8
93 F3A8 BCS 0x0089
(0107) }
(0108)
(0109) RST_CLR; //禁止DS1302总线
94 98AE CBI 0x15,6
(0110) return temp;
95 2F04 MOV R16,R20
96 9169 LD R22,Y+
97 9149 LD R20,Y+
98 9508 RET
_ds1302_write_time:
time_data --> R20
99 934A ST R20,-Y
9A 935A ST R21,-Y
9B 01A8 MOVW R20,R16
(0111) }
(0112)
(0113) //写入时钟数据
(0114) void ds1302_write_time(unsigned char *time_data)
(0115) {
(0116)
(0117) ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
9C 2722 CLR R18
9D E80E LDI R16,0x8E
9E DFB3 RCALL _ds1302_write_byte
(0118) ds1302_write_byte(ds1302_sec_add,0x80); //暂停
9F E820 LDI R18,0x80
A0 E800 LDI R16,0x80
A1 DFB0 RCALL _ds1302_write_byte
(0119) time_data++;
A2 5F4F SUBI R20,0xFF
A3 4F5F SBCI R21,0xFF
(0120) ds1302_write_byte(ds1302_year_add,*time_data++); //只写入后面两位 08
A4 01FA MOVW R30,R20
A5 9121 LD R18,Z+
A6 01AF MOVW R20,R30
A7 E80C LDI R16,0x8C
A8 DFA9 RCALL _ds1302_write_byte
(0121) ds1302_write_byte(ds1302_month_add,*time_data++); //月
A9 01FA MOVW R30,R20
AA 9121 LD R18,Z+
AB 01AF MOVW R20,R30
AC E808 LDI R16,0x88
AD DFA4 RCALL _ds1302_write_byte
(0122) ds1302_write_byte(ds1302_date_add,*time_data++); //日
AE 01FA MOVW R30,R20
AF 9121 LD R18,Z+
B0 01AF MOVW R20,R30
B1 E806 LDI R16,0x86
B2 DF9F RCALL _ds1302_write_byte
(0123) ds1302_write_byte(ds1302_hr_add,*time_data++); //时
B3 01FA MOVW R30,R20
B4 9121 LD R18,Z+
B5 01AF MOVW R20,R30
B6 E804 LDI R16,0x84
B7 DF9A RCALL _ds1302_write_byte
(0124) ds1302_write_byte(ds1302_min_add,*time_data++); //分
B8 01FA MOVW R30,R20
B9 9121 LD R18,Z+
BA 01AF MOVW R20,R30
BB E802 LDI R16,0x82
BC DF95 RCALL _ds1302_write_byte
(0125) ds1302_write_byte(ds1302_sec_add,*time_data++); //秒
BD 01FA MOVW R30,R20
BE 9121 LD R18,Z+
BF 01AF MOVW R20,R30
C0 E800 LDI R16,0x80
C1 DF90 RCALL _ds1302_write_byte
(0126) ds1302_write_byte(ds1302_day_add,*time_data); //周
C2 01FA MOVW R30,R20
C3 8120 LDD R18,Z+0
C4 E80A LDI R16,0x8A
C5 DF8C RCALL _ds1302_write_byte
(0127) ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
C6 E820 LDI R18,0x80
C7 E80E LDI R16,0x8E
C8 DF89 RCALL _ds1302_write_byte
C9 9159 LD R21,Y+
CA 9149 LD R20,Y+
CB 9508 RET
_ds1302_read_time:
time_data --> R20
CC 940E 03A0 CALL push_xgsetF00C
CE 01A8 MOVW R20,R16
(0128) }
(0129)
(0130) //读出时钟数据
(0131) void ds1302_read_time(unsigned char *time_data) {
(0132) time_data++;
CF 5F4F SUBI R20,0xFF
D0 4F5F SBCI R21,0xFF
(0133) *time_data=ds1302_read_byte(ds1302_year_add); //只读出后面两位08
D1 E80C LDI R16,0x8C
D2 DFA1 RCALL _ds1302_read_byte
D3 01FA MOVW R30,R20
D4 8300 STD Z+0,R16
(0134) time_data++;
D5 5F4F SUBI R20,0xFF
D6 4F5F SBCI R21,0xFF
(0135) *time_data=ds1302_read_byte(ds1302_month_add); //月
D7 E808 LDI R16,0x88
D8 DF9B RCALL _ds1302_read_byte
D9 01FA MOVW R30,R20
DA 8300 STD Z+0,R16
(0136) time_data++;
DB 5F4F SUBI R20,0xFF
DC 4F5F SBCI R21,0xFF
(0137) *time_data=ds1302_read_byte(ds1302_date_add); //日
DD E806 LDI R16,0x86
DE DF95 RCALL _ds1302_read_byte
DF 2EA0 MOV R10,R16
E0 01FA MOVW R30,R20
E1 82A0 STD Z+0,R10
(0138) time_data++;
E2 5F4F SUBI R20,0xFF
E3 4F5F SBCI R21,0xFF
(0139) *time_data=ds1302_read_byte(ds1302_hr_add); //时
E4 E804 LDI R16,0x84
E5 DF8E RCALL _ds1302_read_byte
E6 2EA0 MOV R10,R16
E7 01FA MOVW R30,R20
E8 82A0 STD Z+0,R10
(0140) time_data++;
E9 5F4F SUBI R20,0xFF
EA 4F5F SBCI R21,0xFF
(0141) *time_data=ds1302_read_byte(ds1302_min_add); //分
EB E802 LDI R16,0x82
EC DF87 RCALL _ds1302_read_byte
ED 2EA0 MOV R10,R16
EE 01FA MOVW R30,R20
EF 82A0 STD Z+0,R10
(0142) time_data++;
F0 5F4F SUBI R20,0xFF
F1 4F5F SBCI R21,0xFF
(0143) *time_data=(ds1302_read_byte(ds1302_sec_add))&0x7F; //秒
F2 E800 LDI R16,0x80
F3 DF80 RCALL _ds1302_read_byte
F4 2F60 MOV R22,R16
F5 2F86 MOV R24,R22
F6 778F ANDI R24,0x7F
F7 01FA MOVW R30,R20
F8 8380 STD Z+0,R24
(0144) time_data++;
F9 5F4F SUBI R20,0xFF
FA 4F5F SBCI R21,0xFF
(0145) *time_data=ds1302_read_byte(ds1302_day_add); //周
FB E80A LDI R16,0x8A
FC DF77 RCALL _ds1302_read_byte
FD 2EA0 MOV R10,R16
FE 01FA MOVW R30,R20
FF 82A0 STD Z+0,R10
100 940C 03A7 JMP pop_xgsetF00C
(0146) }
(0147)
(0148) //初始化
(0149) void ds1302_init(void) {
(0150)
(0151) RST_CLR;
_ds1302_init:
102 98AE CBI 0x15,6
(0152) SCK_CLR;
103 98A8 CBI 0x15,0
(0153) RST_OUT;
104 9AA6 SBI 0x14,6
(0154) SCK_OUT;
105 9AA0 SBI 0x14,0
106 9508 RET
FILE: E:\16实验程序\ds1302\1602.h
(0001) #define uchar unsigned char
(0002) #define uint unsigned int
(0003)
(0004) #define RS 5
(0005) #define RW 6
(0006) #define EN 7
(0007)
(0008) void s_ms(uint ms)
(0009) {
(0010) for(;ms>1;ms--);
_s_ms:
ms --> R16
107 C002 RJMP 0x010A
108 5001 SUBI R16,1
109 4010 SBCI R17,0
10A E081 LDI R24,1
10B E090 LDI R25,0
10C 1780 CP R24,R16
10D 0791 CPC R25,R17
10E F3C8 BCS 0x0108
10F 9508 RET
_busy:
temp --> R20
110 934A ST R20,-Y
(0011) }
(0012)
(0013) //查忙
(0014) void busy(void)
(0015) {
(0016) uchar temp;
(0017) s_ms(500);
111 EF04 LDI R16,0xF4
112 E011 LDI R17,1
113 DFF3 RCALL _s_ms
(0018) PORTA&=~(1<<RS); //RS=0
114 98DD CBI 0x1B,5
(0019) s_ms(500);
115 EF04 LDI R16,0xF4
116 E011 LDI R17,1
117 DFEF RCALL _s_ms
(0020) PORTA|=(1<<RW); //RW=1
118 9ADE SBI 0x1B,6
(0021) s_ms(500);
119 EF04 LDI R16,0xF4
11A E011 LDI R17,1
11B DFEB RCALL _s_ms
11C C01A RJMP 0x0137
(0022) while(temp)
(0023) {
(0024) PORTA|=(1<<EN); //EN=1
11D 9ADF SBI 0x1B,7
(0025) s_ms(500);
11E EF04 LDI R16,0xF4
11F E011 LDI R17,1
120 DFE6 RCALL _s_ms
(0026) DDRD=0x00; //A口变输入
121 2422 CLR R2
122 BA21 OUT 0x11,R2
(0027) PORTD=0xff; //上拉使能
123 EF8F LDI R24,0xFF
124 BB82 OUT 0x12,R24
(0028) s_ms(500);
125 EF04 LDI R16,0xF4
126 E011 LDI R17,1
127 DFDF RCALL _s_ms
(0029) temp = PIND&0x80; //读取A口
128 B340 IN R20,0x10
129 7840 ANDI R20,0x80
(0030) s_ms(500);
12A EF04 LDI R16,0xF4
12B E011 LDI R17,1
12C DFDA RCALL _s_ms
(0031) DDRD=0xff;
12D EF8F LDI R24,0xFF
12E BB81 OUT 0x11,R24
(0032) PORTD=0xff; //A口变输出
12F BB82 OUT 0x12,R24
(0033) s_ms(500);
130 EF04 LDI R16,0xF4
131 E011 LDI R17,1
132 DFD4 RCALL _s_ms
(0034) PORTA&=~(1<<EN); //EN=0
133 98DF CBI 0x1B,7
(0035) s_ms(500);
134 EF04 LDI R16,0xF4
135 E011 LDI R17,1
136 DFD0 RCALL _s_ms
137 2344 TST R20
138 F721 BNE 0x011D
139 9149 LD R20,Y+
13A 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -