最近使用FM24CL16,430的I2C不是很好使,自己写IO操作。 
贴出代码。 
头文件: 
 
#ifndef LIB_IO_I2C_H 
#define LIB_IO_I2C_H 
 
//*--------------------------------------------------------------------------------------- 
//* 符号定义 
//*--------------------------------------------------------------------------------------- 
#define FM24CLXX        16 
#if FM24CLXX <= 16 
#define PAGE_SIZE        FM24CLXX/2 //页数目,每页256字节 
#endif 
 
#define DEVICE_ADDRESS        0xA0 
 
#define FM24CLXX_READ        0x01 
#define FM24CLXX_WRITE        0x00 
 
#define SDA_BIT        BIT3 
#define SCL_BIT        BIT0 
 
#define SDA_DIR        P7DIR 
#define SCL_DIR        P8DIR 
 
#define SDA_IN        P7IN 
#define SDA_OUT        P7OUT 
#define SCL_OUT        P8OUT 
 
#define SDA_IN_MODE                SDA_DIR &= ~SDA_BIT 
#define SDA_OUT_MODE        SDA_DIR |= SDA_BIT 
#define SCL_OUT_MODE        SCL_DIR |= SCL_BIT 
 
#define I2C_CONFIG        {SDA_OUT_MODE;SCL_OUT_MODE;} 
 
#define SDA_H        SDA_OUT |= SDA_BIT         
#define SDA_L        SDA_OUT &= ~SDA_BIT 
 
#define SCL_H        SCL_OUT |= SCL_BIT         
#define SCL_L        SCL_OUT &= ~SCL_BIT 
 
#define READ_SDA_IN        (SDA_IN & SDA_BIT)==SDA_BIT 
 
//*--------------------------------------------------------------------------------------- 
//* 函数定义 
//*--------------------------------------------------------------------------------------- 
void IO_FM24CLXX_I2C_init(void); 
void IO_FM24CLXX_I2C_Wait(void); 
unsigned char IO_FM24CLXX_I2C_Start(void); 
void IO_FM24CLXX_I2C_Stop(void); 
void IO_FM24CLXX_I2C_Ack(void); 
void IO_FM24CLXX_I2C_NoAck(void); 
unsigned char IO_FM24CLXX_I2C_WaitAck(void);          //返回为:1=有ACK,0=无ACK 
void IO_FM24CLXX_I2C_Write(unsigned char dat); //数据从高位到低位// 
unsigned char IO_FM24CLXX_I2C_Read(void);  //数据从高位到低位// 
 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_ReadByte  
* 描述 : 随机读取指定地址的数据; 
* 输入 : 数据存储地址 
* 输出 : 读取的字节; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_ReadByte(unsigned int Addr); 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_ReadBytes  
* 描述 : 随机读取指定地址的数据穿; 
* 输入 : unsigned int Addr,读取数据的地址;  
                 unsigned char *ptr, 数据保存的数据指针 
                 unsigned int length,读取的数据长度; 
* 输出 : 返回读取成功; 
                0,读取失败; 
                1,读取成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_ReadBytes(unsigned int Addr, unsigned char *ptr, unsigned int length); 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_writeByte  
* 描述 : 随机将数据写入指定地址; 
* 输入 : unsigned int Addr,写入数据的地址;  
                 unsigned char dat,写入的数据 
* 输出 : 返回成功标志; 
                0,写入失败; 
                1,写入成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_WriteByte(unsigned int Addr, unsigned char dat); 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_WriteBytes  
* 描述 : 指定地址写入指定长度的数据; 
* 输入 : unsigned int Addr,写入数据的地址;  
                 unsigned char *ptr, 数据保存的数据指针 
                 unsigned int length,写入数据长度; 
* 输出 : 返回读取成功; 
                0,读取失败; 
                1,读取成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_WriteBytes(unsigned int Addr, unsigned char *ptr, unsigned int length); 
 
 
 
#endif 
 
C文件内容为: 
#include "msp430F5438.h" 
#include "lib_io_i2c.h" 
 
#define FM24CLXX_TRUE  1 
#define FM24CLXX_FALSE 0 
 
