;------------Подпрограммы нижнего уровня,обслуживающие интерфейс I2C-----------

resi2c: push    psw           ;подпрограмма приема байта по шине I2C:
        push    0             ;сохранить изменяемые регистры
        mov     r0,#8         ;количество принимаемых бит 8
resive1:lcall   sclhgh        ;смена данных на шине SDA происходит при SCL=0
        mov     c,sda         ;принять очередной бит с шины данных
        rlc     a             ;подготовить к приему следующий бит
        clr     scl           ;положительном фронте на шине SCL
        djnz    r0,resive1    ;следующий бит
        lcall   sclhgh        ;выдать импульс NAK
        clr     scl           ;на шине SCL
        setb    sda           ;установить шину sda
        pop     0             ;восстановить
        pop     psw           ;изменяемые регистры
        ret                   ;и выход SDA = 1 , SCL = 0

sendi2c:push    0             ;подпрограмма передачи байта по шине I2C:
        push    acc           ;сохранить изменяемые регистры
        push    psw           ;сохpанить флаг ошибки (если был)
        mov     r0,#8         ;количество передаваемых бит
sndi2c1:clr     c             ;первым всегда передается старший бит
        rlc     a             ;поэтому необходим сдвиг влево
        mov     sda,c         ;выдать текущий передаваемый бит на шину
        lcall   sclhgh        ;запись происходит при положительном фронте
        clr     scl           ;на шине SCL.Сбросить шину SCL для
        djnz    r0,sndi2c1    ;смены данных.Следующий бит
        setb    sda           ;проверка условия ASK:освободить шину данных
        lcall   sclhgh        ;ASK условие появляется при переднем фронте
        pop     psw
        jnb     sda,ask1      ;если приемник удерживает шину - переход
        setb    c             ;установить бит общей ошибки
ask1:   clr     scl           ;обнулить шину SCL.При этом освобождается
        pop     acc           ;шина данных от сигнала ASK.Восстановить
        pop     0             ;изменяемые регистры
        ret                   ;и выход при SDA = 1 , SCL = 0

strti2c:lcall   sclhgh        ;старт - условием считается
        clr     sda           ;отрицательный перепад на шине SDA при
        clr     scl           ;единичном сигнале на шине SCL
        ret                   ;и выход при SDA = 0 , SCL = 0

stopi2c:clr     sda           ;стоп - условием считается
        lcall   sclhgh        ;положительный перепад на шине SDA при
        setb    sda           ;единичном сигнале на шине SCL
        ret                   ;и выход при SDA = 1 , SCL = 1

sclhgh: setb    scl           ;установить шину SCL в 1
        jnb     scl,$         ;пpовеpить,не удеpживается ли SCL пеpефеpией
        ret                   ;
