www.mikrocontroller.net

i2c.c

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() */

webmaster@mikrocontroller.net – Impressum – Werbung auf Mikrocontroller.net