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

📄 eeprom.asm

📁 各种Eeprom的C驱动程序(可配置)
💻 ASM
字号:
$LIST
;--------------------------------------------------------------
;	Eeprom.asm(for 8051 ASM) 
;
; 功能: I2C总线Eeprom驱动汇编程序 for 8051 serial
;
; Copyright(c) 2002-2003 Xiamen Yealink Network Technology Co,.Ltd
; By:Stonelu		2003.5.5
;--------------------------------------------------------------
	$include	(805Xasm.inc)

;使用此模块要定义存储器类型,本软件支持智能页写模式
;bioEepromSDA		equ P2.4; //数据线
;boEepromSCL		equ P2.5; //24C16的时钟脚
;boEepromWP		equ P2.6; //写保护线

;--------------------------------------
;AT24C01/02   	cnEepromBlockBytes	EQU	8
;AT24C04/08/16  cnEepromBlockBytes	EQU	16
;AT24C32/64	cnEepromBlockBytes	EQU	32
;AT24C128/256 	cnEepromBlockBytes	EQU	64
;--------------------------------------
cnEepromBlockBytes		equ 64
mEEprom32Up256			equ 1	;是 32,64,128,256					

;----	硬件定义
;EXTRN	BIT	(boEepromSCL)	;24C16的时钟脚
;EXTRN	BIT	(bioEepromSDA)	;数据线
;EXTRN	BIT	(boEepromWP)	;写保护线

;---	子程序
;EXTRN	CODE	(_Delay10ms)	;延时10ms (只能使用A,B,R7)
;EXTRN	CODE	(_Delay6us)	;延时6us (不能使用任何变量)
;EXTRN	CODE	(_IncR23)

;~~~
PUBLIC	_EepromRD		;单个字节读 _EepromRD(R2R3)
PUBLIC	_EepromWR		;单个字节写 _EepromWR(R2R3,ACC)
PUBLIC	_EepromWRX		;单个字节写 _EepromWR(R2R3,ACC)
PUBLIC	_EepromBlockRead	;块读 _EepromBlockRead(R2R3,R0,ACC)
PUBLIC	_EepromBlockWrite	;块写 _EepromBlockWrite(R2R3,R0,ACC)
PUBLIC	_EepromBlockReadX	;块读 _EepromBlockRead(R2R3,R0,ACC)
PUBLIC	_EepromBlockWriteX	;块写 _EepromBlockWrite(R2R3,R0,ACC)
PUBLIC	_IncR23			;R23++(R2=H)
PUBLIC	_DecR23			;R23--(R2=H)
EXTRN  CODE	(ResetSysWDT)
EXTRN	DATA (SoftWDTimer)

EepromBseg	SEGMENT	BIT
		RSEG	EepromBseg
bEepUseXD:	dbit	1	;使用外部Ram标志
		
;==============================================================
EepromCseg SEGMENT 	CODE
	RSEG	EepromCseg
	
;--------------------------------------------------------------
;	_EepromBlockRead	从EEprom读取一块数据
;
; in	R2 = High Address    EEpROM高位地址
;	R3 = Low Address     EEpROM低位地址
;	R0  = 存放数据的内部RAM指针
;	ACC = 要读取的个数
; out	C=0  OK  A=R5 读取的数据
;	 =1  Error
; used	ACC,B,R0,R1,R6,R7
;--------------------------------------------------------------	
_EepromBlockReadX:
	setb	bEepUseXD
	sjmp	LEepromBlockRead01
_EepromBlockRead:
	clr	bEepUseXD
LEepromBlockRead01:
	setb	boEEpromWP		;防止误写入
	sjmp	_EepromBlockWrite05

;--------------------------------------------------------------
;	_EepromRD	从EEprom读取一个数据
;
; in	R2 = High Address    EEpROM高位地址
;	R3 = Low Address     EEpROM低位地址
; out	C=0  OK  A=R5 读取的数据
;	 =1  Error
; used	ACC,B,R0,R1,R6,R7
;--------------------------------------------------------------	
_EepromRD:
	clr	bEepUseXD
	setb	boEEpromWP
	sjmp	_EepromWR05
	
