[讨论] 新手可要好好看看,里面可是很绕人的哦……

fengzheng   2007-1-17 11:53 楼主
::应用在69P42/43上
porta         equ    08h
portb        equ    09h
portc        equ    0ah
portd        equ    0bh
porte        equ    0ch
trisa        equ    18h
trisb        equ    19h
trisc        equ    1ah
trisd        equ    1bh
trise         equ     1ch
zEEPByte     equ    59h
;zNACKcount     equ    5ah
zi2cNACK     equ    5bh
zEEPportBuf      equ    5ch
zEEPBufferL    equ    5dh
zEEPBufferH     equ    5eh
zTemp         equ    5fh
pSCL         equ    0100b;portb
pSDA         equ    1000b;portb
EEPportCRdef   equ    1111b
EEPport     equ    portb
EEPportCR     equ    trisb
port_key     equ    portd;定义按键端口
tris_key     equ    trisd
;-------------------------------
delayRW:    nop
        nop
        nop
        nop
        rtni
;-------------------------------
ReadData:    ldi    zEEPByte,06h;写入7个字节
        ldi    zEEPportBuf,1100b;初始化zEEPportBuf
        ldi    dpl,0fh&f0_h
        ldi    dpm,0fh&(f0_h>>4)
        ldi    dph,0fh&(f0_h>>7);调整间接寻址寄存器
        call    WriteAddress
        call    I2Cstart
        ldi    zEEPBufferH,0ah
        ldi    zEEPBufferL,01h;读EEPROM命令
        call    EEPWriteByte
        call    checkACK
ReadOneByte:    call    EEPReadByte
        lda    zEEPBufferL
        sta    rzINX
        call    DPInc
        lda    zEEPBufferH
        sta    rzINX
        call    DPInc
        sbim    zEEPByte,01h
        bnc    ReadOver
        call    sendACK
        jmp    ReadOneByte
ReadOver:    call    sendNACK
        call    I2Cstop
        rtni        
;-------------------------------
WriteData:    ldi    zEEPByte,06h;写入7个字节
        ldi    zEEPportBuf,1100b;初始化zEEPportBuf
        ldi    dpl,0fh&f0_h
        ldi    dpm,0fh&(f0_h>>4)
        ldi    dph,0fh&(f0_h>>7);调整间接寻址寄存器        
        call    WriteAddress
writeNewByte:    lda    rzINX
        sta    zEEPBufferL
        call    DPInc
        lda    rzINX
        sta    zEEPBufferH
        call    DPInc
        call    EEPWriteByte
        call    checkACK
        sbim    zEEPByte,01h
        bc    writeNewByte
        call    I2Cstop
        rtni        
;-------------------------------
WriteAddress:    ldi    zEEPBufferH,0ah
        ldi    zEEPBufferL,00h;写EEPROM命令
        call    I2Cstart
        call    EEPWriteByte
        call    checkACK
        baz    wrAddressRet        
        ldi    zEEPBufferH,00h;EEPROM的写入起始地址
        ldi    zEEPBufferL,00h
        call    EEPWriteByte
        call    checkACK
wrAddressRet:    rtni
;-------------------------------
EEPReadByte:    ldi    zEEPBufferL,00h
        ldi    zEEPBufferH,00h
        ldi    EEPportCR,EEPportCRdef&(0fh^pSDA)|pSCL;SDA=input;SDA=output
        call    delayRW
        ldi    zi2cNACK,08h
shiftbyte_R:    lda    zEEPBufferL
        addm    zEEPBufferL
        lda    zEEPBufferH
        adcm    zEEPBufferH
        orim    zEEPportBuf,pSCL
        sta    EEPport
        call    delayRW
        lda    EEPport
        sta    zTemp
        andim    zTemp,pSDA
        baz    $+2
        orim    zEEPBufferL,01h
        andim    zEEPportBuf,(0fh^pSCL)
        sta     EEPport
        sbim    zi2cNACK,01H
        bnz    shiftbyte_R
exitread:    ldi    EEPportCR,EEPportCRdef|pSCL|pSDA;SCL=output;SDA=output
        call    delayRW
        rtni
;-------------------------------
EEPWriteByte:    ldi    zi2cNACK,08H
shiftbit_W:    andim    zEEPportBuf,(0fh^pSDA)
        lda    zEEPBufferL
        addm    zEEPBufferL
        lda    zEEPBufferH
        adcm    zEEPBufferH;zEEPBufferl\zEEPBufferH左移一位
        bnc    $+2
        orim    zEEPportBuf,pSDA
        lda    zEEPportBuf
        sta    EEPport
        call    delayRW
        orim    zEEPportBuf,pSCL
        sta    EEPport
        call    delayRW
        andim    zEEPportBuf,(0fh^pSCL)
        sta    EEPport
        sbim    zi2cNACK,01H
        bnz    shiftbit_W
exitwrite:    call    delayRW
        rtni        
;-------------------------------
DPInc:        adim    dpl,01h
        EOR    dpl
        adcm    dpm
        rtni        
;-------------------------------
sendNACK:    orim    zEEPportBuf,pSDA
        jmp    $+2;sendACK1
sendACK:    andim    zEEPportBuf,(0fh^pSDA);0fh^pSDA==!pSDA
sendACK1:    sta    EEPport
        call    delayRW
        orim    zEEPportBuf,pSCL
PSCLlow:    sta    EEPport
        call    delayRW         ;clock pulse width high>4us
        andim    zEEPportBuf,(0fh^pSCL)
        sta    EEPport        ;clock pulse width low>4.7us
        call    delayRW
        rtni
;-------------------------------
checkACK:    ldi    EEPportCR,EEPportCRdef&(0fh^pSDA)|pSCL ;portb:SDA=output mode
                 ;1111b       &0111b     |0100b portb:(SCL、1、0)=input mode
        call    delayRW
        orim    zEEPportBuf,pSCL
        sta    EEPport    
        call    delayRW        ;clock pulse width high>4.0us
        ldi    zi2cNACK,00H    ;initial rzTBR=0,no ACK
        lda    EEPport        ;check the ack from pSDA pin
        sta     zTemp
        andim   zTemp,pSDA
        bnz    $+2
        ldi     zi2cNACK,01H    ;return rzTBR=1,mean respond ACK
        andim    zEEPportBuf,(0fh^pSCL);clock pulse width low>4.7us
        sta    EEPport
        call    delayRW
        ldi    EEPportCR,EEPportCRdef|pSCL|pSDA;set SCL and SDA as output
        lda    zi2cNACK            ;return the ack flag
        rtni
;-------------------------------
I2Cstart:    ldi    EEPport,pSDA|pSCL
        ldi    EEPportCR,EEPportCRdef|pSDA|pSCL;set sda and scl as output mode    
        call    delayRW
                orim    zEEPportBuf,pSDA    ;pull high SDA to prepare IIC
                sta     EEPport
        call    delayRW
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW             ;start setup time>4.7us
                andim    zEEPportBuf,(0fh^pSDA)    ;pull low SDA to start IIC
                sta    EEPport                  ;start hold time>4us
        call    delayRW
                andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;start        
        ;-------------------------------
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;9个'1'
        ;------------------------------------------------------------
                orim    zEEPportBuf,pSDA    ;pull high SDA to prepare IIC
                sta     EEPport
        call    delayRW
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW             ;start setup time>4.7us
                andim    zEEPportBuf,(0fh^pSDA)    ;pull low SDA to start IIC
                sta    EEPport                  ;start hold time>4us
        call    delayRW
                andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
                sta     EEPport
        call    delayRW            ;start    
        ;------------------------------------------------------------
                orim    zEEPportBuf,pSCL    ;pull high SCL to prepare IIC
                sta    EEPport
        call    delayRW
                orim    zEEPportBuf,pSDA    ;pull high SDA to prepare IIC
                sta     EEPport
        call    delayRW            ;stop
        ;------------------------------------------------------------
        lda    EEPport
        ba2    $+2
        jmp    $            ;SCL=0
        ba3    $+2            
        jmp    $            ;SDA=0
        
              andim    zEEPportBuf,(0fh^pSDA)    ;pull low SDA to start IIC
              sta    EEPport                  ;start hold time>4us
        call    delayRW
        andim   zEEPportBuf,(0fh^pSCL)    ;pull low SCL
              sta     EEPport
        call    delayRW            ;start            
              rtni
;-------------------------------
I2Cstop:      andim    zEEPportBuf,(0fh^pSDA)    ;pull low SDA to prepare IIC stop
        sta    EEPport
        call    delayRW
        orim   zEEPportBuf,pSCL          ;pull high SCL
        sta    EEPport
        call    delayRW                  ;stop setup time>4.7us
        orim    zEEPportBuf,pSDA          ;pull high SDA to stop IIC
        sta    EEPport
        call    delayRW                  ;bus free before a new transmission start>4.7us
        lda    EEPport
        ba2    $+2
        jmp    $            ;SCL=0
        ba3    $+2            
        jmp    $            ;SDA=0
        
              andim  zEEPportBuf,(0fh^pSCL);pull low SCL
              sta    EEPport
        call    delayRW
              rtni

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复