//****************************************************************************** // // I2C-Library // // Stellt I2C-Routinen für den MSP430F149 bereit. SDA ist an Pin 47 // angeschlossen, SCL an Pin 48. // //****************************************************************************** #include #include "projekt.h" #define SDA 0x08 #define SCL 0x10 void SCL_low(void); void SCL_high(void); void SCL_clock(void); void SDA_low(void); void SDA_high(void); void SDA_read(void); void SDA_write(void); void SCL_write(void); void SCL_read(void); void I2C_start(void); void I2C_init(char address, char r_w); int I2C_gotACK(void); void I2C_sendbyte(char byte); double I2C_receivebyte(void); void I2C_sendACK(void); /******************************************************************************* * * void SCL_low(void) * *******************************************************************************/ void SCL_low(void) // Pin 48 (SCL) auf LOW setzen { P5DIR|=SCL; // Ausgang auf Output setzen, damit aktiv null anliegt wait(1); // 1ms warten (rise time, fall time usw.) }/* void SCL_low(void) */ /******************************************************************************* * * void SCL_high(void) * *******************************************************************************/ void SCL_high(void) // Pin 48 (SCL) auf High setzen { P5DIR&=~SCL; // Ausgang auf Input setzen, damit er auf HIGH geht // (pullup) wait(1); }/* void SCL_high(void) */ /******************************************************************************* * * void SCL_clock(void) * *******************************************************************************/ void SCL_clock(void) { SCL_high(); SCL_low(); }/* void SCL_clock(void) */ /******************************************************************************* * * void SDA_low(void) * *******************************************************************************/ void SDA_low(void) // Pin 47 (SDA) auf Low setzen { P5DIR|=SDA; wait(1); }/* void SDA_low(void) */ /******************************************************************************* * * void SDA_high(void) * *******************************************************************************/ void SDA_high(void) // Pin 47 (SDA) auf High setzen { P5DIR&=~SDA; wait(1); }/* void SDA_high(void) */ /******************************************************************************* * * void SDA_write(void) * *******************************************************************************/ void SDA_write(void) // Pin 47 (SDA) auf Output setzen { P5DIR|=SDA; P5OUT&=~SDA; }/* void SDA_write(void) */ /******************************************************************************* * * void SDA_read(void) * *******************************************************************************/ void SDA_read(void) // Pin 47 (SDA) auf Input setzen { P5DIR&=~SDA; }/* void SDA_read(void) */ /******************************************************************************* * * void SCL_write(void) * *******************************************************************************/ void SCL_write(void) // Pin 48 (SCL) auf Output setzen { P5DIR|=SCL; P5OUT&=~SCL; }/* void SCL_write(void) */ /******************************************************************************* * * void SCL_read(void) * *******************************************************************************/ void SCL_read(void) // Pin 48 (SCL) auf Input setzen { P5DIR&=~SCL; }/* void SCL_read(void) */ /******************************************************************************* * * void I2C_start(void) * *******************************************************************************/ void I2C_start(void) // I2C START condition auf den Bus senden { SCL_write(); SDA_write(); SCL_low(); SDA_high(); SCL_high(); SDA_low(); SCL_low(); }/* void I2C_start(void) */ /******************************************************************************* * * void I2C_init(char address, char r_w) * *******************************************************************************/ void I2C_init(char address, char r_w) // I2C-device mit Adresse "address" lesend { // oder schreibend initialisieren char i; SDA_write(); // Sicherheitshalber erst mal SDA und SCL SCL_write(); // auf wWrite setzen SCL_low(); // Sicherheitshalber erst mal SCL auf LOW // setzen for (i=7; i>0; i--) // 7-Bit-I2C-Adresse senden { if (address&(1<<(i-1))) SDA_high(); else SDA_low(); SCL_clock(); }/* for (i=7; i>0; i--) */ if (r_w=='r') SDA_high(); else SDA_low(); SCL_clock(); // 1 oder 0 senden (read oder write) }/* void I2C_init(char address, char r_w) */ /******************************************************************************* * * int I2C_gotACK(void) * *******************************************************************************/ int I2C_gotACK(void) // Nachschauen, ob ein ACK vom Bus empfangen wurde { char gotACK; SCL_write(); SCL_low(); // Sicherheitshalber erst mal SCL auf Low setzen SDA_read(); // Sicherheitshalber erst mal SDA auf Read und SCL // auf write setzen SCL_high(); // Jetzt SCL auf HIGH setzen und damit 9. Clockpuls // erzeugt wird if (!(P5IN & SDA)) gotACK=1; else gotACK=0; SCL_low(); // Jetzt SCL wieder auf LOW setzen if (gotACK) return 1; else return 0; }/* int I2C_gotACK(void) */ /******************************************************************************* * * void I2C_sendbyte(char byte) * *******************************************************************************/ void I2C_sendbyte(char byte) // Ein komplettes Byte auf den Bus schicken { char i; SDA_write(); // Sicherheitshalber erst mal SDA und SCL SCL_write(); // auf Write setzen SCL_low(); // Sicherheitshalber erst mal SCL auf LOW setzen for (i=8; i>0; i--) { if (byte&(1<<(i-1))) SDA_high(); else SDA_low(); SCL_clock(); }/* for (i=8; i>0; i--) */ }/* void I2C_sendbyte(char byte) */ /******************************************************************************* * * double I2C_receivebyte(void) * *******************************************************************************/ double I2C_receivebyte(void) // Ein komplettes Byte vom Bus empfangen { double byte=0; SCL_low(); // Sicherheitshalber erst mal SCL auf LOW SDA_read(); // und SDA auf Read setzen SCL_high(); if ((P5IN&0x08)>>3) byte+=128; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=64; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=32; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=16; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=8; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=4; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=2; SCL_low(); SCL_high(); if ((P5IN&0x08)>>3) byte+=1; SCL_low(); return byte; }/* double I2C_receivebyte(void) */ /******************************************************************************* * * void I2C_sendACK(void) * *******************************************************************************/ void I2C_sendACK(void) // ACK auf den Bus schicken { SDA_low(); SDA_write(); SDA_low(); SCL_clock(); }/* void I2C_sendACK(void) */ /******************************************************************************* * * void I2C_stop() * *******************************************************************************/ void I2C_stop() // I2C STOP condition auf den Bus senden { SCL_write(); SCL_low(); SDA_write(); SDA_low(); SCL_high(); SDA_high(); }/* void I2C_stop() */