⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302.lst

📁 AVR单片机C语言编程及应用实例 适合初学者的学习研究 其中包含Atmega16中文资料及Protel部分电路图
💻 LST
📖 第 1 页 / 共 3 页
字号:
    00FA 0757      CPC	R21,R23
    00FB F3D8      BCS	0x00F7
(0045) }
    00FC 940E02D6  CALL	pop_gset2
    00FE 9508      RET
_Delayms:
  i                    --> R20
  j                    --> R22
  MS                   --> R16
    00FF 940E02CE  CALL	push_gset2
(0046) void Delayms(uint MS)		  
(0047) {
(0048)  uint i,j;
(0049)  for( i=0;i<MS;i++)
    0101 2744      CLR	R20
    0102 2755      CLR	R21
    0103 C00B      RJMP	0x010F
(0050)  for(j=0;j<1141;j++);	//1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
    0104 2766      CLR	R22
    0105 2777      CLR	R23
    0106 C002      RJMP	0x0109
    0107 5F6F      SUBI	R22,0xFF
    0108 4F7F      SBCI	R23,0xFF
    0109 3765      CPI	R22,0x75
    010A E0E4      LDI	R30,4
    010B 077E      CPC	R23,R30
    010C F3D0      BCS	0x0107
    010D 5F4F      SUBI	R20,0xFF
    010E 4F5F      SBCI	R21,0xFF
    010F 1740      CP	R20,R16
    0110 0751      CPC	R21,R17
    0111 F390      BCS	0x0104
(0051) }
    0112 940E02D6  CALL	pop_gset2
    0114 9508      RET
(0052) 
(0053) 
(0054) 
(0055) /*******************************************
(0056) 函数名称: DS1302_init
(0057) 功    能: 初始化DS1302的数据接口
(0058) 参    数: 无
(0059) 返回值  : 无
(0060) /********************************************/
(0061) void DS1302_portinit(void)		  
(0062) {
(0063)  DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
_DS1302_portinit:
    0115 B387      IN	R24,P17
    0116 6A80      ORI	R24,0xA0
    0117 BB87      OUT	P17,R24
(0064) }
    0118 9508      RET
_DS1302_writeB:
  i                    --> R20
  byte                 --> R22
    0119 940E02CE  CALL	push_gset2
    011B 2F60      MOV	R22,R16
(0065) /*******************************************
(0066) 函数名称: DS1302_writeB
(0067) 功    能: 向DS1302写入一个字节数据(没有RST操作)
(0068) 参    数: byte--要写入的数据
(0069) 返回值  : 无
(0070) /********************************************/
(0071) void DS1302_writeB(uchar byte)
(0072) {
(0073)  uchar i;
(0074)  for(i=0;i<8;i++)		 	  //8位数据计数
    011C 2744      CLR	R20
    011D C00C      RJMP	0x012A
(0075)  {
(0076)   PORTB&=~BIT(RTC_CLK);		  //拉低时钟端
    011E 98C7      CBI	P18,7
(0077)   if(byte&0x01)				  //当前位是否是1
    011F FF60      SBRS	R22,0
    0120 C002      RJMP	0x0123
(0078)   {
(0079)    PORTB|=BIT(RTC_DATA);	  //当前位是1,拉高数据端
    0121 9AC5      SBI	P18,5
(0080)   }
    0122 C001      RJMP	0x0124
(0081)   else						  
(0082)   {
(0083)    PORTB&=~BIT(RTC_DATA);	  //当前位是0,拉低数据端
    0123 98C5      CBI	P18,5
(0084)   }  
(0085)   Delayus(10);				  //调整时钟和脉冲宽度
    0124 E00A      LDI	R16,0xA
    0125 E010      LDI	R17,0
    0126 DFC0      RCALL	_Delayus
(0086)   PORTB|=BIT(RTC_CLK);		  //时钟上升沿(DS1302采样数据)
    0127 9AC7      SBI	P18,7
(0087)   byte>>=1;					  //数据右移1位,为送出新数据位做准备
    0128 9566      LSR	R22
    0129 9543      INC	R20
    012A 3048      CPI	R20,0x8
    012B F390      BCS	0x011E
(0088)  }
(0089) }
    012C 940E02D6  CALL	pop_gset2
    012E 9508      RET
_DS1302_readB:
  i                    --> R20
  byte                 --> R22
    012F 940E02CE  CALL	push_gset2
