В приведенных ниже примерах вывод SCL I2C устройства подключен к выводу RB2 pic-контроллера,
вывод SDA - к RB3.
  Процедуры написаны на ассемблере и могут быть встроены в код С-компиллятора (как это сделано
в примерах - для C2C). Проверялась работа процедур с частотой кварца 4МГц. При
более высоких частотах возможно потребуется вводить временные задержки для корректного обмена
по шине I2C.
/*--------- начало примера----------- Требуется 2 байта ОЗУ - i2c_byte - в него помещается байт, который необходимо вывести на шину, в нем оказывается байт, считанный с шины; tmp - счетчик, используемый в цикле. */ char i2c_byte; /* рабочий регистр */ char tmp; /* счетчик */ void i2c_start() { asm { bcf STATUS, RP0 bsf PORTB, 2 ; SCL - 1 bsf PORTB, 3 ; SDA - 1 bcf PORTB, 3 ; SDA - 0 bcf PORTB, 2 ; SCL - 0 } } void i2c_stop() { asm { bcf STATUS, RP0 bcf PORTB, 3 ; SDA - 0 bsf PORTB, 2 ; SCL - 1 bsf PORTB, 3 ; SDA - 1 } } void i2c_write() { asm { movlw 0x08 movwf _tmp bsf STATUS, RP0 bcf TRISB, 3 ; SDA - вывод bcf STATUS, RP0 bcf PORTB, 2 ; SCL - 0 send_bit bsf PORTB, 3 ; выводим 1 на SDA btfss _i2c_byte, 7 ; бит данных - 1 ? bcf PORTB, 3 ; нет - выводим 0 на SDA bsf PORTB, 2 ; SCL - 1 rlf _i2c_byte, F ; сдвигаем влево байт данных bcf PORTB, 2 ; SCL - 0 decfsz _tmp, F ; конец цикла ? goto send_bit ; нет - переход bsf PORTB, 3 ; осв. SDA bsf PORTB, 2 ; SCL - 1, получаем ACK-бит и игнорируем его (!) bcf PORTB, 2 ; SCL - 0 } } void i2c_read() { asm { movlw 0x08 movwf _tmp bsf STATUS, RP0 bsf TRISB, 3 ; SDA - на ввод bcf STATUS, RP0 bcf PORTB, 2 ; SCL - на 0 read_bit rlf _i2c_byte, F ; сдвигаем байт влево bsf PORTB, 2 ; SCL - up bsf _i2c_byte, 0 ; устанавливаем бит в 1 btfss PORTB, 3 ; SDA - 1? bcf _i2c_byte, 0 ; нет - устанавливаем бит в 0 bcf PORTB, 2 ; SCL - 0 decfsz _tmp, F ; конец цикла ? goto read_bit ; нет - переход bsf STATUS, RP0 bcf TRISB, 3 ; SDA - на вывод bcf STATUS, RP0 } } /*------------- окончание примера ------------ */
*/------------начало примера---------------- вывод содержимого памяти на COM-порт */ void outAllData() { for (i = 0; i < 32767; i++) { i2c_start(); i2c_byte = 0xA0; // control байт с битом WR i2c_write(); asm { movfw _i+1 movwf _i2c_byte ; старший байт адреса памяти } i2c_write(); asm { movfw _i movwf _i2c_byte ; младший байт адреса памяти } i2c_write(); i2c_start(); i2c_byte = 0xA1; // control байт с битом RD i2c_write(); i2c_read(); i2c_stop(); putchar(i2c_byte); } } /* запись в 24LC256 числа 1Fh по адресам от 00h по FFh */ for (temp = 0; temp <= 0xFF; temp++) { i2c_start(); i2c_byte = 0xA0; //control байт с битом WR i2c_write(); i2c_byte = 0; // старший байт адреса памяти i2c_write(); i2c_byte = temp; // младший байт адреса памяти i2c_write(); i2c_byte = 0x1F; // записываемые данные i2c_write(); i2c_stop(); } /*------------окончание примера---------------*/