新闻  |   论坛  |   博客  |   在线研讨会
24CXX系列读写程序(EMC指令版)
zhchxgh | 2009-07-05 14:22:14    阅读:1208   发布文章

24CXX系列读写程序(EMC指令版)

;******************************************
;** 24CXX  接口I2C总线读/写的程序
;**  (所有时序均基于4MHZ晶体震荡器频率)
;******************************************
/*
;****************************
;随机读写测试程序(示范程序)
;****************************
TEST:
    MOV    A,@0XAE        ;A2=A1=A0=1
    MOV    SLAVE_24,A    ;设置器件码
    MOV    A,@2        ;R/W LOC. = 2
    MOV    ADDR_24,A    ;设置地址码
    MOV    A,@55        ;
    MOV    DATA_24,A    ;写55到E2PROM
    CALL    WRBYTE        ;写一个字节
    CALL    DL10MS        ;延时10MS,等待写操作完成(注意,此语句非常重要)
    CALL     RDBYTE        ;读回原数据
    MOV    A,@55        ;
    XOR    A,DATA_24    ;
    JBS    R3,Z        ;读出数据=写入数据跳
WRONG:
    JMP    WRONG        ;校验失败
CORRECT:
    JMP    CORRECT        ;校验通过
DL10MS:
    RET    
;****************************
;存储器定义
;****************************
PROT_I2C    EQU    0X05    ;I2C操作口
    SDA    EQU    3    ;数据脚
    SCL    EQU    2    ;时钟脚

ADDR_24    EQU    0X1B        ;地址寄存器
DATA_24    EQU    0X1C        ;写入/读自I2C的数据寄存器
SLAVE_24 EQU    0X1D        ;从器件地址寄存器(1010XXX0)
DBUF_24    EQU    0X1E        ;发送/接受自SDA口的数据缓冲器
COUNT_24 EQU    0X1F        ;位计数器
TT_24    EQU    0X20        ;标志寄存器
    REND_24    EQU    1    ;读完毕标志(0=未完毕,1=完毕)
NUM_24    EQU    0X21        ;页写/页读字节数

*/
;****************************
;宏定义
;****************************
;=================
;设置SCL,SDA为输出口
;=================
SDA_OUT    MACRO
    MOV    A,@0B00000001   
    IOW    PROT_I2C
ENDM
;=================
;设置SCL为输出口,SDA为输入口
;=================
SDA_IN    MACRO
    MOV    A,@0B00001001
    IOW    PROT_I2C
ENDM
;****************************
;字节写程序
;功能:    写一个字节到EEPROM器件
;入口:    DATA_24    =要写的数据
;    ADDR_24    =数据地址
;    SLAVE_24=从器件地址1010XXX0)
;****************************
WRBYTE:
    MOV    A,SLAVE_24               
    MOV    DBUF_24,A        
    CALL    BSTART            ;送起始位
    CALL    TX            ;送从器件地址并检测应答信号
    MOV    A,ADDR_24        
    MOV    DBUF_24,A        
    CALL    TX            ;送数据地址并检测应答信号
    MOV    A,DATA_24        
    MOV    DBUF_24,A        
    CALL    TX            ;送数据并检测应答信号
    CALL    BSTOP            ;送停止位
    RET
;****************************
;字节读程序
;功能:    从EEPROM器件读一个字节
;入口:    ADDR_24    =数据地址
;    SLAVE_24=从器件地址(1010XXX0)
;出口:    DATA_24    =读到的数据
;****************************
RDBYTE:
    MOV    A,SLAVE_24
    MOV    DBUF_24,A
    CALL    BSTART            ;送起始位
    CALL    TX            ;送从器件地址并检测应答信号
    MOV    A,ADDR_24        
    MOV    DBUF_24,A
    CALL    TX            ;送数据地址并检测应答信号
;转入读状态    
    CALL    BSTART            ;送起始位    
    MOV    A,SLAVE_24           
    MOV    DBUF_24,A
    BS     DBUF_24,0            
    CALL    TX            ;送从器件地址并检测应答信号
    BS    TT_24,REND_24        
    CALL    RX            ;读数据并发送应答信号
    CALL    BSTOP            ;送停止位
    MOV    A,DBUF_24        
    MOV    DATA_24,A        ;保存数据到DATA_24
    RET
;****************************
;页写程序
;功能:    写一个字节到EEPROM器件
;入口:    R4    =要写的数据在RAM中存放首地址
;    NUM_24    =字节数
;    ADDR_24    =数据地址
;    SLAVE_24=从器件地址1010XXX0)
;****************************
WRPAGE:
    MOV    A,SLAVE_24               
    MOV    DBUF_24,A        
    CALL    BSTART            ;送起始位
    CALL    TX            ;送从器件地址并检测应答信号
    MOV    A,ADDR_24        
    MOV    DBUF_24,A        
    CALL    TX            ;送数据地址并检测应答信号
WRPAGE1:
    MOV    A,R0        
    MOV    DBUF_24,A        
    CALL    TX            ;送数据并检测应答信号
    INC    R4
    DJZ    NUM_24
    JMP    WRPAGE1            ;未写完继续
    CALL    BSTOP            ;送停止位
    RET
