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

📄 rtc.lst

📁 在AVR开发板驱动时钟芯片DS1302
💻 LST
📖 第 1 页 / 共 5 页
字号:
    01F5 E04B      LDI	R20,0xB
(0093) 			break;
    01F6 C007      RJMP	0x01FE
(0094) 	   case 0xE7:
(0095) 	   		keycode=0xC;
    01F7 E04C      LDI	R20,0xC
(0096) 			break;
    01F8 C005      RJMP	0x01FE
(0097) 	   case 0xD7:
(0098) 	   		keycode=0xD;
    01F9 E04D      LDI	R20,0xD
(0099) 			break;
    01FA C003      RJMP	0x01FE
(0100) 	   case 0xB7:
(0101) 	   		keycode=0xE;
    01FB E04E      LDI	R20,0xE
(0102) 			break;
    01FC C001      RJMP	0x01FE
(0103) 	   case 0x77:
(0104) 	   		keycode=0xF;
    01FD E04F      LDI	R20,0xF
(0105) 			break;
(0106) 	}
(0107)  }
(0108)  return keycode;  		//返回经过翻译的键码
    01FE 2F04      MOV	R16,R20
    01FF 940E070A  CALL	pop_gset3
    0201 9508      RET
FILE: C:\icc\examples.avr\AVR_PQ1A_DEMO\17_RTC\RTC.C
(0001) /*******************************************
(0002)   文件:RTC.C
(0003)   环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10 
(0004)   硬件:ATMEGA16芯片
(0005)   日期:2006年12月10日 
(0006)   功能:驱动开发板上的DS1302时钟芯片
(0007)   备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
(0008) /******************************************/
(0009) #include <iom16v.h>			//包含型号头文件
(0010) #include <macros.h>			//包含"位"操作头文件
(0011) #include <stdio.h>			//标准输入输出头文件
(0012) #include <AVR_PQ1A.h>		//包含自定义常量头文件
(0013) #include "YJ1602.C"			//包含1602液晶函数文件
(0014) #include "MKEY.C"			//包含矩阵键盘函数文件
(0015) 
(0016) /*******************************************
(0017) 函数名称: DS1302_init
(0018) 功    能: 初始化DS1302的数据接口
(0019) 参    数: 无
(0020) 返回值  : 无
(0021) /********************************************/
(0022) void DS1302_portinit(void)		  
(0023) {
(0024)  DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
_DS1302_portinit:
    0202 B387      IN	R24,P17
    0203 6A80      ORI	R24,0xA0
    0204 BB87      OUT	P17,R24
(0025) }
    0205 9508      RET
_DS1302_writeB:
  i                    --> R20
  byte                 --> R22
    0206 940E06FF  CALL	push_gset2
    0208 2F60      MOV	R22,R16
(0026) /*******************************************
(0027) 函数名称: DS1302_writeB
(0028) 功    能: 向DS1302写入一个字节数据(没有RST操作)
(0029) 参    数: byte--要写入的数据
(0030) 返回值  : 无
(0031) /********************************************/
(0032) void DS1302_writeB(uchar byte)
(0033) {
(0034)  uchar i;
(0035)  for(i=0;i<8;i++)		 	  //8位数据计数
    0209 2744      CLR	R20
    020A C00C      RJMP	0x0217
(0036)  {
(0037)   PORTB&=~BIT(RTC_CLK);		  //拉低时钟端
    020B 98C7      CBI	P18,7
(0038)   if(byte&0x01)				  //当前位是否是1
    020C FF60      SBRS	R22,0
    020D C002      RJMP	0x0210
(0039)   {
(0040)    PORTB|=BIT(RTC_DATA);	  //当前位是1,拉高数据端
    020E 9AC5      SBI	P18,5
(0041)   }
    020F C001      RJMP	0x0211
(0042)   else						  
(0043)   {
(0044)    PORTB&=~BIT(RTC_DATA);	  //当前位是0,拉低数据端
    0210 98C5      CBI	P18,5
(0045)   }  
(0046)   Delayus(10);				  //调整时钟和脉冲宽度
    0211 E00A      LDI	R16,0xA
    0212 E010      LDI	R17,0
    0213 DE67      RCALL	_Delayus
(0047)   PORTB|=BIT(RTC_CLK);		  //时钟上升沿(DS1302采样数据)
    0214 9AC7      SBI	P18,7
(0048)   byte>>=1;					  //数据右移1位,为送出新数据位做准备
    0215 9566      LSR	R22
    0216 9543      INC	R20
    0217 3048      CPI	R20,0x8
    0218 F390      BCS	0x020B
(0049)  }
(0050) }
    0219 940E0707  CALL	pop_gset2
    021B 9508      RET