;--------------------------------------------------------------
;	_EepromWR	写一字节到eeprom
;
; in	R2 = High Address    EEpROM高位地址
;	R3 = Low Address     EEpROM低位地址
;	ACC  写入EEpROM的数据
; out	C=0  OK (A=R5)
;	 =1  Error
; used	ACC,B,R0,R1,R6,R7
;--------------------------------------------------------------
	USING	0		;使用寄存器0
_EepromWRX:
	setb	bEepUseXD
	sjmp	LEepromWR01
_EepromWR:
	clr	bEepUseXD
LEepromWR01:
	clr	boEEpromWP
	mov	R1,A		;将要写入的数放在R5数据
_EepromWR05:
	mov	A,#AR1
	mov	R0,A		;R0为R1的地址
	mov	A,#1
	sjmp	_EepromBlockWrite05	
	
;--------------------------------------------------------------
;	_EepromBlockWrite  写一块内容到eeprom
;
; in	R2 = High Address    EEpROM高位地址
;	R3 = Low Address     EEpROM低位地址
;	R0  = 要写入的内容指针 
;	ACC  写入EEpROM的字节长度
; out	C=0  OK   R0=R0+len(写入的长度)
;	 =1  Error
; used	ACC,B,R0,R1,R6,R7
;--------------------------------------------------------------
_EepromBlockWriteX:
	setb	bEepUseXD
	sjmp	LEepromBlockWrite01
_EepromBlockWrite:
	clr	bEepUseXD
LEepromBlockWrite01:
	clr	boEEpromWP
_EepromBlockWrite05:	
	mov	R6,A
LEepromBlockWrite10:	
;	LCALL	_FeeWatchDog
	mov	A,#0
	lcall	_EepromStartDevice	;送start和device 命令
	jc	LEepromBlockWrite40
	
LEepromBlockWrite12:
     
     if mEEprom32Up256    			
	mov	A,R2
	lcall	_SendByteACK		;等待确认信号,送数据高位地址
	jc	LEepromBlockWrite40
     endif

	mov	A,R3			 ;送数据低位地址
	lcall	_SendByteACK
	jc	LEepromBlockWrite40

;---	读操作
	jnb	boEEpromWP,LEepromBlockWrite30
	mov	A,#1
	lcall	_EepromStartDevice     	;EEpROM再次进入开始状态,并送读命令
	jc	LEepromBlockWrite40
LEepromBlockWrite26:	
	lcall	_ReadByte	       	;读取数据
	jnb	bEepUseXD,LEepromBlockWrite26A
	movx	@R0,A
	sjmp	LEepromBlockWrite26B
LEepromBlockWrite26A:	
	mov	@R0,A
LEepromBlockWrite26B:			
	inc	R0
	lcall	_IncR23			;inc	DPTR
	djnz	R6,LEepromBlockWrite28	;R6!=0 branch
	lcall	_EEpromStop
	sjmp	LEepromBlockWrite38 	;数据已经读完
LEepromBlockWrite28:	
	lcall	_OutputACK		;读取下一个数
	sjmp	LEepromBlockWrite26
	
	
;--- 	写操作
LEepromBlockWrite30:
	jnb	bEepUseXD,LEepromBlockWrite30A
	movx	A,@R0
	sjmp	LEepromBlockWrite30B
LEepromBlockWrite30A:
	mov	A,@R0
LEepromBlockWrite30B:	
	lcall	_SendByteACK		;将数据写入EEpROM
	jc	LEepromBlockWrite40
	inc	R0
	lcall	_IncR23
	dec	R6
	cje	R6,#0,LEepromBlockWrite32 ;判断数据已经写完
	mov	A,R3				
	anl	A,#(cnEepromBlockBytes-1)
	jnz	LEepromBlockWrite30	;表示一页没有完成
LEepromBlockWrite32:	
	lcall	_EepromStop		;EEpROM进入停止状态
	mov	R7,#200
LEepromBlockWrite34:			;查询,是否已经写结束
	push	AR7
	mov	A,#0
	lcall	_EEpromStartDevice
	pop	AR7
	jnc	LEepromBlockWrite36
	djnz	R7,LEepromBlockWrite34
	sjmp	LEepromBlockWrite40	;测试,如果200次查询没通过,认为错误
LEepromBlockWrite36:
	cjne	R6,#0,LEepromBlockWrite12
	lcall	_EEpromStop		;因为查询,所以要停止