(0090) /*******************************************
(0091) 函数名称: DS1302_readB
(0092) 功    能: 从DS1302读出一个字节数据(没有RST操作)
(0093) 参    数: 无
(0094) 返回值  : byte--读出的数据
(0095) /********************************************/
(0096) uchar DS1302_readB(void)
(0097) {
(0098)  uchar i,byte=0;
    0131 2766      CLR	R22
(0099)  DDRB&=~BIT(RTC_DATA);		 //将数据端口设置为输入		  
    0132 98BD      CBI	P17,5
(0100)  PORTB&=~BIT(RTC_DATA);		 //无上拉电阻
    0133 98C5      CBI	P18,5
(0101)  for(i=0;i<8;i++)			 //8位数据计数
    0134 2744      CLR	R20
    0135 C00F      RJMP	0x0145
(0102)  {
(0103)   byte>>=1;  				 //保存读入的数据位
    0136 9566      LSR	R22
(0104)   PORTB|=BIT(RTC_CLK);		 //时钟上升沿
    0137 9AC7      SBI	P18,7
(0105)   Delayus(10);				 //延时,调整时钟脉冲宽度
    0138 E00A      LDI	R16,0xA
    0139 E010      LDI	R17,0
    013A DFAC      RCALL	_Delayus
(0106)   PORTB&=~BIT(RTC_CLK);		 //时钟下降沿,DS1302输出数据位
    013B 98C7      CBI	P18,7
(0107)   Delayus(10);				 //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
    013C E00A      LDI	R16,0xA
    013D E010      LDI	R17,0
    013E DFA8      RCALL	_Delayus
(0108)   if(PINB&BIT(RTC_DATA))	 //当前位是否是高电平
    013F 9BB5      SBIS	P16,5
    0140 C002      RJMP	0x0143
(0109)   {
(0110)    byte|=BIT(PB7);			 //是高电平就将返回数据的当前位置1
    0141 6860      ORI	R22,0x80
(0111)   }
    0142 C001      RJMP	0x0144
(0112)   else
(0113)   {
(0114)    byte&=~BIT(PB7);			 //是低电平就将返回数据的当前位置0
    0143 776F      ANDI	R22,0x7F
    0144 9543      INC	R20
    0145 3048      CPI	R20,0x8
    0146 F378      BCS	0x0136
(0115)   }
(0116)  }
(0117)  DDRB|=BIT(RTC_DATA);		 //最后将数据端口设置为输出
    0147 9ABD      SBI	P17,5
(0118)  return byte;				 //返回读出的数据
    0148 2F06      MOV	R16,R22
    0149 940E02D6  CALL	pop_gset2
    014B 9508      RET
_DS1302_writeD:
  data                 --> R20
  addr                 --> R22
    014C 940E02CE  CALL	push_gset2
    014E 2F42      MOV	R20,R18
    014F 2F60      MOV	R22,R16
(0119) }
(0120) /*******************************************
(0121) 函数名称: DS1302_writeD
(0122) 功    能: 向DS1302的某个地址写入一个字节数据
(0123) 参    数: addr--地址值(寄存器或RAM)
(0124) 	  	  data--要写入的地址
(0125) 返回值  : 无
(0126) /********************************************/
(0127) void DS1302_writeD(uchar addr,uchar data)
(0128) {
(0129)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    0150 98AF      CBI	P15,7
(0130)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    0151 98C7      CBI	P18,7
(0131)  Delayus(10);
    0152 E00A      LDI	R16,0xA
    0153 E010      LDI	R17,0
    0154 DF92      RCALL	_Delayus
(0132)  PORTC|=BIT(RTC_CS);	 //拉高片选端
    0155 9AAF      SBI	P15,7
(0133)  Delayus(10); 			 //调整片选脉冲
    0156 E00A      LDI	R16,0xA
    0157 E010      LDI	R17,0
    0158 DF8E      RCALL	_Delayus
(0134)  DS1302_writeB(addr);	 //写入操作命令(地址)
    0159 2F06      MOV	R16,R22
    015A DFBE      RCALL	_DS1302_writeB
(0135)  Delayus(10);
    015B E00A      LDI	R16,0xA
    015C E010      LDI	R17,0
    015D DF89      RCALL	_Delayus
(0136)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    015E 98C7      CBI	P18,7
(0137)  Delayus(10);
    015F E00A      LDI	R16,0xA
    0160 E010      LDI	R17,0
    0161 DF85      RCALL	_Delayus
(0138)  DS1302_writeB(data);	 //写入数据
    0162 2F04      MOV	R16,R20
    0163 DFB5      RCALL	_DS1302_writeB
(0139)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    0164 98C7      CBI	P18,7
(0140)  Delayus(10);			 //调整片选脉冲
    0165 E00A      LDI	R16,0xA
    0166 E010      LDI	R17,0
    0167 DF7F      RCALL	_Delayus
(0141)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    0168 98AF      CBI	P15,7
(0142) }
    0169 940E02D6  CALL	pop_gset2
    016B 9508      RET
