最近使用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)。 |
|