最近使用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)。 |
欢迎光临 因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/) | Powered by Discuz! X3.4 |