⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 software IIC for msp430
💻 C
字号:
#include  <msp430xe42x.h>
#include "IIC.h"
#include "hardware.h"

// important
// all the delay are set with MCLK = 4MHZ. 

unsigned char RXTXI2C;

//-------------------------------------------------------------------------------
//           Start of subroutines to communicate with EEPROM via I2C
//-------------------------------------------------------------------------------

/* This delay is needed for EEPROMs */
void delay(int i)
{
    for (  ;  i;  i--)
    {
        _NOP();
        _NOP();
        _NOP();
        _NOP();
    }
}



//-------------------------------------------------------------------------------
void iic_start(void)           // Set up start condition for I2C
{   
   /* Send a start to the EEPROM */
   /* A start is the data bit falling while the clock is high */
   P1DIR &= ~SDA;
   delay(2);   //At least ???  1.9祍
   P1DIR &= ~SCL;
   delay(5);   //At least 4.7us   
   P1DIR |= SDA;               // Set to output, data low so SDA = 0
   delay(5);   //At least 4.7us
   P1DIR |= SCL;               // Set to output, data low so SCL = 0    
}


//------------------------------------------------------------------------------- 
void iic_stop(void)            // Send I2C stop command
{
  /* Send a stop to the EEPROM */
    /* A stop is the data bit rising while the clock is high */  
   P1DIR |= SDA;               // Set to output, data low so SCA = 0
   delay(2);
   P1DIR &= ~SCL;              // Set to input, SDL = 1 due to pull-up
   delay(5);
   P1DIR &= ~SDA;              // Set to input, SDA = 1 due to pull-up
   delay(5);
   P1DIR |= SCL;
}

/************************************************************************
***                             iic_send                             ***
************************************************************************/
int iic_send(unsigned char data)
{
    int i;    
    /* Send 8 bits of data */
    P1DIR |= SCL;    
    for (i = 8;  i > 0;  i--)
    {
        /* The data can now change without delay */
        if (data & 0x80)            
            P1DIR &= ~SDA;
        else
            P1DIR |= SDA;
        data <<= 1;
        /* Pulse the clock high while the data bit is steady */
        delay(5);   //At least 4.7us
        
        P1DIR &= ~SCL;
        delay(5);   //At least 4.7us        
        P1DIR |= SCL;
    }
    
    /* Check the acknowledgement from the EEPROM */
    /* Pulse the clock high, and see what the device says while the clock is high */
    delay(5);
    P1DIR &= ~SDA;
    delay(5);
    
    P1DIR &= ~SCL;
    delay(5);
    
    i = P1IN & SDA;
    P1DIR |= SCL;
    delay(4);
    
    return i;
}

////////////////////////////////////////////////////////////////////////////////////////////
/************************************************************************
***                             iic_receive                             ***
************************************************************************/
unsigned char iic_receive(int ok)
{
    unsigned char data;
    int i;

    /* Get 8 bits of data */
    P1DIR &= ~SDA;     //Input
    data = 0;
    for (i = 8;  i > 0;  i--)
    {
        P1DIR &= ~SCL;
        delay(5);   //At least 4.7us
        data <<= 1;
        if (P1IN & SDA)
            data |= 0x01;
        P1DIR |= SCL;
        delay(5);   //At least 4.7us
    }
    /* Send the acknowledgement to the EEPROM */
    if (ok)
        P1DIR |= SDA;
    else
        P1DIR &= ~SDA;
    delay(4);
    
    P1DIR &= ~SCL;
    delay(4);
    
    P1DIR |= SCL;
    P1DIR &= ~SDA;
    return data;
}


/************************************************************************
***                             test_SDA                              ***
************************************************************************/
int test_SDA(void)
{
    int i;
  
    iic_stop();
    P1DIR &= ~SDA;
    delay(4);
    for (i = 16;  i > 0;  i--)
    {
        delay(5);
        if (!(P1IN & SDA))
            break;
    }
    return i;
}


int iicEEPROM_init(void)
{
    int i;

    /* While idling, the EEPROM clock should be low */
    P1DIR |= SCL;
    /* If we happen to have restarted in the middle of a read from
       the EEPROM/FRAM, we need to regain control of the device. If we
       give it enough clocks, and do no acknowledge it we should get out
       of any odd conditions. Then we do a stop, and we should be OK. If
       the device was mid write when the restart occurred we cannot really
       act in a clean way. */
    delay(5);   //At least 4.7us
    for (i = 0;  i < 16;  i++)
    {
        P1DIR &= ~SCL;
        delay(5);   //At least 4.7us
        P1DIR |= SCL;
        delay(5);   //At least 4.7us
    }
    iic_stop();
    return 0;
}




/************************************************************************
***                          iic_EEPROM_read                          ***
************************************************************************/
int iicEEPROM_read(unsigned int addr)
{
    int i;
    
    
    delay(5);
    iicEEPROM_init();
    for (i = 0;  i < MAX_IIC_TRIES;  ++i)
    {
        if (i)
        {
            /* Read FALSE, retry */
            if (test_SDA())
                continue;
        }
        
        iic_start();   //start
        
        
       
        if (iic_send(0xA0 | ((unsigned char)(addr/0x100)*2))  ||  iic_send(addr))
            continue;
  
        
        
        iic_start();
        

        if (iic_send(0xA1 | ((unsigned char)(addr/0x100)*2)))
            continue;

        
            RXTXI2C = iic_receive(TRUE);
        
        iic_stop();
        
        return TRUE;
    }
    iic_stop();
    return FALSE;
}





/************************************************************************
***                        iicEEPROM_write                            ***
************************************************************************/
int iicEEPROM_write(unsigned int addr, unsigned char dat)
{
    int i;
        
    /* If the write spreads across pages in the EEPROM, we need to split the write
       into sections. */ 
        //delay(5);
        iicEEPROM_init();
        for (i = 0;  i < MAX_IIC_TRIES;  ++i)
        {
            if (i)
            {
                /* Write FALSE, retry */
                if (test_SDA())
                    continue;
            }

            iic_start();

            if (iic_send(0xA0 | ((unsigned char)(addr/0x100)*2))  ||  iic_send(addr))
                continue;
            if (iic_send(dat)) break;
            
        }
        
        iic_stop();
        
        if (i >= MAX_IIC_TRIES)
            return 0;
    return 1;
}
















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -