/* Driver for I2C on the HB expansionboard. the driver works over the MISO and MOSI on J6 (4x2 Header) MISO is the CLK (Clock) MOSI is the SDA (Data) You need to pullup the Data line with a 1.2 KOhm resistor - int i2c_init() - inits the I2C-interface - int i2c_write_byte(int adress, int data) --> writes one byte to the device with the given adresss - int i2c_write_2byte(int adress, int data, int data2) --> writes two byte to the device with the given adresss - int i2c_receive_byte(int adress) --> receives one byte from the device with the given adress - int i2c_receive_2byte(int adress) --> receives two bytes from the device with the given adress EXAMPLE: // read the value from the compass modul CMPS03 from devantech void main() { int test; // init I2C bus i2c_init(); // write one byte to the device with the adress 192 i2c_write_byte(192,2); // receive two byte(16 bit) from the device with the adress 192 test = i2c_receive_2byte(192); printf("\n %d ", test); } Author: Thomas Krause URL: www.krause.robotik.de URL2: www.robotik-ag.de eMail: info@krause-robotik.de eMail: thomas.krause@s1998.tu-chemnitz.de Date: Germany 07.11.2003 */ int PORTD = 4104; int DDRD = 4105; int SCLbit = 4; int SDAbit = 8; int i2c_init() { bit_set(PORTD, SCLbit); bit_set(PORTD, SDAbit); bit_set(DDRD, SCLbit); bit_set(DDRD, SDAbit); //sleep(0.1); return 1; } void i2c_clk_puls() { bit_set(PORTD, SCLbit); bit_clear(PORTD, SCLbit); } int i2c_init_start() { bit_set(DDRD, SCLbit); bit_set(DDRD, SDAbit); bit_set(PORTD,SCLbit); bit_set(PORTD, SDAbit); bit_clear(PORTD, SDAbit); return 1; } int i2c_init_stop() { bit_set(PORTD, SCLbit); //sleep(0.1); bit_set(PORTD, SDAbit); //sleep(0.1); return 1; } void i2c_send_adress(int adress) { bit_set(DDRD, SDAbit); //printf("\n"); bit_clear(PORTD, SCLbit); if (adress&0b10000000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b01000000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00100000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00010000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00001000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00000100) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00000010) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); } void i2c_send_data(int adress) { bit_set(DDRD, SDAbit); bit_clear(PORTD, SCLbit); if (adress&0b10000000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b01000000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00100000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00010000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00001000) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00000100) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00000010) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); if (adress&0b00000001) bit_set(PORTD, SDAbit); else bit_clear(PORTD, SDAbit); i2c_clk_puls(); } int i2c_receive_data() { int data; int bit; bit_clear(DDRD, SDAbit); bit_clear(PORTD, SCLbit); bit_set(PORTD,SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 128; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 64; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 32; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 16; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 8; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 4; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 2; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data + 1; bit_clear(PORTD, SCLbit); return data; } int i2c_receive_2data() { int data; int bit; bit_clear(DDRD, SDAbit); bit_clear(PORTD, SCLbit); bit_set(PORTD,SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b1000000000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0100000000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0010000000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0001000000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000100000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000010000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000001000000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000100000000; bit_clear(PORTD, SCLbit); bit_set(DDRD, SDAbit); bit_clear(PORTD, SDAbit); i2c_clk_puls(); bit_clear(DDRD, SDAbit); bit_set(PORTD,SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000010000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000001000000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000100000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000010000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000001000; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000000100; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000000010; bit_clear(PORTD, SCLbit); bit_set(PORTD, SCLbit); bit = peek(PORTD); if (bit&SDAbit) data = data | 0b0000000000000001; bit_clear(PORTD, SCLbit); return data; } int i2c_receive_ack() { int bit; bit_set(PORTD, SDAbit); //lesebit hoch setzen bit_clear(DDRD, SDAbit); // Datenbit auf Lesezugriff bit_set(PORTD, SCLbit); // clock hoch bit = peek(PORTD); // register holen bit_clear(PORTD, SCLbit); // clock runter bit_set(DDRD, SDAbit); // Datenbit auf Schreibzugriff if (bit&SDAbit) return 0; else return 1; } int i2c_write_byte(int adress, int data) { int bit; i2c_init_start(); i2c_clk_puls(); //Adresse senden i2c_send_adress(adress); //Datenbit loeschen (= Daten senden) bit_clear(PORTD, SDAbit); i2c_clk_puls(); //Ackbit abwarten if (i2c_receive_ack()) { //printf(" 1"); //msleep(100L); i2c_send_data(data); if (i2c_receive_ack()) { //printf(" 1"); i2c_init_stop(); return 1; } else { return 0; } } else return 0; } int i2c_write_2byte(int adress, int data, int data2) { int bit; i2c_init_start(); i2c_clk_puls(); //Adresse senden i2c_send_adress(adress); //Datenbit loeschen (= Daten senden) bit_clear(PORTD, SDAbit); i2c_clk_puls(); //Ackbit abwarten if (i2c_receive_ack()) { //printf(" 1"); //msleep(100L); i2c_send_data(data); if (i2c_receive_ack()) { i2c_send_data(data2); if (i2c_receive_ack()) { //printf(" 1"); i2c_init_stop(); return 1; } else return 0; } else { return 0; } } else return 0; } int i2c_receive_byte(int adress) { int data = 0; int bit; i2c_init_start(); i2c_clk_puls(); //Adresse senden i2c_send_adress(adress); //Datenbit setzen (= Daten empfangen) bit_set(PORTD, SDAbit); i2c_clk_puls(); //Ackbit abwarten if (i2c_receive_ack()) { //printf(" 1"); //msleep(100L); data = i2c_receive_data(); // Datenleitung nach unten ziehen als Empfangsbesttigung //bit_set(DDRD, SDAbit); bit_clear(PORTD, SDAbit); i2c_clk_puls(); i2c_init_stop(); return data; } else { //printf("falsch"); return 0; } } int i2c_receive_2byte(int adress) { int data = 0; int bit; i2c_init_start(); i2c_clk_puls(); //Adresse senden i2c_send_adress(adress); //Datenbit setzen (= Daten empfangen) bit_set(PORTD, SDAbit); i2c_clk_puls(); //Ackbit abwarten if (i2c_receive_ack()) { //printf(" 1"); //msleep(100L); data = i2c_receive_2data(); // Datenleitung nach unten ziehen als Empfangsbesttigung bit_clear(PORTD, SDAbit); i2c_clk_puls(); i2c_init_stop(); return data; } else { //printf("falsch"); return 0; } }