/****************************************************************************** 
* 功能 :IO_I2C_init  
* 描述 : 调用初始化宏定义; 
* 输入 : 无 
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_init(void) 
{ 
        //初始化端口,默认管脚高电平,输出模式; 
        I2C_CONFIG; 
        SDA_H; 
        SCL_H; 
} 
 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_Wait  
* 描述 : 小段延时函数; 
* 输入 : 无 
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_Wait(void) 
{         
        //延时功能,短暂延时5个时钟周期; 
        for(int i=10;i>0;i--); 
} 
 
void _delay_us(unsigned int i) 
{ 
        while(i--) 
        { 
                for(int j=5;j>0;j--); 
        } 
} 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_Start  
* 描述 : 启动i2c总线; 
* 输入 : 无 
* 输出 : 无; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_Start(void) 
{ 
        //启动I2C总线;SDA=1,SCL=0;         
        SCL_H; 
        SDA_H; 
        _delay_us(2); 
        SDA_L; 
        _delay_us(2); 
        SCL_L; 
        _delay_us(2); 
        return FM24CLXX_TRUE; 
} 
 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_Start  
* 描述 : 关闭i2c总线; 
* 输入 : 无 
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_Stop(void) 
{ 
        SCL_L; 
        SDA_L; 
        _delay_us(2); 
        SCL_H; 
        _delay_us(2); 
        SDA_H; 
        _delay_us(2); 
         
} 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_Ack  
* 描述 :i2c发送ACK; 
* 输入 : 无  
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_Ack(void) 
{         
        SCL_L; 
        SDA_L; 
        _delay_us(2); 
        SCL_H; 
        _delay_us(2);; 
        SCL_L; 
        _delay_us(2); 
} 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_NoAck  
* 描述 :i2c发送NO ACK; 
* 输入 : 无  
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_NoAck(void) 
{         
        SCL_L; 
        SDA_H; 
        _delay_us(2); 
        SCL_H; 
        _delay_us(2);; 
        SCL_L; 
        _delay_us(2); 
 
} 
 
/****************************************************************************** 
* 功能 :IO_FM24CLXX_I2C_WaitAck  
* 描述 :i2c读取 ACK; 
* 输入 : 无  
* 输出 : 无; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_WaitAck(void)          //返回为:1=有ACK,0=无ACK 
{ 
    unsigned char i=0; 
        SDA_IN_MODE; 
        SDA_H; 
        _delay_us(2); 
        SCL_L; 
        _delay_us(2); 
        SCL_H; 
        _delay_us(2); 
    while((READ_SDA_IN) && (i<250)) 
            { 
                    i++; 
            } 
        SCL_L; 
        SDA_OUT_MODE; 
    _delay_us(2); 
        return FM24CLXX_TRUE; 
} 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_Write 
* 描述 : i2c写入一个字节; 
* 输入 : unsigned char dat 
                写入的数据; 
* 输出 : 无; 
******************************************************************************/ 
void IO_FM24CLXX_I2C_Write(unsigned char dat) //数据从高位到低位// 
{ 
    unsigned char i,temp; 
    temp=dat; 
        SCL_L; 
        _delay_us(2); 
        SDA_OUT_MODE; 
    for(i=0;i<8;i++) 
    { 
        SCL_L; 
        _delay_us(1); 
                if((temp&0x80)==0x80) 
                SDA_H; 
                else 
                        SDA_L; 
                temp<<=1; 
        _delay_us(1); 
        SCL_H; 
        _delay_us(1); 
                SCL_L; 
                _delay_us(1); 
        } 
    //SDA_H; 
        _delay_us(2); 
} 
 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_Read 
* 描述 : i2c读取一个字节; 
* 输入 : 无 
* 输出 : 读取的字节; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_Read(void)  //数据从高位到低位// 
{ 
    unsigned char i,k=0; 
           SCL_L; 
        SDA_IN_MODE; 
    _delay_us(2); 
    for(i=0;i<8;i++) 
    { 
                k<<=1; 
                SCL_L; 
        _delay_us(1);         
        SCL_H; 
        _delay_us(2); 
                if(READ_SDA_IN) 
                k+=1; 
                SCL_L; 
        _delay_us(1);         
    } 
        SDA_OUT_MODE; 
        _delay_us(1); 
    return k; 
} 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_ReadByte  
* 描述 : 随机读取指定地址的数据; 
* 输入 : 数据存储地址 
* 输出 : 读取的字节; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_ReadByte(unsigned int Addr) 
{ 
        unsigned char dat; 
 
        unsigned char page; 
        page = Addr/256; 
        page &= 0x07; 
         
        IO_FM24CLXX_I2C_Start(); 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE + (page << 1)); 
 
        IO_FM24CLXX_I2C_WaitAck(); 
         
        IO_FM24CLXX_I2C_Write(Addr%256); 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
        IO_FM24CLXX_I2C_Start(); 
 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_READ+ (page << 1)); 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
        dat = IO_FM24CLXX_I2C_Read(); 
 
        IO_FM24CLXX_I2C_NoAck(); 
 
        IO_FM24CLXX_I2C_Stop(); 
        return dat; 
} 
 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_ReadBytes  