_DS1302_readB:
  i                    --> R20
  byte                 --> R22
    021C 940E06FF  CALL	push_gset2
(0051) /*******************************************
(0052) 函数名称: DS1302_readB
(0053) 功    能: 从DS1302读出一个字节数据(没有RST操作)
(0054) 参    数: 无
(0055) 返回值  : byte--读出的数据
(0056) /********************************************/
(0057) uchar DS1302_readB(void)
(0058) {
(0059)  uchar i,byte=0;
    021E 2766      CLR	R22
(0060)  DDRB&=~BIT(RTC_DATA);		 //将数据端口设置为输入		  
    021F 98BD      CBI	P17,5
(0061)  PORTB&=~BIT(RTC_DATA);		 //无上拉电阻
    0220 98C5      CBI	P18,5
(0062)  for(i=0;i<8;i++)			 //8位数据计数
    0221 2744      CLR	R20
    0222 C00F      RJMP	0x0232
(0063)  {
(0064)   byte>>=1;  				 //保存读入的数据位
    0223 9566      LSR	R22
(0065)   PORTB|=BIT(RTC_CLK);		 //时钟上升沿
    0224 9AC7      SBI	P18,7
(0066)   Delayus(10);				 //延时,调整时钟脉冲宽度
    0225 E00A      LDI	R16,0xA
    0226 E010      LDI	R17,0
    0227 DE53      RCALL	_Delayus
(0067)   PORTB&=~BIT(RTC_CLK);		 //时钟下降沿,DS1302输出数据位
    0228 98C7      CBI	P18,7
(0068)   Delayus(10);				 //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
    0229 E00A      LDI	R16,0xA
    022A E010      LDI	R17,0
    022B DE4F      RCALL	_Delayus
(0069)   if(PINB&BIT(RTC_DATA))	 //当前位是否是高电平
    022C 9BB5      SBIS	P16,5
    022D C002      RJMP	0x0230
(0070)   {
(0071)    byte|=BIT(PB7);			 //是高电平就将返回数据的当前位置1
    022E 6860      ORI	R22,0x80
(0072)   }
    022F C001      RJMP	0x0231
(0073)   else
(0074)   {
(0075)    byte&=~BIT(PB7);			 //是低电平就将返回数据的当前位置0
    0230 776F      ANDI	R22,0x7F
    0231 9543      INC	R20
    0232 3048      CPI	R20,0x8
    0233 F378      BCS	0x0223
(0076)   }
(0077)  }
(0078)  DDRB|=BIT(RTC_DATA);		 //最后将数据端口设置为输出
    0234 9ABD      SBI	P17,5
(0079)  return byte;				 //返回读出的数据
    0235 2F06      MOV	R16,R22
    0236 940E0707  CALL	pop_gset2
    0238 9508      RET
_DS1302_writeD:
  data                 --> R20
  addr                 --> R22
    0239 940E06FF  CALL	push_gset2
    023B 2F42      MOV	R20,R18
    023C 2F60      MOV	R22,R16
(0080) }
(0081) /*******************************************
(0082) 函数名称: DS1302_writeD
(0083) 功    能: 向DS1302的某个地址写入一个字节数据
(0084) 参    数: addr--地址值(寄存器或RAM)
(0085) 	  	  data--要写入的地址
(0086) 返回值  : 无
(0087) /********************************************/
(0088) void DS1302_writeD(uchar addr,uchar data)
(0089) {
(0090)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    023D 98AF      CBI	P15,7
(0091)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    023E 98C7      CBI	P18,7
(0092)  Delayus(10);
    023F E00A      LDI	R16,0xA
    0240 E010      LDI	R17,0
    0241 DE39      RCALL	_Delayus
(0093)  PORTC|=BIT(RTC_CS);	 //拉高片选端
    0242 9AAF      SBI	P15,7
(0094)  Delayus(10); 			 //调整片选脉冲
    0243 E00A      LDI	R16,0xA
    0244 E010      LDI	R17,0
    0245 DE35      RCALL	_Delayus
(0095)  DS1302_writeB(addr);	 //写入操作命令(地址)
    0246 2F06      MOV	R16,R22
    0247 DFBE      RCALL	_DS1302_writeB
(0096)  Delayus(10);
    0248 E00A      LDI	R16,0xA
    0249 E010      LDI	R17,0
    024A DE30      RCALL	_Delayus
(0097)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    024B 98C7      CBI	P18,7
(0098)  Delayus(10);
    024C E00A      LDI	R16,0xA
    024D E010      LDI	R17,0
    024E DE2C      RCALL	_Delayus
(0099)  DS1302_writeB(data);	 //写入数据
    024F 2F04      MOV	R16,R20
    0250 DFB5      RCALL	_DS1302_writeB
(0100)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    0251 98C7      CBI	P18,7
(0101)  Delayus(10);			 //调整片选脉冲
    0252 E00A      LDI	R16,0xA
    0253 E010      LDI	R17,0
    0254 DE26      RCALL	_Delayus
(0102)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    0255 98AF      CBI	P15,7
(0103) }
    0256 940E0707  CALL	pop_gset2
    0258 9508      RET
