查看: 1419|回复: 0
打印 上一主题 下一主题

MSP430F5438 IO模拟I2C操作FM24CL16

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-1 18:30:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近使用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)。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表