;---	读写完成(OK出口)
LEepromBlockWrite38:	
	setb	boEEpromWP
	clr	C
	ret

;---	读写错误返回出口	
LEepromBlockWrite40:
	setb	boEEpromWP
	;///
	setb	boEepromSCL
	setb	bioEepromSDA
	;///
	setb 	C
	ret

;=====	_EEpromStartDevice
; in:	ACC=0 发送读命令
;	   =1 发送写命令
; out	C=0 OK
;	 =1 Error,NO ACKR

_EEpromStartDevice:
	push	ACC
	lcall	_EEpromStart
	pop	ACC
_EEpromDevcie:		
	mov	B,A			;in ACC=0 Write  =1 Read
     if mEEprom32Up256    			;=1 要兼容24C32/64/128/256操作
	mov	A,#10100000B		;送器件地址
     else
     	mov	A,R2
	anl	A,#111B
	rl	A
	orl	A,#10100000b		;送器件地址
     endif	
     	orl	A,B
	sjmp	_SendByteACK		;等待确认信号,送数据高位地址
	

;=====	_SendByteACK
; in:	ACC  发送的数据,并等待ACK
; para: T=90us
; out	C=0 OK
;	 =1 Error,NO ACKR

_SendByteACK:
	mov	R7,#8
SDBY12: rlc	A		 ;写数据字节
	mov	bioEepromSDA,C
	lcall	_Delay6us	 ;_Delay6us
	setb	boEepromSCL
	lcall	_Delay6us
	clr	boEepromSCL
	djnz	R7,SDBY12	
	sjmp	_EepromACK	

;=====	_EepromACK
; out	C=0 OK
;	 =1 Error
; para	T=10us
; used	R7

_EepromACK:
	setb	bioEepromSDA
	setb	boEepromSCL

	mov	R7,#5
LEepromACK12: 
	jnb	bioEepromSDA,LEepromACK20		;延迟20us
	djnz	R7,LEepromACK12		;2
	clr	boEepromSCL
	setb	C
	ret
LEepromACK20:
	clr	boEepromSCL
	clr	C
	ret


;=====	_ReadByte
; out	ACC  读取的数据
; para: T=90us

_ReadByte:
	mov	R7,#8
LReadByte10:
	setb	boEepromSCL	    ;1
	setb	bioEepromSDA 	    ;1
	nop			    ;1
	nop			    ;1
	mov	C,bioEepromSDA	    ;2	读取数据
	clr	boEepromSCL	    ;1
	rlc	A		    ;1
	djnz	R7,LReadByte10	    ;2
	ret

;====	_EepromStart
; para: T=24us

_EepromStart:
	clr	boEepromSCL
	nop
	setb	bioEepromSDA
	setb	boEepromSCL
	lcall	_Delay6us
	clr	bioEepromSDA
	lcall	_Delay6us
	clr	boEepromSCL
	ret


;=====	_EepromStop
; para: T=30us

_EepromStop:
	clr	boEepromSCL
	lcall	ResetSysWDT		;Reset WDT
	mov	SoftWDTimer,#00
	;nop
	clr	bioEepromSDA
	setb	boEepromSCL
	lcall	_Delay6us
	setb	bioEepromSDA
	lcall	_Delay6us
;	clr	boEepromSCL
	ret


;====	_OutputACK   向Eeprom发一ACK信号

_OutputACK:
	clr	bioEepromSDA
	lcall	_Delay6us
	setb	boEepromSCL
	lcall	_Delay6us
	clr	boEepromSCL
	setb	bioEepromSDA
	ret
	
;====	_IncR23
; in	R23 R2=H,R3=L
; out	R23=R23+1

_IncR23:
	inc	R3
	cjne	R3,#0,LIncR2310
	inc	R2
LIncR2310:
	ret	

;====	_DecR23
;in	R23 R2=H,R3=L
;out	R23=R23-1

_DecR23:
	dec	R3
	cjne	R3,#0ffH,LDecR2310
	dec	R2
LDecR2310:
	ret
	
_Delay6us:
		nop
		nop
if	mOSC22d1184
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
endif
		ret
;****************************************************************
$LIST
	END


⌨️ 快捷键说明

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