_DS1302_readD:
  data                 --> R20
  addr                 --> R20
    0259 940E06E8  CALL	push_gset1
    025B 2F40      MOV	R20,R16
(0104) /*******************************************
(0105) 函数名称: DS1302_readD
(0106) 功    能: 从DS1302的某个地址读出一个字节数据
(0107) 参    数: addr--地址值(寄存器或RAM)
(0108) 返回值  : data--读出的数据
(0109) /********************************************/
(0110) uchar DS1302_readD(uchar addr)
(0111) {
(0112)  uchar data;
(0113)  PORTC&=~BIT(RTC_CS);	 //拉低片选端
    025C 98AF      CBI	P15,7
(0114)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    025D 98C7      CBI	P18,7
(0115)  Delayus(10);
    025E E00A      LDI	R16,0xA
    025F E010      LDI	R17,0
    0260 DE1A      RCALL	_Delayus
(0116)  PORTC|=BIT(RTC_CS);	 //拉高片选端
    0261 9AAF      SBI	P15,7
(0117)  Delayus(10); 			 //调整片选脉冲
    0262 E00A      LDI	R16,0xA
    0263 E010      LDI	R17,0
    0264 DE16      RCALL	_Delayus
(0118)  DS1302_writeB(addr);	 //写入操作命令(地址)
    0265 2F04      MOV	R16,R20
    0266 DF9F      RCALL	_DS1302_writeB
(0119)  Delayus(10);
    0267 E00A      LDI	R16,0xA
    0268 E010      LDI	R17,0
    0269 DE11      RCALL	_Delayus
(0120)  data=DS1302_readB();	 //读出数据
    026A DFB1      RCALL	_DS1302_readB
    026B 2F40      MOV	R20,R16
(0121)  Delayus(10);
    026C E00A      LDI	R16,0xA
    026D E010      LDI	R17,0
    026E DE0C      RCALL	_Delayus
(0122)  PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
    026F 98C7      CBI	P18,7
(0123)  PORTC&=~BIT(RTC_CS); 	 //拉低片选端
    0270 98AF      CBI	P15,7
(0124)  return data;			 //返回读出的数据
    0271 2F04      MOV	R16,R20
    0272 940E06EB  CALL	pop_gset1
    0274 9508      RET
_DS1302_setT:
  addr                 --> R20
  i                    --> R22
  ptTimeD              --> R10
    0275 940E0703  CALL	push_gset3
    0277 0158      MOVW	R10,R16
(0125) }
(0126) /*******************************************
(0127) 函数名称: DS1302_setT
(0128) 功    能: 设置DS1302的时间
(0129) 参    数: ptTimeD--设置时间数组指针
(0130) 返回值  : 无
(0131) /********************************************/
(0132) void DS1302_setT(uchar ptTimeD[])
(0133) {
(0134)     uchar i;
(0135)     uchar addr = 0x80; 			 	  //写入地址从秒寄存器开始
    0278 E840      LDI	R20,0x80
(0136)     DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
    0279 2722      CLR	R18
    027A E80E      LDI	R16,0x8E
    027B DFBD      RCALL	_DS1302_writeD
(0137) 	Delayms(5);
    027C E005      LDI	R16,5
    027D E010      LDI	R17,0
    027E DE14      RCALL	_Delayms
(0138)     for(i=0;i<7;i++)
    027F 2766      CLR	R22
    0280 C00C      RJMP	0x028D
(0139)     {
(0140)         DS1302_writeD(addr|WR,ptTimeD[i]);   // 秒 分 时 日 月 星期 年         
    0281 2FE6      MOV	R30,R22
    0282 27FF      CLR	R31
    0283 0DEA      ADD	R30,R10
    0284 1DFB      ADC	R31,R11
    0285 8120      LDD	R18,0+Z
    0286 2F04      MOV	R16,R20
    0287 DFB1      RCALL	_DS1302_writeD
(0141)         addr+=2;
    0288 5F4E      SUBI	R20,0xFE
(0142) 		Delayms(1);
    0289 E001      LDI	R16,1
    028A E010      LDI	R17,0
    028B DE07      RCALL	_Delayms
    028C 9563      INC	R22
    028D 3067      CPI	R22,7
    028E F390      BCS	0x0281
(0143)     }
(0144)     DS1302_writeD(C_WP|WR,PROTECT); 		//控制命令,WP位为1,不允许写操作
    028F E820      LDI	R18,0x80
    0290 E80E      LDI	R16,0x8E
    0291 DFA7      RCALL	_DS1302_writeD
(0145) }
    0292 940E070A  CALL	pop_gset3
    0294 9508      RET
