📄 ds1302.lst
字号:
0130 E021 LDI R18,1
0131 E030 LDI R19,0
0132 2700 CLR R16
0133 2711 CLR R17
0134 DF84 RCALL _LCD_write_char
(0130) delay(1);
0135 E001 LDI R16,1
0136 E010 LDI R17,0
0137 DF50 RCALL _delay
(0131) LCD_write_char(0,0x06); // 显示光标移动设置
0138 E026 LDI R18,6
0139 E030 LDI R19,0
013A 2700 CLR R16
013B 2711 CLR R17
013C DF7C RCALL _LCD_write_char
(0132) delay(1);
013D E001 LDI R16,1
013E E010 LDI R17,0
013F DF48 RCALL _delay
(0133) LCD_write_char(0,0x0c); // 显示开及光标设置
0140 E02C LDI R18,0xC
0141 E030 LDI R19,0
0142 2700 CLR R16
0143 2711 CLR R17
0144 DF74 RCALL _LCD_write_char
(0134) delay(5);
0145 E005 LDI R16,5
0146 E010 LDI R17,0
0147 DF40 RCALL _delay
0148 9508 RET
FILE: D:\单片机\ds1302\ds1302_end\ds1302.c
(0001) #include <iom16v.h> //包含型号头文件
(0002) #include <macros.h> //包含"位"操作头文件
(0003) #define uchar unsigned char
(0004) #define uint unsigned int
(0005)
(0006) #include "1602B_LCD.C" //包含1602液晶函数文件
(0007)
(0008) /******************RTC常量******************/
(0009) #define RTC_CLK PB7
(0010) #define RTC_DATA PB6
(0011) #define RTC_CS PB4
(0012) //命令
(0013) #define RD 0x01
(0014) #define WR 0x00
(0015) #define C_SEC 0x80 //秒
(0016) #define C_MIN 0x82 //分
(0017) #define C_HR 0x84 //时
(0018) #define C_DAY 0x86 //日
(0019) #define C_MTH 0x88 //月
(0020) #define C_WK 0x8A //星期 DATE
(0021) #define C_YR 0x8C //年
(0022) #define C_WP 0x8E //控制(写保护)
(0023) #define C_CHARGE 0x90 //涓流充电
(0024) #define C_BURST 0xBE //时钟多字节
(0025) //配置
(0026) #define CLK_HALT 0x80 //停止时钟控制位 SECOND bit7
(0027) #define CLK_START 0x00 //启动时钟
(0028) #define M12_24 0x80 //12/24小时值选择位 HOUR bit7
(0029) #define PROTECT 0x80 //写保护控制位 CONTROL bit7
(0030) #define UPROTECT 0x00 //写保护控制位 CONTROL bit7
(0031) //涓流充电控制常量
(0032) #define TC_D1R2 0xA5 //high 1 Diode +2K Resistors
(0033) #define TC_D2R8 0xAB //low 2 Diodes+8K Resistors
(0034) #define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00)
(0035) //RAM 命令
(0036) #define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位
(0037)
(0038) void Delayus(uint US)
(0039) {
(0040) asm("nop");
_Delayus:
US --> R16
0149 0000 NOP
014A 9508 RET
_Delayms:
i --> R20
j --> R22
MS --> R16
014B 940E02CB CALL push_gset2
(0041) }
(0042) void Delayms(uint MS)
(0043) {
(0044) uint i,j;
(0045) for( i=0;i<MS;i++)
014D 2744 CLR R20
014E 2755 CLR R21
014F C00B RJMP 0x015B
(0046) for(j=0;j<1180;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
0150 2766 CLR R22
0151 2777 CLR R23
0152 C002 RJMP 0x0155
0153 5F6F SUBI R22,0xFF
0154 4F7F SBCI R23,0xFF
0155 396C CPI R22,0x9C
0156 E0E4 LDI R30,4
0157 077E CPC R23,R30
0158 F3D0 BCS 0x0153
0159 5F4F SUBI R20,0xFF
015A 4F5F SBCI R21,0xFF
015B 1740 CP R20,R16
015C 0751 CPC R21,R17
015D F390 BCS 0x0150
015E 940E02BF CALL pop_gset2
0160 9508 RET
(0047) }
(0048)
(0049)
(0050)
(0051) /*******************************************
(0052) 函数名称: DS1302_init
(0053) 功 能: 初始化DS1302的数据接口
(0054) 参 数: 无
(0055) 返回值 : 无
(0056) /********************************************/
(0057) void DS1302_portinit(void)
(0058) {
(0059) DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
_DS1302_portinit:
0161 B387 IN R24,0x17
0162 6D80 ORI R24,0xD0
0163 BB87 OUT 0x17,R24
0164 9508 RET
_DS1302_writeB:
i --> R20
byte --> R22
0165 940E02CB CALL push_gset2
0167 2F60 MOV R22,R16
(0060) }
(0061) /*******************************************
(0062) 函数名称: DS1302_writeB
(0063) 功 能: 向DS1302写入一个字节数据(没有RST操作)
(0064) 参 数: byte--要写入的数据
(0065) 返回值 : 无
(0066) /********************************************/
(0067) void DS1302_writeB(uchar byte)
(0068) {
(0069) uchar i;
(0070) for(i=0;i<8;i++) //8位数据计数
0168 2744 CLR R20
0169 C00C RJMP 0x0176
(0071) {
(0072) PORTB&=~BIT(RTC_CLK); //拉低时钟端
016A 98C7 CBI 0x18,7
(0073) if(byte&0x01) //当前位是否是1
016B FF60 SBRS R22,0
016C C002 RJMP 0x016F
(0074) {
(0075) PORTB|=BIT(RTC_DATA); //当前位是1,拉高数据端
016D 9AC6 SBI 0x18,6
(0076) }
016E C001 RJMP 0x0170
(0077) else
(0078) {
(0079) PORTB&=~BIT(RTC_DATA); //当前位是0,拉低数据端
016F 98C6 CBI 0x18,6
(0080) }
(0081) Delayus(10); //调整时钟和脉冲宽度
0170 E00A LDI R16,0xA
0171 E010 LDI R17,0
0172 DFD6 RCALL _Delayus
(0082) PORTB|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)
0173 9AC7 SBI 0x18,7
(0083) byte>>=1; //数据右移1位,为送出新数据位做准备
0174 9566 LSR R22
0175 9543 INC R20
0176 3048 CPI R20,0x8
0177 F390 BCS 0x016A
0178 940E02BF CALL pop_gset2
017A 9508 RET
_DS1302_readB:
i --> R20
byte --> R22
017B 940E02CB CALL push_gset2
(0084) }
(0085) }
(0086) /*******************************************
(0087) 函数名称: DS1302_readB
(0088) 功 能: 从DS1302读出一个字节数据(没有RST操作)
(0089) 参 数: 无
(0090) 返回值 : byte--读出的数据
(0091) /********************************************/
(0092) uchar DS1302_readB(void)
(0093) {
(0094) uchar i,byte=0;
017D 2766 CLR R22
(0095) DDRB&=~BIT(RTC_DATA); //将数据端口设置为输入
017E 98BE CBI 0x17,6
(0096) PORTB&=~BIT(RTC_DATA); //无上拉电阻
017F 98C6 CBI 0x18,6
(0097) for(i=0;i<8;i++) //8位数据计数
0180 2744 CLR R20
0181 C00F RJMP 0x0191
(0098) {
(0099) byte>>=1; //保存读入的数据位
0182 9566 LSR R22
(0100) PORTB|=BIT(RTC_CLK); //时钟上升沿
0183 9AC7 SBI 0x18,7
(0101) Delayus(10); //延时,调整时钟脉冲宽度
0184 E00A LDI R16,0xA
0185 E010 LDI R17,0
0186 DFC2 RCALL _Delayus
(0102) PORTB&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位
0187 98C7 CBI 0x18,7
(0103) Delayus(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
0188 E00A LDI R16,0xA
0189 E010 LDI R17,0
018A DFBE RCALL _Delayus
(0104) if(PINB&BIT(RTC_DATA)) //当前位是否是高电平
018B 9BB6 SBIS 0x16,6
018C C002 RJMP 0x018F
(0105) {
(0106) byte|=BIT(PB7); //是高电平就将返回数据的当前位置1
018D 6860 ORI R22,0x80
(0107) }
018E C001 RJMP 0x0190
(0108) else
(0109) {
(0110) byte&=~BIT(PB7); //是低电平就将返回数据的当前位置0
018F 776F ANDI R22,0x7F
0190 9543 INC R20
0191 3048 CPI R20,0x8
0192 F378 BCS 0x0182
(0111) }
(0112) }
(0113) DDRB|=BIT(RTC_DATA); //最后将数据端口设置为输出
0193 9ABE SBI 0x17,6
(0114) return byte; //返回读出的数据
0194 2F06 MOV R16,R22
0195 940E02BF CALL pop_gset2
0197 9508 RET
_DS1302_writeD:
data --> R20
addr --> R22
0198 940E02CB CALL push_gset2
019A 2F42 MOV R20,R18
019B 2F60 MOV R22,R16
(0115) }
(0116) /*******************************************
(0117) 函数名称: DS1302_writeD
(0118) 功 能: 向DS1302的某个地址写入一个字节数据
(0119) 参 数: addr--地址值(寄存器或RAM)
(0120) data--要写入的地址
(0121) 返回值 : 无
(0122) /********************************************/
(0123) void DS1302_writeD(uchar addr,uchar data)
(0124) {
(0125) PORTB&=~BIT(RTC_CS); //拉低片选端
019C 98C4 CBI 0x18,4
(0126) PORTB&=~BIT(RTC_CLK); //拉低时钟端
019D 98C7 CBI 0x18,7
(0127) Delayus(10);
019E E00A LDI R16,0xA
019F E010 LDI R17,0
01A0 DFA8 RCALL _Delayus
(0128) PORTB|=BIT(RTC_CS); //拉高片选端
01A1 9AC4 SBI 0x18,4
(0129) Delayus(10); //调整片选脉冲
01A2 E00A LDI R16,0xA
01A3 E010 LDI R17,0
01A4 DFA4 RCALL _Delayus
(0130) DS1302_writeB(addr); //写入操作命令(地址)
01A5 2F06 MOV R16,R22
01A6 DFBE RCALL _DS1302_writeB
(0131) Delayus(10);
01A7 E00A LDI R16,0xA
01A8 E010 LDI R17,0
01A9 DF9F RCALL _Delayus
(0132) PORTB&=~BIT(RTC_CLK); //拉低时钟端
01AA 98C7 CBI 0x18,7
(0133) Delayus(10);
01AB E00A LDI R16,0xA
01AC E010 LDI R17,0
01AD DF9B RCALL _Delayus
(0134) DS1302_writeB(data); //写入数据
01AE 2F04 MOV R16,R20
01AF DFB5 RCALL _DS1302_writeB
(0135) PORTB&=~BIT(RTC_CLK); //拉低时钟端
01B0 98C7 CBI 0x18,7
(0136) Delayus(10); //调整片选脉冲
01B1 E00A LDI R16,0xA
01B2 E010 LDI R17,0
01B3 DF95 RCALL _Delayus
(0137) PORTB&=~BIT(RTC_CS); //拉低片选端
01B4 98C4 CBI 0x18,4
01B5 940E02BF CALL pop_gset2
01B7 9508 RET
_DS1302_readD:
data --> R20
addr --> R20
01B8 940E02CD CALL push_gset1
01BA 2F40 MOV R20,R16
(0138) }
(0139) /*******************************************
(0140) 函数名称: DS1302_readD
(0141) 功 能: 从DS1302的某个地址读出一个字节数据
(0142) 参 数: addr--地址值(寄存器或RAM)
(0143) 返回值 : data--读出的数据
(0144) /********************************************/
(0145) uchar DS1302_readD(uchar addr)
(0146) {
(0147) uchar data;
(0148) PORTB&=~BIT(RTC_CS); //拉低片选端
01BB 98C4 CBI 0x18,4
(0149) PORTB&=~BIT(RTC_CLK); //拉低时钟端
01BC 98C7 CBI 0x18,7
(0150) Delayus(10);
01BD E00A LDI R16,0xA
01BE E010 LDI R17,0
01BF DF89 RCALL _Delayus
(0151) PORTB|=BIT(RTC_CS); //拉高片选端
01C0 9AC4 SBI 0x18,4
(0152) Delayus(10); //调整片选脉冲
01C1 E00A LDI R16,0xA
01C2 E010 LDI R17,0
01C3 DF85 RCALL _Delayus
(0153) DS1302_writeB(addr); //写入操作命令(地址)
01C4 2F04 MOV R16,R20
01C5 DF9F RCALL _DS1302_writeB
(0154) Delayus(10);
01C6 E00A LDI R16,0xA
01C7 E010 LDI R17,0
01C8 DF80 RCALL _Delayus
(0155) data=DS1302_readB(); //读出数据
01C9 DFB1 RCALL _DS1302_readB
01CA 2F40 MOV R20,R16
(0156) Delayus(10);
01CB E00A LDI R16,0xA
01CC E010 LDI R17,0
01CD DF7B RCALL _Delayus
(0157) PORTB&=~BIT(RTC_CLK); //拉低时钟端
01CE 98C7 CBI 0x18,7
(0158) PORTB&=~BIT(RTC_CS); //拉低片选端
01CF 98C4 CBI 0x18,4
(0159) return data; //返回读出的数据
01D0 2F04 MOV R16,R20
01D1 940E02D0 CALL pop_gset1
01D3 9508 RET
_DS1302_setT:
addr --> R20
i --> R22
ptTimeD --> R10
01D4 940E02C9 CALL push_gset3
01D6 0158 MOVW R10,R16
(0160) }
(0161) /*******************************************
(0162) 函数名称: DS1302_setT
(0163) 功 能: 设置DS1302的时间
(0164) 参 数: ptTimeD--设置时间数组指针
(0165) 返回值 : 无
(0166) /********************************************/
(0167) void DS1302_setT(uchar ptTimeD[])
(0168) {
(0169) uchar i;
(0170) uchar addr = 0x80; //写入地址从秒寄存器开始
01D7 E840 LDI R20,0x80
(0171) DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
01D8 2722 CLR R18
01D9 E80E LDI R16,0x8E
01DA DFBD RCALL _DS1302_writeD
(0172) Delayms(5);
01DB E005 LDI R16,5
01DC E010 LDI R17,0
01DD DF6D RCALL _Delayms
(0173) for(i=0;i<7;i++)
01DE 2766 CLR R22
01DF C00C RJMP 0x01EC
(0174) {
(0175) DS1302_writeD(addr|WR,ptTimeD[i]); // 秒 分 时 日 月 星期 年
01E0 2FE6 MOV R30,R22
01E1 27FF CLR R31
01E2 0DEA ADD R30,R10
01E3 1DFB ADC R31,R11
01E4 8120 LDD R18,Z+0
01E5 2F04 MOV R16,R20
01E6 DFB1 RCALL _DS1302_writeD
(0176) addr+=2;
01E7 5F4E SUBI R20,0xFE
(0177) Delayms(1);
01E8 E001 LDI R16,1
01E9 E010 LDI R17,0
01EA DF60 RCALL _Delayms
01EB 9563 INC R22
01EC 3067 CPI R22,7
01ED F390 BCS 0x01E0
(0178) }
(0179) DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作
01EE E820 LDI R18,0x80
01EF E80E LDI R16,0x8E
01F0 DFA7 RCALL _DS1302_writeD
01F1 940E02C2 CALL pop_gset3
01F3 9508 RET
_DS1302_getT:
i --> R20
time --> R22
01F4 940E02CB CALL push_gset2
01F6 01B8 MOVW R22,R16
(0180) }
(0181) /*******************************************
(0182) 函数名称: DS1302_getT
(0183) 功 能: 读取DS1302的当前时间
(0184) 参 数: time[]--读取的时间数组
(0185) 返回值 : 无
(0186) /********************************************/
(0187) void DS1302_getT(uchar time[])
(0188) {
(0189) uchar i;
(0190) ////////下面的是单次读写//////////////////////////
(0191) /* uchar addr = 0x80; //读取地址从秒寄存器开始
(0192) for(i=0;i<7;i++)
(0193) {
(0194) time[i]=DS1302_readD(addr|RD); // 秒 分 时 日 月 星期 年
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -