; **************
; * ФУНКЦИЯ: Формирует на дине состояние СТАРТ *
; * ВХОД: FSR указывает на регистр TRIS порта, *
; * подключенного к шине I2C *
; * ВЫХОД: Формируется состояние СТАРТ, SCL и SDA — НИЗКИЙ уровень *
; **************
START bsf INDF,SDA; Гарантируем, что перед состоянием СТАРТ
bsf INDF,SCL; линии тактового сигнала и данных находились
Delay_600; в режиме ожидания (ВЫСОКИЙ уровень)
Delay_600; в течение не менее 1.3 мкс
bcf INDF,SDA; Формируем спадающий фронт на линии данных
Delay_600; Ждем, чтобы ведомый мог его обнаружить
bcf INDF,SCL; Выходим, при этом на SCL — НИЗКИЙ уровень
return
; ****************
; * ФУНКЦИЯ: Формирует на дине состояние СТОП *
; * ВХОД: FSR указывает на регистр TRIS порта, подключенного к шине I2C *
; * ВЫХОД: Формируется состояние СТОП, SCL и SDA — ВЫСОКИЙ уровень *
; ****************
STOP bcf INDF,SCL; Гарантируем наличие НИЗКОГО уровня на
bcf INDF,SDA; линии тактового сигнала и данных
bsf INDF, SCL; Формируем на линии тактового сигнала
Delay_600; ВЫСОКИЙ уровень на время не менее 0.6 мкс
bsf INDF,SDA; Формируем нарастающий фронт на линии данных
return
; ***************
; * ФУНКЦИЯ: Передает байт ведомому и проверяет подтверждение *
; * ВХОД: 8 бит передаваемых данных в DATA_OUT *
; * РЕСУРСЫ: Подпрограммы START и STOP *
; * ВЫХОД: Байт передан. Если не было подтверждения, ERR = 1 *
; * ВЫХОД: ИНАЧЕ ERR = 00. SCL — НИЗКИЕ уровень *
; ***************
I2C_OUT bcf TNDF,SCL; На линии такт, сигнала — НИЗКИЙ уровень
clrf ERR; Сбрасываем признак ошибки
movlw 8; Инициализируем счетчик цикла
movwf COUNT
I2C_OUT_LOOP
bcf INDF,SDA; Попробуем выдать 0 на линию данных
rlf DATA_OUT,f; Сдвигаем исходный байт влево
btfsc STATUS,С; С = 0 или 1?
bsf INDF,SDA; ЕСЛИ последнее, TO выдаем на линию 1
Delay_600; Формируем требуемую задержку
Delay_600
bsf TNDF,SCL; Выдаем на линию такт, сигнала ВЫСОКИЙ
Delay_600; уровень на время не менее 0.6 мкс
bcf INDF,SCL; Выдаем ка линию такт, сигнала НИЗКИЙ уровень
decfsz COUNT,f; Декрементируем счетчик цикла
goto I2C_OUT_LOOP; и повторяем восемь раз
; Теперь проверим наличие подтверждения от ведомого
bsf INDF,SDA; Высвобождаем линию данных
Delay_600; Сохраняем на линии такт, сигнала НИЗКИЙ уровень
Delay_600; на время, достаточное для ответа
bsf INDF,SCL; Выдаем на линию такт, сигнала ВЫСОКИЙ уровень
bcf sc INDF, SDA; Проверяем наличие НИЗКОГО уровня на линии данных
incf ERR,f; ЕСЛИ нет, TO ERR = 1
bcf INDF,SCL; Переводим линию такт, сигнала в состояние НИЗКОГО уровня
return