_DS1302_getT:
  addr                 --> R20
  i                    --> R22
  time                 --> R10
    0295 940E0703  CALL	push_gset3
    0297 0158      MOVW	R10,R16
(0146) /*******************************************
(0147) 函数名称: DS1302_getT
(0148) 功    能: 读取DS1302的当前时间
(0149) 参    数: time[]--读取的时间数组
(0150) 返回值  : 无
(0151) /********************************************/
(0152) void DS1302_getT(uchar time[])
(0153) {
(0154)     uchar i;
(0155)     uchar addr = 0x80; 			 	  		  //读取地址从秒寄存器开始 
    0298 E840      LDI	R20,0x80
(0156)     for(i=0;i<7;i++)
    0299 2766      CLR	R22
    029A C00A      RJMP	0x02A5
(0157)     {
(0158)         time[i]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
    029B 2F04      MOV	R16,R20
    029C 6001      ORI	R16,1
    029D DFBB      RCALL	_DS1302_readD
    029E 2FE6      MOV	R30,R22
    029F 27FF      CLR	R31
    02A0 0DEA      ADD	R30,R10
    02A1 1DFB      ADC	R31,R11
    02A2 8300      STD	R16,0+Z
(0159)         addr+=2;
    02A3 5F4E      SUBI	R20,0xFE
    02A4 9563      INC	R22
    02A5 3067      CPI	R22,7
    02A6 F3A0      BCS	0x029B
(0160)     }
(0161)     PORTB&=~BIT(RTC_CLK);	 				  //拉低时钟端(时钟端在不操作时为低)
    02A7 98C7      CBI	P18,7
(0162) }
    02A8 940E070A  CALL	pop_gset3
    02AA 9508      RET
_DS1302_check:
  exist                --> R20
    02AB 940E06E8  CALL	push_gset1
(0163) /*******************************************

⌨️ 快捷键说明

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