_DS1302_readD:
  data                 --> R20
  addr                 --> R20
    016C 940E02B7  CALL	push_gset1
    016E 2F40      MOV	R20,R16
(0143) /*******************************************
(0144) 函数名称: DS1302_readD
(0145) 功    能: 从DS1302的某个地址读出一个字节数据
(0146) 参    数: addr--地址值(寄存器或RAM)
(0147) 返回值  : data--读出的数据
(0148) /********************************************/
(0149) uchar DS1302_readD(uchar addr)
(0150) {
(0151)  uchar data;
(0152)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    016F 98AF      CBI	P15,7
(0153)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    0170 98C7      CBI	P18,7
(0154)  Delayus(10);
    0171 E00A      LDI	R16,0xA
    0172 E010      LDI	R17,0
    0173 DF73      RCALL	_Delayus
(0155)  PORTC|=BIT(RTC_CS);	 //拉高片选端
    0174 9AAF      SBI	P15,7
(0156)  Delayus(10); 			 //调整片选脉冲
    0175 E00A      LDI	R16,0xA
    0176 E010      LDI	R17,0
    0177 DF6F      RCALL	_Delayus
(0157)  DS1302_writeB(addr);	 //写入操作命令(地址)
    0178 2F04      MOV	R16,R20
    0179 DF9F      RCALL	_DS1302_writeB
(0158)  Delayus(10);
    017A E00A      LDI	R16,0xA
    017B E010      LDI	R17,0
    017C DF6A      RCALL	_Delayus
(0159)  data=DS1302_readB();	 //读出数据
    017D DFB1      RCALL	_DS1302_readB
    017E 2F40      MOV	R20,R16
(0160)  Delayus(10);
    017F E00A      LDI	R16,0xA
    0180 E010      LDI	R17,0
    0181 DF65      RCALL	_Delayus
(0161)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    0182 98C7      CBI	P18,7
(0162)  PORTC&=~BIT(RTC_CS); 	 //拉低片选端
    0183 98AF      CBI	P15,7
(0163)  return data;			 //返回读出的数据
    0184 2F04      MOV	R16,R20
    0185 940E02BA  CALL	pop_gset1
    0187 9508      RET
_DS1302_setT:
  addr                 --> R20
  i                    --> R22
  ptTimeD              --> R10
    0188 940E02D2  CALL	push_gset3
    018A 0158      MOVW	R10,R16
(0164) }
(0165) /*******************************************
(0166) 函数名称: DS1302_setT
(0167) 功    能: 设置DS1302的时间
(0168) 参    数: ptTimeD--设置时间数组指针
(0169) 返回值  : 无
(0170) /********************************************/
(0171) void DS1302_setT(uchar ptTimeD[])
(0172) {
(0173)     uchar i;
(0174)     uchar addr = 0x80; 			 	  //写入地址从秒寄存器开始
    018B E840      LDI	R20,0x80
(0175)     DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
    018C 2722      CLR	R18
    018D E80E      LDI	R16,0x8E
    018E DFBD      RCALL	_DS1302_writeD
(0176) 	Delayms(5);
    018F E005      LDI	R16,5
    0190 E010      LDI	R17,0
    0191 DF6D      RCALL	_Delayms
(0177)     for(i=0;i<7;i++)
    0192 2766      CLR	R22
    0193 C00C      RJMP	0x01A0
(0178)     {
(0179)         DS1302_writeD(addr|WR,ptTimeD[i]);   // 秒 分 时 日 月 星期 年         
    0194 2FE6      MOV	R30,R22
    0195 27FF      CLR	R31
    0196 0DEA      ADD	R30,R10
    0197 1DFB      ADC	R31,R11
    0198 8120      LDD	R18,0+Z
    0199 2F04      MOV	R16,R20
    019A DFB1      RCALL	_DS1302_writeD
(0180)         addr+=2;
    019B 5F4E      SUBI	R20,0xFE
(0181) 		Delayms(1);
    019C E001      LDI	R16,1
    019D E010      LDI	R17,0
    019E DF60      RCALL	_Delayms
    019F 9563      INC	R22
    01A0 3067      CPI	R22,7
    01A1 F390      BCS	0x0194
(0182)     }
(0183)     DS1302_writeD(C_WP|WR,PROTECT); 		//控制命令,WP位为1,不允许写操作
    01A2 E820      LDI	R18,0x80
    01A3 E80E      LDI	R16,0x8E
    01A4 DFA7      RCALL	_DS1302_writeD
(0184) }
    01A5 940E02D9  CALL	pop_gset3
    01A7 9508      RET