* 描述 : 随机读取指定地址的数据穿; 
* 输入 : unsigned int Addr,读取数据的地址;  
                 unsigned char *ptr, 数据保存的数据指针 
                 unsigned int length,读取的数据长度; 
* 输出 : 返回读取成功; 
                0,读取失败; 
                1,读取成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_ReadBytes(unsigned int Addr, unsigned char *ptr, unsigned int length) 
{ 
        //unsigned char dat; 
        unsigned int num; 
        #if FM24CLXX>=4&&FM24CLXX<=16 
        unsigned char page; 
        page = Addr >> 8; 
        #endif 
         
        IO_FM24CLXX_I2C_Start(); 
        #if FM24CLXX>=4&&FM24CLXX<=16 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE + (page << 1)); 
        #else 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE ); 
        #endif 
 
        IO_FM24CLXX_I2C_WaitAck(); 
         
        #if FM24CLXX>=4&&FM24CLXX<=16 
        IO_FM24CLXX_I2C_Write(Addr); 
        #else 
        IO_FM24CLXX_I2C_Write(Addr); 
        #endif 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
        IO_FM24CLXX_I2C_Start(); 
        #if FM24CLXX>=4&&FM24CLXX<=16 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_READ+ (page << 1)); 
        #else 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_READ); 
        #endif 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
        for(num = 0;num < length;num ++) 
                { 
                        *ptr++ = IO_FM24CLXX_I2C_Read(); 
                        if(num != (length - 1) ) 
                                { 
                                        IO_FM24CLXX_I2C_Ack(); 
                                } 
                } 
         
        //IO_FM24CLXX_I2C_NoAck(); 
        IO_FM24CLXX_I2C_Wait(); 
        IO_FM24CLXX_I2C_Stop(); 
        return FM24CLXX_TRUE; 
} 
 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_writeByte  
* 描述 : 随机将数据写入指定地址; 
* 输入 : unsigned int Addr,写入数据的地址;  
                 unsigned char dat,写入的数据 
* 输出 : 返回成功标志; 
                0,写入失败; 
                1,写入成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_WriteByte(unsigned int Addr, unsigned char dat) 
{ 
        unsigned char page; 
        page = Addr/256; 
         
        IO_FM24CLXX_I2C_Start(); 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE + (page << 1)); 
        IO_FM24CLXX_I2C_WaitAck(); 
         
 
        IO_FM24CLXX_I2C_Write(Addr%256); 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
 
        IO_FM24CLXX_I2C_Write(dat); 
         
        IO_FM24CLXX_I2C_WaitAck(); 
 
        IO_FM24CLXX_I2C_Stop(); 
        return FM24CLXX_TRUE; 
} 
 
 
/****************************************************************************** 
* 功能 : IO_FM24CLXX_I2C_WriteBytes  
* 描述 : 指定地址写入指定长度的数据; 
* 输入 : unsigned int Addr,写入数据的地址;  
                 unsigned char *ptr, 数据保存的数据指针 
                 unsigned int length,写入数据长度; 
* 输出 : 返回读取成功; 
                0,读取失败; 
                1,读取成功; 
******************************************************************************/ 
unsigned char IO_FM24CLXX_I2C_WriteBytes(unsigned int Addr, unsigned char *ptr, unsigned int length) 
{ 
        //unsigned char dat; 
        unsigned int num; 
         
        #if FM24CLXX>=4&&FM24CLXX<=16 
        unsigned char page; 
        page = Addr >> 8; 
        #endif 
         
        IO_FM24CLXX_I2C_Start(); 
        #if FM24CLXX>=4&&FM24CLXX<=16 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE + (page << 1)); 
        #else 
        IO_FM24CLXX_I2C_Write(DEVICE_ADDRESS + FM24CLXX_WRITE ); 
        #endif 
 
        IO_FM24CLXX_I2C_WaitAck(); 
         
        #if FM24CLXX>=4&&FM24CLXX<=16 
        IO_FM24CLXX_I2C_Write(Addr); 
        #else 
        IO_FM24CLXX_I2C_Write(Addr); 
        #endif 
 
        IO_FM24CLXX_I2C_WaitAck(); 
 
        for(num = 0;num < length;num++) 
                { 
                        IO_FM24CLXX_I2C_WriteByte(Addr++, *ptr++); 
                        IO_FM24CLXX_I2C_WaitAck(); 
                } 
 
        IO_FM24CLXX_I2C_Stop(); 
        return FM24CLXX_TRUE; 
} 
 
最后贴出源工程(IAR)。 |  
  
 |