📄 fm24c64.c
字号:
//==============================================================================
//2006-01-24...2006-01-24
//FM24C64模块的C程序源文件
//File Name=FM24C64.c
//这里不考虑多个芯片在总线上互联的情形,只处理一个芯片,地址A2A1A0=0!
//==============================================================================
#include "FM24C64.h"
//外部全局变量的预定义
//内部函数
static void i2c_delay(void);
static void i2c_start_cond(void);
static void i2c_stop_cond(void);
static uint8 i2c_read_byte(void);
static uint8 i2c_read_byte_nack(void);
static void i2c_write_byte(uint8 da);
//*******************************************************
//序号:
// HD_FM24C64_S00
//功能:
// 进行端口初始化
//输入:
// 无
//输出:
// 无
//********************************************************
void FM24C64_init_pin(void)
{
PINSEL0 =PINSEL0 &(~ ( (0x03 <<(_HD_PIN_SCL_0 <<1) ) |
(0x03 <<(_HD_PIN_SDA_0 <<1) ) ) ); //P0.2-3 =GPIO
// PINSEL0 =0x00;
// PINSEL1 =0x00;
// PINSEL2 &=(~0x08);
OUT_FM24C64_SDA;
OUT_FM24C64_SCL;
SET_FM24C64_SDA;
SET_FM24C64_SCL;
}
//*******************************************************
//序号:
// HD_FM24C64_S01
//功能:
// 在指定地址读出一个字节
//输入:
// add: 操作的字节地址
//输出:
// 读出的字节值
//********************************************************
uint8 FM24C64_read_byte(uint16 add)
{
uint8 i;
#ifdef _USE_WP
CLR_FM24C64_WP; //解除写保护
#endif
i2c_start_cond();
#ifdef _USE_EEP_LARGE_TYPE
i2c_write_byte(FM24C64_WRITE); //器件地址=1010A2A1A0r/w
i2c_write_byte( (add>>8) &0xff); //地址字节
#else
i2c_write_byte(FM24C64_WRITE |((add >>7) &0x0e)); //器件地址=1010A2A1A0r/w
#endif
i2c_write_byte(add &0xff); //地址字节
i2c_start_cond();
#ifdef _USE_EEP_LARGE_TYPE
i2c_write_byte(FM24C64_READ); //器件地址=1010A2A1A0r/w
#else
i2c_write_byte(FM24C64_READ |((add >>7) &0x0e)); //器件地址=1010A2A1A0r/w
#endif
i =i2c_read_byte_nack(); //顺序读的方式读出一个字节
i2c_stop_cond();
#ifdef _USE_WP
SET_FM24C64_WP;
#endif
return i;
}
//*******************************************************
//序号:
// HD_FM24C64_S02
//功能:
// 在指定地址写入一个字节
//输入:
// add: 操作的字节地址(0~2047)
// inda: 需要写入的字节值
//输出:
// 无
//********************************************************
void FM24C64_write_byte(uint16 add, uint8 inda)
{
#ifdef _USE_WP
CLR_FM24C64_WP; //解除写保护
#endif
i2c_start_cond();
#ifdef _USE_EEP_LARGE_TYPE
i2c_write_byte(FM24C64_WRITE); //器件地址=1010A2A1A0r/w
i2c_write_byte( (add>>8) &0xff); //地址字节
#else
i2c_write_byte(FM24C64_WRITE |((add >>7) &0x0e)); //器件地址=1010A2A1A0r/w
#endif
i2c_write_byte(add &0xff); //地址低字节
i2c_write_byte(inda); //字节写方式写入一个字节
i2c_stop_cond();
// delay_x1ms(10);
#ifdef _USE_WP
SET_FM24C64_WP;
#endif
}
//*******************************************************
//序号:
// HD_FM24C64_S03
//功能:
// 在指定地址读出指定长度的字串
//输入:
// add: 操作的字节地址(0~2047)
// len: 指定长度
// str: 存放读出字符串的地址指针
//输出:
// 无
//********************************************************
void FM24C64_read_string(uint16 add, uint8 len, uint8 *str)
{
uint8 i;
if(len ==0 || len >FM24C64_LEN_MAX) return;
#ifdef _USE_WP
CLR_FM24C64_WP; //解除写保护
#endif
i2c_start_cond();
#ifdef _USE_EEP_LARGE_TYPE
i2c_write_byte(FM24C64_WRITE); //器件地址=1010A2A1A0r/w
i2c_write_byte( (add>>8) &0xff); //地址字节
#else
i2c_write_byte(FM24C64_WRITE |((add >>7) &0x0e)); //器件地址=1010A2A1A0r/w
#endif
i2c_write_byte(add &0xff); //地址字节
i2c_delay();
i2c_start_cond();
i2c_write_byte(FM24C64_READ | ((add >>7) &0x0e));
for(i=0; i<len-1; i++)
{
str[i] =i2c_read_byte();
}
str[i] =i2c_read_byte_nack(); //顺序读的方式读出一个字节
i2c_stop_cond();
#ifdef _USE_WP
SET_FM24C64_WP;
#endif
}
//*******************************************************
//序号:
// HD_FM24C64_S04
//功能:
// 在指定地址写入一个字节
//输入:
// add: 操作的字节地址(0~2047)
// len: 指定长度
// str: 存放读出字符串的地址指针
//输出:
// 无
//********************************************************
void FM24C64_write_string(uint16 add, uint8 len, uint8 *str)
{
uint8 i;
if(len ==0 || len >FM24C64_LEN_MAX) return;
#ifdef _USE_WP
CLR_FM24C64_WP; //解除写保护
#endif
i2c_start_cond();
#ifdef _USE_EEP_LARGE_TYPE
i2c_write_byte(FM24C64_WRITE); //器件地址=1010A2A1A0r/w
i2c_write_byte( (add>>8) &0xff); //地址字节
#else
i2c_write_byte(FM24C64_WRITE |((add >>7) &0x0e)); //器件地址=1010A2A1A0r/w
#endif
i2c_write_byte(add &0xff); //地址低字节
for(i=0; i<len; i++)
{
i2c_write_byte(str[i]); //字节写方式写入一个字节
}
i2c_stop_cond();
// delay_x1ms(10);
#ifdef _USE_WP
SET_FM24C64_WP;
#endif
}
//==============
//内部调用函数部分
//==============
//这里默认: Fpclk=11.0592MHz, 而操作速率最大1MHz
#define _DELAY_I2C_COUNT 5 //延时控制
void i2c_delay(void)
{
uint8 i;
for(i=_DELAY_I2C_COUNT; i>0; i--);
}
//----------------------------------------------
//I2C 发启始条件:时钟线为高时数据线发生下降沿跳变
//----------------------------------------------
static void i2c_start_cond(void)
{
CLR_FM24C64_SCL;
i2c_delay();
SET_FM24C64_SDA;
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
CLR_FM24C64_SDA; //最后输出数据低电平
i2c_delay();
}
//----------------------------------------
//I2C 发结束条件:时钟线为高时数据线发生上升沿跳变
//----------------------------------------
static void i2c_stop_cond(void)
{
CLR_FM24C64_SCL;
i2c_delay();
CLR_FM24C64_SDA;
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
SET_FM24C64_SDA; //最后输出数据高电平
i2c_delay();
}
//----------------------------------------
// I2C 读取一个中间字节的数据
//----------------------------------------
static uint8 i2c_read_byte(void)
{
uint8 i;
uint8 da=0;
SET_FM24C64_SDA;
IN_FM24C64_SDA;
for(i =0; i<8; i++)
{
da <<=1; //传输的数据高位在前
CLR_FM24C64_SCL;
i2c_delay();
SET_FM24C64_SCL; //时钟为高时读数据
i2c_delay();
if (JUDGE_FM24C64_SDA !=0) da++;
}
CLR_FM24C64_SCL;
i2c_delay();
OUT_FM24C64_SDA;
CLR_FM24C64_SDA; //发送应答位
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
CLR_FM24C64_SCL;
i2c_delay();
SET_FM24C64_SDA; //最后输出数据高电平
return(da);
}
//----------------------------------------
// I2C 读取一个结尾字节的数据
//----------------------------------------
static uint8 i2c_read_byte_nack(void)
{
uint8 i;
uint8 da =0;
SET_FM24C64_SDA;
IN_FM24C64_SDA;
for (i =0; i<8; i++)
{
da <<=1;
CLR_FM24C64_SCL;
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
if(JUDGE_FM24C64_SDA !=0) da++;
}
CLR_FM24C64_SCL;
i2c_delay();
OUT_FM24C64_SDA;
SET_FM24C64_SDA; //最后输出数据高电平
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
CLR_FM24C64_SCL;
return( da );
}
//----------------------------------------
// I2C 写入一个字节的数据
//----------------------------------------
static void i2c_write_byte(uint8 da )
{
uint8 i;
for(i =0; i<8; i++)
{
CLR_FM24C64_SCL;
if(da&0x80)
{
SET_FM24C64_SDA;
}
else
{
CLR_FM24C64_SDA;
}
i2c_delay();
SET_FM24C64_SCL;
i2c_delay();
da <<=1;
}
CLR_FM24C64_SCL; //第8个SCL下降沿,写入8位数据
i2c_delay();
SET_FM24C64_SDA; //最后输出数据高电平
i2c_delay();
SET_FM24C64_SCL;
}
//=============================================================================
//End Of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -