×
嵌入式 > 技术百科 > 详情

s3c9228汇编写的I2C及一字节除法

发布时间:2020-06-22 发布时间:
|

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

 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实时控制.安全.如何加速实现未来工厂落地?