;****************************
;页读程序
;功能:    从EEPROM器件读一个字节
;入口:    ADDR_24    =数据地址
;    SLAVE_24=从器件地址(1010XXX0)
;    NUM_24    =字节数
;出口:    R4    =读到的数据在RAM中存放首地址
;****************************
RDPAGE:
    MOV    A,SLAVE_24
    MOV    DBUF_24,A
    CALL    BSTART            ;送起始位
    CALL    TX            ;送从器件地址并检测应答信号
    MOV    A,ADDR_24        
    MOV    DBUF_24,A
    CALL    TX            ;送数据地址并检测应答信号
;转入读状态    
    CALL    BSTART            ;送起始位    
    MOV    A,SLAVE_24           
    MOV    DBUF_24,A
    BS     DBUF_24,0            
    CALL    TX            ;送从器件地址并检测应答信号
RDPAGE1:
    MOV    A,@1
    XOR    A,NUM_24
    BS    TT_24,REND_24        
    JBS    R3,Z            ;NUM_24=1跳;判断是否最后一个字节,决定应答信号    
    BC    TT_24,REND_24        
    CALL    RX            ;读数据并发送应答信号
    MOV    A,DBUF_24        
    MOV    R0,A            ;保存数据到R0
    INC    R4
    DJZ    NUM_24
    JMP    RDPAGE1            ;未读完继续
    CALL    BSTOP            ;送停止位
    RET
;****************************
;I2C操作子程序(时序)集合
;****************************
;=================
;发送起始位程序
;说明:    当SCL=1时,向SDA发一个下降沿
;=================
BSTART:
    SDA_OUT                ;设置SDA为输出口
    BS    PROT_I2C,SDA        ;SDA=1
    NOP                ;延时0.6US
    BS    PROT_I2C,SCL        ;SCL=1
    NOP                ;延时0.6US
    BC    PROT_I2C,SDA        ;SDA=0
    NOP                ;延时0.6US
    BC    PROT_I2C,SCL        ;SCL=0
    NOP                ;延时0.6US
    RET
;=================
;发送结束位程序
;说明:    当SCL=1时,向SDA发一个上升沿
;=================
BSTOP:
    SDA_OUT                ;设置SDA为输出口
    BC    PROT_I2C,SDA        ;SDA=0
    NOP                ;延时0.6US
    BS    PROT_I2C,SCL        ;SCL=1
    NOP                ;延时0.6US
    BS    PROT_I2C,SDA        ;SDA=1
    NOP                ;延时0.6US
    RET
;=================
;位输入子程序
;说明:    当SCL=1时,从SDA上读电平
;出口:    C=从SDA上读入的位值    
;=================
BITIN:
    SDA_IN                ;设置SDA为输入口
    BS    PROT_I2C,SDA        ;SDA=1
    NOP                ;延时0.6US
    BS    PROT_I2C,SCL        ;SCL=1
    NOP                ;延时0.6US
    BC    R3,C
    JBC    PROT_I2C,SDA        
    BS    R3,C            ;C=SDA
    NOP                ;延时0.6US
    BC    PROT_I2C,SCL        ;SCL=0
    NOP                ;延时0.6US
    RET
;=================
;位输出子程序
;说明:    每当SCL=0时,改写SDA上的电平
;入口:    C=要写到SDA上的位值
;=================
BITOUT:
    SDA_OUT                ;设置SDA为输出口
    JBS    R3,C
    JMP    BIT0
    BS    PROT_I2C,SDA        ;SDA=C=1
    JMP    CLK1        
BIT0:
    BC    PROT_I2C,SDA        ;SDA=C=0
CLK1:
    NOP                ;延时0.6US
    BS    PROT_I2C,SCL        ;SCL=1
BIT2:
    NOP
    NOP
    BC    PROT_I2C,SCL        ;SCL=0
    RET
;============================
;接收数据子程序
;入口:    TT_24.REND_24    =读完毕标志
;出口:    DBUF_24    =接受到的数据(8_BIT)
;============================
RX:
    MOV    A,@8            ;循环次数=8
    MOV    COUNT_24,A
    CLR    DBUF_24
RXLP:
    CALL    BITIN            ;输入1_BIT
    RLC    DBUF_24            ;左移(带C)
    DJZ    COUNT_24        ;循环结束?
    JMP    RXLP
;设置应答信号位,如果读完毕则送1(NO_ACK)停止接受,否则送0(ACK)继续接受
    BS    R3,C        
    JBS    TT_24,REND_24        ;读完毕信号->C
    BC    R3,C        
    CALL    BITOUT            ;应答            
    RET
;============================
;发送数据子程序
;入口:    DBUF_24    =要发送的数据(8_BIT)
;============================
TX:
    MOV    A,@8            ;循环次数=8
    MOV    COUNT_24,A
TXLP:
    RLC    DBUF_24            ;左移(带C)
    CALL    BITOUT            ;输出1_BIT
    DJZ    COUNT_24        ;循环结束?
    JMP    TXLP        
    CALL    BITIN            ;读应答信号
    RET

;****************************
;I2C总线读/写的程序全部结束 !
;****************************

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客