搜索
bottom↓
回复: 4

MSP430F5438 IO模拟I2C操作FM24CL16

[复制链接]

出0入0汤圆

发表于 2013-2-26 09:39:40 | 显示全部楼层 |阅读模式
最近使用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)。




阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-2-26 09:40:02 | 显示全部楼层
IO_FM24CLXX_I2C_init();
        while(1)
        {
            buffer[0]=IO_FM24CLXX_I2C_ReadByte(0x0001);
                IO_FM24CLXX_I2C_WriteByte(0x0001,0x5A);
                buffer[1]=IO_FM24CLXX_I2C_ReadByte(0x0001);

               
                for(int i=0;i<2048;i++)
                        {
                                buffer[i]=i+1;
                        }
                IO_FM24CLXX_I2C_WriteBytes(0,buffer,128);
                IO_FM24CLXX_I2C_ReadBytes(0,readdat,128);

出0入0汤圆

 楼主| 发表于 2013-2-26 09:40:38 | 显示全部楼层
上面是简单的一个实例,单字节读写多字节读写

出0入0汤圆

 楼主| 发表于 2013-2-26 09:43:05 | 显示全部楼层
原工程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-2-26 09:48:35 | 显示全部楼层
在头文件中定义FM24CLxx中的xx,可以使用条件编译兼容所有型号,目前给的值兼容至16,稍微修改下可以兼容所有型号
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 23:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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