i2c.c
//******************************************************************************
//
// I2C-Library
//
// Stellt I2C-Routinen für den MSP430F149 bereit. SDA ist an Pin 47
// angeschlossen, SCL an Pin 48.
//
//******************************************************************************
#include <msp430x14x.h>
#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() */