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

2008-3-25 19:45 1707 4 4 分类: MCU/ 嵌入式

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


;******************************************


;** 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总线读/写的程序全部结束 !


;****************************


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条