; /*EEPROM的读写*/
;本文件提供四个函数,对MEM(24C02)进行读写
;ReadMemByte
;ReadMemBlock
;WriteMemByte
;WriteMemBlock
;---------------------------------------------------------
;从EEPROM中读一个字节,函数返回值R15
;unsigned char ReadMemByte(unsigned char Addr)
;入口:R15
;出口:R15
;资源: R14,R15
;引用:供外部用作从MEM读1BYTE的函数
ReadMemByte:
PUSH R15 ;保存Addr堆栈
;StartI2C(0x51)
LD R15,#0a0h
CALL StartI2C
;写入地址并读出数所
POP R15
CALL WriteI2C ;写地址
CALL StopI2C
LD R15,#0a1h
CALL StartI2C
LD R12,#01h
CALL ReadI2C ;返回值R15
CALL StopI2C
RET
;---------------------------------------------------------
;从EEPROM中读Len个字节到Dst
;void ReadMemBlock(unsigned char Addr,unsigned char *Dst,unsigned char Len)
;入口:R15--Addr,R13--&Dst,R12--Len
;出口:
;资源: R14
;方法:
; LD R15,#E_Addr
; LD R13,#Var_Addr
; LD R12,#Len
; CALL ReadMemBlock ;从NVRAM读
;引用:供外部用作从MEM读LEN个BYTE的函数
ReadMemBlock:
PUSH R15 ;保存地址
LD R15,#0a0h
CALL StartI2C
POP R15 ;恢复地址
CALL WriteI2C
CALL StopI2C
LD R15,#0a1h
CALL StartI2C
;读R12个数据
ReadMB_Loop:
CALL ReadI2C
LD @R13,R15
INC R13
DEC R12
JR NZ,ReadMB_Loop
CALL StopI2C
OR BTCON,#BIT1 ;WatchDog
RET
;---------------------------------------------------------
;
;向EEPROM中写一个字节Sdata到Addr,函数返回值C为ACK是否正确
;bit WriteMemByte(unsigned char Addr,unsigned char SData)
;入口:R15--Addr,R13--Sdata
;出口:
;资源: R13,(R14,)R15
;引用:供外部用作向MEM写1BYTE的函数
WriteMemByte:
PUSH R15 ;暂存地址
OR BTCON,#BIT1 ;WatchDog
LD R15,#0a0h
CALL StartI2C
POP R15
CALL WriteI2C ;写入地址
LD R15,R13
CALL WriteI2C ;写入数据
CALL StopI2C
LD R15,#10
CALL Delay
RET
;---------------------------------------------------------
;
;向EEPROM中写Len个字节Sdata到Addr,函数返回值C为ACK是否正确
;bit WriteMemBlock(unsigned char Addr,unsigned char *Sdata,unsigned char Len)
;入口:R15--Addr,R13--&Sdata,R12--Len
;出口:
;资源: R12,R13,(R14,)R15
; LD R15,#E_Addr
; LD R13,#Var_Addr
; LD R12,#Len
; CALL WriteMemBlock ;
;引用:供外部用作向MEM写LEN长度(BYTE)的函数
WriteMemBlock:
PUSH R0
PUSH R1
LD R0,R15
LD R1,R13
;写R12个数据
WriteMB_Loop:
LD R15,R0
LD R13,@R1
CALL WriteMemByte ;WriteI2C
INC R0
INC R1
DEC R12
JR NZ,WriteMB_Loop
POP R1
POP R0
RET
;---------------------------------------------------------
;
;开始向设备0读或写作好准备
;void StartI2C(unsigned char Device)
;入口:R15
;出口:
;资源: R14,R5
;引用:本文件内的读、写函数
StartI2C:
AND P1CON,#03fh ;SCL作为输入
OR P1PUR,#008h ;SCL上拉使能
OR P1,#SCL ;SCL = 1
OR P2CON,#040h ;设SDA输出
OR P2PUR,#008h ;SDA上拉使能,以便输入,但此时为输出
OR P2,#SDA ;SDA = 1
;等设备释放总线
LD R5,#0ffh
StartI2C_1:
DEC R5
JR Z,StartI2C_2
TM P1,#SCL
JR Z,StartI2C_1
;开始对设备进行操作
StartI2C_2:
OR P1CON,#040h ;SCL作为输出
AND P1PUR,#0f7h ;SCL禁止上拉
NOP
AND P2,#~SDA ;SDA = 0
NOP
AND P1,#~SCL ;SCL = 0
CALL WriteI2C
JR NC,StartI2C
RET
;---------------------------------------------------------
;从设备处得到ACK响应
;bit GetAckI2C(void)
;入口:
;出口:C
;资源:
;引用:本文件内的读、写函数
GetAckI2C:
AND P2CON,#03fh ;SDA为输入
OR P1,#SCL ;SCL = 1
NOP
TM P2,#SDA
JR Z,GetAckI2C_1
AND P1,#~SCL ;SCL = 0
RCF
RET
GetAckI2C_1:
AND P1,#~SCL ;SCL = 0
SCF
RET
;---------------------------------------------------------;
;使设备停止
;void StopI2CA(void)
;入口:
;出口:R15
;资源: R14
;引用:本文件内的读、写函数
StopI2C:
OR P2CON,#040h ;SDA输出
AND P2,#~SDA ;SDA = 0
NOP
OR P1,#SCL ;SCL = 1
NOP
OR P2,#SDA ;SDA = 1
NOP
AND P1,#~SCL
AND P2,#~SDA ;SDA = 0
RET
;---------------------------------------------------------
;向设备写一个字节的命令或数据或地址,返回值C=1为成功
;bit WriteI2C(const unsigned char SendData)
;入口:R15
;出口:C
;资源: R14
;引用:本文件内的读、写函数
WriteI2C:
LD R14,#008h
AND P2CON,#07fh
OR P2CON,#040h ;SDA输出
;用R14作变量,进行一个字节的传送
WriteI2C_Loop:
TM R15,#080h
JR Z,WriteI2C_1
OR P2,#SDA ;SDA = 1
JR WriteI2C_2
WriteI2C_1:
AND P2,#~SDA ;SDA = 0
NOP
WriteI2C_2:
OR P1,#SCL ;SCL = 1
NOP
AND P1,#~SCL ;SCL = 0
RL R15
DEC R14
JR NZ,WriteI2C_Loop
CALL GetAckI2C
JR NC,WriteI2C_Error
RET
WriteI2C_Error:
CALL StopI2C
RET
;---------------------------------------------------------
;
;从设备中读出一个字节,返回值R15;中间用到资源R14
;unsigned char ReadI2C(void)
;入口:
;出口:R15
;资源: R14
;引用:本文件内的读函数
ReadI2C:
AND P2CON,#03fh ;SDA为输入
CLR R15
LD R14,#080h
ReadI2C_Loop:
OR P1,#SCL ;SCL = 1
NOP
TM P2,#SDA
JR Z,ReadI2C_1
OR R15,R14
ReadI2C_1:
AND P1,#~SCL ;SCL = 0
RCF
RRC R14
JR NZ,ReadI2C_Loop
CP R12,#01h
JR EQ,ReadI2C_2
OR P2CON,#040h ;SDA为输出状态
AND P2,#~SDA
ReadI2C_2:
OR P1,#SCL
NOP
AND P1,#~SCL
RET
;---------------------------------------------------------
;一字节除以10
;入口:R15
;出口:R15,R13; R15= R15/10,R13 = R15 %10
;次源: R13,R14,R15
ByteDiv10:
LD R14,#10
LD R13,R15
CLR R15
Div10_Loop:
CP R13,R14
JR ULT,Div10_Exit
SUB R13,R14
INC R15
JR T,Div10_Loop
Div10_Exit:
RET
上一篇:GCC精彩之旅(2)
下一篇:基于ADμC812的温度检测系统的设计
推荐阅读最新更新时间:2024-03-16 13:52