|
; /*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 ; 2004.8 wyanxi
|