_DS1302_getT:
  i                    --> R20
  time                 --> R22
    01A8 940E02CE  CALL	push_gset2
    01AA 01B8      MOVW	R22,R16
(0185) /*******************************************
(0186) 函数名称: DS1302_getT
(0187) 功    能: 读取DS1302的当前时间
(0188) 参    数: time[]--读取的时间数组
(0189) 返回值  : 无
(0190) /********************************************/
(0191) void DS1302_getT(uchar time[])
(0192) {
(0193)     uchar i;
(0194) ////////下面的是单次读写//////////////////////////	
(0195)    /* uchar addr = 0x80; 			 	  		  //读取地址从秒寄存器开始 
(0196)     for(i=0;i<7;i++)
(0197)     {
(0198)         time[i]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
(0199)         addr+=2;
(0200)     }*/
(0201) ////////////////////////////////////////////////////	
(0202) 	/////////下面是多字节读取/////////////// 
(0203) 	 PORTC&=~BIT(RTC_CS);	 //拉低片选端
    01AB 98AF      CBI	P15,7
(0204)      Delayus(10);
    01AC E00A      LDI	R16,0xA
    01AD E010      LDI	R17,0
    01AE DF38      RCALL	_Delayus
(0205)      PORTC|=BIT(RTC_CS);	 //拉高片选端
    01AF 9AAF      SBI	P15,7
(0206)      Delayus(10); 			 //调整片选脉冲
    01B0 E00A      LDI	R16,0xA
    01B1 E010      LDI	R17,0
    01B2 DF34      RCALL	_Delayus
(0207) 	 DS1302_writeB(0xbf);       // 0xbf:时钟多字节读取命令 
    01B3 EB0F      LDI	R16,0xBF
    01B4 DF64      RCALL	_DS1302_writeB
(0208)      for (i=0;i<8;i++)       //时间数据的存放格式是:
    01B5 2744      CLR	R20
    01B6 C007      RJMP	0x01BE
(0209)        {                        //秒,分,时,日,月,星期,年,控制
(0210)          time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】 
    01B7 DF77      RCALL	_DS1302_readB
    01B8 2FE4      MOV	R30,R20
    01B9 27FF      CLR	R31
    01BA 0FE6      ADD	R30,R22
    01BB 1FF7      ADC	R31,R23
    01BC 8300      STD	R16,0+Z
    01BD 9543      INC	R20
    01BE 3048      CPI	R20,0x8
    01BF F3B8      BCS	0x01B7
(0211)        }
(0212) 				
(0213)      PORTC&=~BIT(RTC_CS); 	 //拉低片选端
    01C0 98AF      CBI	P15,7
(0214)  ///////////////////////////////////////////////
(0215)      PORTB&=~BIT(RTC_CLK);	 				  //拉低时钟端(时钟端在不操作时为低)
    01C1 98C7      CBI	P18,7
(0216) }
    01C2 940E02D6  CALL	pop_gset2
    01C4 9508      RET
_DS1302_check:
  exist                --> R20
    01C5 940E02B7  CALL	push_gset1
(0217) /*******************************************
(0218) 函数名称: DS1302_check
(0219) 功    能: 检测DS1302是否正常工作
(0220) 参    数: 无
(0221) 返回值  : exist--为TRUE为检测到DS1302,为FALSE为没检测到
(0222) /********************************************/
(0223) uchar DS1302_check(void)
(0224) {
(0225) 	uchar exist;
(0226)     DS1302_writeD(C_WP|WR,UPROTECT);		  //写入写允许命令
    01C7 2722      CLR	R18
    01C8 E80E      LDI	R16,0x8E
    01C9 DF82      RCALL	_DS1302_writeD
(0227)     DS1302_writeD(C_RAMBASE|WR,0xA5);		  //RAM0写入0xA5
    01CA EA25      LDI	R18,0xA5
    01CB EC00      LDI	R16,0xC0
    01CC DF7F      RCALL	_DS1302_writeD
(0228)     exist=DS1302_readD(C_RAMBASE|RD);		  //读取RAM0
    01CD EC01      LDI	R16,0xC1
    01CE DF9D      RCALL	_DS1302_readD
    01CF 2F40      MOV	R20,R16
(0229)     if(exist==0xA5)	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -