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

📄 24c01.lst

📁 通过MEGA128的串口对I2C芯片24c01的读写程序
💻 LST
📖 第 1 页 / 共 5 页
字号:
(0066)     n=ad_dst/PAGE_SIZE;		//确定地址与块地址的差
    013A 0157      MOVW	R10,R14
    013B 94B6      LSR	R11
    013C 94A7      ROR	R10
    013D 94B6      LSR	R11
    013E 94A7      ROR	R10
    013F 94B6      LSR	R11
    0140 94A7      ROR	R10
(0067) 	if(n) n=(unsigned long)PAGE_SIZE*(n+1)-ad_dst;
    0141 20AA      TST	R10
    0142 F411      BNE	0x0145
    0143 20BB      TST	R11
    0144 F0E1      BEQ	0x0161
    0145 01C5      MOVW	R24,R10
    0146 9601      ADIW	R24,1
    0147 011C      MOVW	R2,R24
    0148 2444      CLR	R4
    0149 2455      CLR	R5
    014A E048      LDI	R20,0x8
    014B E050      LDI	R21,0
    014C E060      LDI	R22,0
    014D E070      LDI	R23,0
    014E 925A      ST	R5,-Y
    014F 924A      ST	R4,-Y
    0150 923A      ST	R3,-Y
    0151 922A      ST	R2,-Y
    0152 018A      MOVW	R16,R20
    0153 019B      MOVW	R18,R22
    0154 940E046C  CALL	empy32u
    0156 0118      MOVW	R2,R16
    0157 0129      MOVW	R4,R18
    0158 0137      MOVW	R6,R14
    0159 2488      CLR	R8
    015A 2499      CLR	R9
    015B 1826      SUB	R2,R6
    015C 0837      SBC	R3,R7
    015D 0848      SBC	R4,R8
    015E 0859      SBC	R5,R9
    015F 0151      MOVW	R10,R2
    0160 C005      RJMP	0x0166
(0068) 	else n=PAGE_SIZE-ad_dst;
    0161 E088      LDI	R24,0x8
    0162 E090      LDI	R25,0
    0163 015C      MOVW	R10,R24
    0164 18AE      SUB	R10,R14
    0165 08BF      SBC	R11,R15
(0069) 	
(0070)     if(n>=num)		//如果ad_dst所在的数据块的末尾地址 >= ad_dst + num, 就直接写入num个数据
    0166 14AC      CP	R10,R12
    0167 04BD      CPC	R11,R13
    0168 F058      BCS	0x0174
(0071)     {
(0072) 	 	wt24c_fc(p_rsc, ad_dst, num);
    0169 82C8      STD	Y+0,R12
    016A 0197      MOVW	R18,R14
    016B 850B      LDD	R16,Y+11
    016C 851C      LDD	R17,Y+12
    016D DF96      RCALL	_wt24c_fc
(0073)     	if(syserr!=0) return;
    016E 9020013D  LDS	R2,syserr
    0170 2022      TST	R2
    0171 F409      BNE	0x0173
    0172 C032      RJMP	0x01A5
    0173 C031      RJMP	0x01A5
(0074)     }
(0075)     else			//如果ad_dst所在的数据块末尾地址 < ad_dst + num, 就先写入ad_dst所在的数据块末尾地址与 ad_dst 之差个数据
(0076)     {
(0077) 	    p_rsc=wt24c_fc(p_rsc, ad_dst, n);
    0174 82A8      STD	Y+0,R10
    0175 0197      MOVW	R18,R14
    0176 850B      LDD	R16,Y+11
    0177 851C      LDD	R17,Y+12
    0178 DF8B      RCALL	_wt24c_fc
    0179 871C      STD	Y+12,R17
    017A 870B      STD	Y+11,R16
(0078)     	if(syserr!=0) return;
    017B 9020013D  LDS	R2,syserr
    017D 2022      TST	R2
    017E F009      BEQ	0x0180
    017F C025      RJMP	0x01A5
(0079) 		
(0080) 		num-=n;     //更新剩下数据个数
    0180 18CA      SUB	R12,R10
    0181 08DB      SBC	R13,R11
(0081)         ad_dst+=n;	//更新剩下数据的起始地址
    0182 0CEA      ADD	R14,R10
    0183 1CFB      ADC	R15,R11
    0184 C013      RJMP	0x0198
(0082) 
(0083)         //把剩下数据写入器件
(0084)         while(num>=PAGE_SIZE)	//先按PAGE_SIZE为长度一页一页的写入
(0085)         {
(0086) 		 	p_rsc=wt24c_fc(p_rsc, ad_dst, PAGE_SIZE);
    0185 E088      LDI	R24,0x8
    0186 8388      STD	Y+0,R24
    0187 0197      MOVW	R18,R14
    0188 850B      LDD	R16,Y+11
    0189 851C      LDD	R17,Y+12
    018A DF79      RCALL	_wt24c_fc
    018B 871C      STD	Y+12,R17
    018C 870B      STD	Y+11,R16
(0087)         	if(syserr!=0) return;
    018D 9020013D  LDS	R2,syserr
    018F 2022      TST	R2
    0190 F009      BEQ	0x0192
    0191 C013      RJMP	0x01A5
(0088)         	
(0089)             num-=PAGE_SIZE;		//更新剩余数据个数
    0192 01C6      MOVW	R24,R12
    0193 9708      SBIW	R24,0x8
    0194 016C      MOVW	R12,R24
(0090)         	ad_dst+=PAGE_SIZE;	//更新剩下数据的起始地址
    0195 01C7      MOVW	R24,R14
    0196 9608      ADIW	R24,0x8
    0197 017C      MOVW	R14,R24
    0198 01C6      MOVW	R24,R12
    0199 3088      CPI	R24,0x8
    019A E0E0      LDI	R30,0
    019B 079E      CPC	R25,R30
    019C F740      BCC	0x0185
(0091) 		}
(0092)         
(0093) 		if(num)			//把最后剩下的小于一个PAGE_SIZE长度的数据写入器件
    019D 3080      CPI	R24,0
    019E 0789      CPC	R24,R25
    019F F029      BEQ	0x01A5
(0094) 			wt24c_fc(p_rsc, ad_dst, num);
    01A0 82C8      STD	Y+0,R12
    01A1 0197      MOVW	R18,R14
    01A2 850B      LDD	R16,Y+11
    01A3 851C      LDD	R17,Y+12
    01A4 DF5F      RCALL	_wt24c_fc
(0095)     }
    01A5 9621      ADIW	R28,1
    01A6 940E04A5  CALL	pop_gset5
    01A8 9624      ADIW	R28,4
    01A9 9508      RET
_rd24c:
  t                    --> R10
  num                  --> R22
  ad_rsc               --> R12
  p_dst                --> R20
    01AA 940E04AA  CALL	push_gset4
    01AC 0169      MOVW	R12,R18
    01AD 01A8      MOVW	R20,R16
    01AE 8568      LDD	R22,Y+8
    01AF 8579      LDD	R23,Y+9
(0096) }
(0097) /*************************************************************************
(0098) ** 函数名称: 
(0099) ** 功能描述: 从24cxx读出数据
(0100) ** 输 入: *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形)
(0101) ** 输出	 : 
(0102) ** 全局变量: 无
(0103) ** 调用模块: 
(0104) ** 说明:ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
(0105) ** 注意:
(0106) **************************************************************************/
(0107) void rd24c(unsigned char *p_dst, unsigned int ad_rsc, unsigned int num)
(0108) {
(0109)     unsigned char t=0;
    01B0 24AA      CLR	R10
(0110) 
(0111) 	#if e2prom<32
(0112) 	t=ad_rsc>>8;
    01B1 0156      MOVW	R10,R12
    01B2 2CAB      MOV	R10,R11
    01B3 24BB      CLR	R11
(0113) 	t<<=1;
    01B4 0CAA      LSL	R10
(0114) 	#endif
(0115) 	
(0116) 	i2cstart();					//发送起始信号
    01B5 940E00E0  CALL	_i2cstart
(0117) 		
(0118) 	if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址
    01B7 2D0A      MOV	R16,R10
    01B8 5600      SUBI	R16,0x60
    01B9 940E00E8  CALL	_i2cwt
    01BB 3108      CPI	R16,0x18
    01BC F4B1      BNE	0x01D3
(0119) 	{	
(0120) 		#if e2prom>16
(0121) 		i2cwt(ad_rsc>>8);		//ad_rsc的高位,  发送要读出数据的地址
(0122) 		#endif
(0123) 		i2cwt(ad_rsc);			//ad_rsc的低位
    01BD 2D0C      MOV	R16,R12
    01BE 940E00E8  CALL	_i2cwt
(0124) 				
(0125) 		i2cstart();				//再发送起始信号
    01C0 940E00E0  CALL	_i2cstart
(0126) 		i2cwt(R_ADD_COM+t);		//发送SLA_R, 读命令字节及器件地址
    01C2 2D0A      MOV	R16,R10
    01C3 550F      SUBI	R16,0x5F
    01C4 940E00E8  CALL	_i2cwt
(0127) 				
(0128) 		for(;num>0;num--)
    01C6 C008      RJMP	0x01CF
(0129) 		{
(0130) 		    *p_dst=i2crd();		//从器件读出一个字节
    01C7 940E00F6  CALL	_i2crd
    01C9 01FA      MOVW	R30,R20
    01CA 8300      STD	Z+0,R16
(0131) 			p_dst++;
    01CB 5F4F      SUBI	R20,0xFF
    01CC 4F5F      SBCI	R21,0xFF
    01CD 5061      SUBI	R22,1
    01CE 4070      SBCI	R23,0
    01CF 3060      CPI	R22,0
    01D0 0767      CPC	R22,R23
    01D1 F7A9      BNE	0x01C7
(0132) 		}
(0133) 	}
    01D2 C003      RJMP	0x01D6
(0134) 	else syserr=ERR_SLAW;		//写字节命令及器件地址错或对方无应答
    01D3 E081      LDI	R24,1
    01D4 9380013D  STS	syserr,R24
(0135) 		
(0136) 	i2cstop();
    01D6 940E0100  CALL	_i2cstop
    01D8 940E04A2  CALL	pop_gset4
    01DA 9508      RET
FILE: D:\avrvi\AVRVi_m128_Starter_Kit\USART_24C01\source\lib\delay.c
(0001) /************************************************
(0002) 文件:delay.c
(0003) 用途:延时函数
(0004) 注意:系统时钟8M
(0005) 创建:2008.1.25
(0006) 修改:2008.1.25
(0007) Copy Right  (c)  www.avrvi.com  AVR与虚拟仪器
(0008) ************************************************/
(0009) 
(0010) void delay_1us(void)                 //1us延时函数
(0011)   {
(0012)    asm("nop");
_delay_1us:
    01DB 0000      NOP
    01DC 9508      RET
_delay_nus:
  i                    --> R20
  n                    --> R22
    01DD 940E04AE  CALL	push_gset2
    01DF 01B8      MOVW	R22,R16
(0013)   }
(0014) 
(0015) void delay_nus(unsigned int n)       //N us延时函数
(0016)   {
(0017)    unsigned int i=0;
    01E0 2744      CLR	R20
    01E1 2755      CLR	R21
(0018)    for (i=0;i<n;i++)
    01E2 C003      RJMP	0x01E6
(0019)    delay_1us();
    01E3 DFF7      RCALL	_delay_1us
    01E4 5F4F      SUBI	R20,0xFF
    01E5 4F5F      SBCI	R21,0xFF
    01E6 1746      CP	R20,R22
    01E7 0757      CPC	R21,R23
    01E8 F3D0      BCS	0x01E3
    01E9 940E049C  CALL	pop_gset2
    01EB 9508      RET
(0020)   }
(0021)   
(0022) void delay_1ms(void)                 //1ms延时函数
(0023)   {
(0024)    unsigned int i;
(0025)    for (i=0;i<1140;i++);
_delay_1ms:
  i                    --> R16
    01EC 2700      CLR	R16
    01ED 2711      CLR	R17
    01EE C002      RJMP	0x01F1
    01EF 5F0F      SUBI	R16,0xFF
    01F0 4F1F      SBCI	R17,0xFF
    01F1 3704      CPI	R16,0x74
    01F2 E0E4      LDI	R30,4
    01F3 071E      CPC	R17,R30
    01F4 F3D0      BCS	0x01EF
    01F5 9508      RET
_delay_nms:
  i                    --> R20
  n                    --> R22
    01F6 940E04AE  CALL	push_gset2
    01F8 01B8      MOVW	R22,R16
(0026)   }
(0027)   
(0028) void delay_nms(unsigned int n)       //N ms延时函数
(0029)   {
(0030)    unsigned int i=0;
    01F9 2744      CLR	R20
    01FA 2755      CLR	R21
(0031)    for (i=0;i<n;i++)
    01FB C003      RJMP	0x01FF
(0032)    delay_1ms();
    01FC DFEF      RCALL	_delay_1ms
    01FD 5F4F      SUBI	R20,0xFF
    01FE 4F5F      SBCI	R21,0xFF
    01FF 1746      CP	R20,R22
    0200 0757      CPC	R21,R23
    0201 F3D0      BCS	0x01FC
    0202 940E049C  CALL	pop_gset2
    0204 9508      RET
FILE: D:\avrvi\AVRVi_m128_Starter_Kit\USART_24C01\source\lib\sio.c
(0001) /************************************************
(0002) 文件:sio.c
(0003) 用途:结构化串口通信程序
(0004) 注意:
(0005) 创建:2008.1.26
(0006) 修改:2008.1.26
(0007) Copy Right  (c)  www.avrvi.com  AVR与虚拟仪器
(0008) ************************************************/
(0009) #include "..\config.h"
(0010) 
(0011) #if USEUART0
(0012) siocirqueue RTbuf_UART0;
(0013) #endif
(0014) #if USEUART1
(0015) siocirqueue RTbuf_UART1;
(0016) #endif
(0017) 
(0018) #if (CPU_TYPE == M32)||(CPU_TYPE == M16)||(CPU_TYPE == M8)
(0019) #define USEUART0  TRUE
(0020) #define USEUART1  FALSE
(0021) #define iv_USART0_RXC   iv_USART_RXC
(0022) #define iv_USART0_TXC   iv_USART_TXC
(0023) #define UDR0  	  UDR 
(0024) #define UCSR0A    UCSRA
(0025) #define UCSR0B    UCSRB
(0026) #define UCSR0C	  UCSRC
(0027) #define UBRR0H	  UBRRH
(0028) #define UBRR0L	  UBRRL
(0029) #define RXCIE0	  RXCIE
(0030) #define TXCIE0	  TXCIE
(0031) #endif
(0032) 
(0033) 
(0034) /*********************************************************************************************************
(0035) ** 函数名称: Com_init
(0036) ** 功能描述: 初始化串行口
(0037) ** 输 入: 
(0038) ** 全局变量: 无
(0039) ** 调用模块: Com_baudrate
(0040) ** 说明:
(0041) ** 注意:
(0042) ********************************************************************************************************/
(0043) void Com_init (void) {
(0044) //WDR(); //喂狗 
(0045) //CLI();                     // 关中断
(0046) #if USEUART0
(0047) Tbuf_init(&RTbuf_UART0);              //初始化接收缓冲
_Com_init:
    0205 E30E      LDI	R16,0x3E
    0206 E011      LDI	R17,1
    0207 D0BB      RCALL	_Tbuf_init
(0048) Rbuf_init(&RTbuf_UART0);
    0208 E30E      LDI	R16,0x3E
    0209 E011      LDI	R17,1
    020A D0AF      RCALL	_Rbuf_init
(0049) UCSR0B = 0x00; //disable while setting baud rate
    020B 2422      CLR	R2
    020C B82A      OUT	0x0A,R2
(0050) UCSR0A=0x00;
    020D B82B      OUT	0x0B,R2
(0051) 
(0052) #if CPU_TYPE <= M32
(0053) UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
(0054) UCSR0B = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);  // RXCIE=1;TXCIE=1;UDREIE=0;RXEN=1;TXEN=1
(0055) #else
(0056) UCSR0C=0x06;  //8 DATA ,1 STOP, NO PARITY
    020E E086      LDI	R24,6
    020F 93800095  STS	0x95,R24
(0057) UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);  // RXCIE=1;TXCIE=1;UDREIE=0;RXEN=1;TXEN=1
    0211 ED88      LDI	R24,0xD8
    0212 B98A      OUT	0x0A,R24
(0058) #endif
(0059) 
(0060) #endif
(0061) 
(0062) 
(0063) #if USEUART1
(0064) Tbuf_init(&RTbuf_B);              //初始化接收缓冲
(0065) Rbuf_init(&RTbuf_B);
(0066) UCSR1B = 0x00; //disable while setting baud rate
(0067) UCSR1A = 0x00;

⌨️ 快捷键说明

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