📄 24c04.c
字号:
/*******************************************************************************
* 版权所有(c) 豪恩科技有限公司
*
* 文件名称: 24C04.H
* 文件标识:
* 内容摘要: 24C04的基本读写程序。但没有定义SDA,SCL。
* 先定义SDA,SCL。还需要定义24C04的A2,A1。
* 再包含该文件。
* 函数有, I2CStart , I2CStop ,
* 其他说明: 所有子函数要求在退出时统一都保证SCL为高,带返回值的,成功返回0,失败返回1
* 当前版本: 00.000
* 作 者: 涂常亮
* 完成日前: 2005
* 修改记录1:
* 修改日期:
* 版 本 号:
* 修 改 人:
* 修改内容:
* 修改记录2:
*******************************************************************************/
#include <intrins.h>
#include<reg54.h>
//#define USE_SEQ_RD
//定义 24C04_H不合理 ???
#ifndef AT24C04_H
#define AT24C04_H
#ifdef ADD_24C04_A2A1
#define ADD_WRITE_24C04 0xA0 | ADD_24C04_A2A1
#define ADD_READ_24C04 0xA1 | ADD_24C04_A2A1
#else
#define ADD_WRITE_24C04 0xA0
#define ADD_READ_24C04 0xA1
#endif
//定义24C04的响应等待时间,Datasheet是10ms,
#define WAIT_ACK_TIME 11
//读写24C04的返回值
#define WR_SUCC_RTN 0
#define RD_SUCC_RTN 0
#define WR_FAIL_RTN 0xFF
#define RD_FAIL_RTN 0xFF
#define ERR_TIME_OV 1
#define ERR_ILLEGAL_ADD 2
//写入后读出值和写入值不同
#define ERR_WRT_WRONG_RESULT 1
//连续读时地址超出范围
#define ERR_ADD_OV
sbit pin_SCL = P1^3;
sbit pin_SDA = P1^4;
//sbit pin_WP = P4^1;
#define SDA pin_SDA
#define SCL pin_SCL
extern volatile unsigned char idata g_ucTimer24C04Ack;
extern bit g_FlagWaiting24C04Ack;
void I2CStart(void);
void I2CStop(void);
bit ReadAck(void);
void SendAck(void);
void Send8Bit(unsigned char uc8BitSend);
unsigned char Recev8Bit(void);
bit WriteByte(unsigned char ucDataWrite, unsigned int uiAddWrite);
unsigned char ReadByte(unsigned int uiAddRead);
unsigned char PageWrite(unsigned char const idata *pucDataWrt,
unsigned int uiAddStart_PgWr,
unsigned char ucLength_PgWr);
unsigned char PageFill(unsigned char const idata ucDataPgFill,
unsigned int uiAddStart_Fill,
unsigned char ucLengthFill);
bit SeqRead(unsigned int uiAddStart_SqRd, unsigned char ucLength_SqRd,
unsigned char *pucDataStr);
/*******************************************************************************
* 函数名称: void I2CStart(void);
* 功能描述: 发送I2C起始位
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
void I2CStart(void)
{
//SCL = 0; //在多机时有用
//_nop_();
SDA = 1;
_nop_();
SCL = 1;
_nop_();
SDA = 0;
SCL = 0;
}
/*******************************************************************************
* 函数名称: void I2CStop(void)
* 功能描述: 发送I2C停止位
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
void I2CStop(void)
{
SCL = 0;
_nop_();
SDA = 0;
_nop_();
SCL = 1;
_nop_();
SDA = 1;
}
/*******************************************************************************
* 函数名称: bit ReadAck(void);
* 功能描述: 主机读取I2C总线的应答信号
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 位变量,应答期间SDA的为高返回1,为低返回0
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
bit ReadAck(void)
{
bit FlagAck;
//SCL = 0;
SDA = 1;
_nop_();
SCL = 1;
_nop_();
FlagAck = SDA;
SCL = 0;
return (FlagAck);
}
/*******************************************************************************
* 函数名称: void Send8Bit(unsigned char uc8BitSend);
* 功能描述: 在I2C总线上发送一个字节
* 输入参数: 1个字节的发送数据
* 输出参数: 无
* 返 回 值: 位变量。
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
void Send8Bit(unsigned char uc8BitSend)
{
unsigned char idata i;
for (i = 8; i != 0; i--)
{
//SCL = 0;
uc8BitSend += uc8BitSend;
SDA = CY;//SDA = uc8BitSend &0x80;
SCL = 1;
_nop_();
SCL = 0;
}
}
/*******************************************************************************
* 函数名称: unsigned char Recev8Bit(void);
* 功能描述: 接收8位数据
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 接收到的8位数据
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
unsigned char Recev8Bit(void)
{
unsigned char idata i;
unsigned char idata uc8BitRecev = 0;
for (i = 8; i != 0; i--)
{
//SCL = 0;
//_nop_();
SCL = 1;
uc8BitRecev <<= 1;
uc8BitRecev |=SDA;
_nop_();
SCL = 0;
}
return uc8BitRecev;
}
/********************************************************************************
* 函数名称: bit WriteByte(unsigned char ucDataWrite, unsigned char uiAddWrite);
* 功能描述: 写一个字节到指定地址
* 输入参数: ucDataWrite:要写入的数据, uiAddWrite: 写入地址
* 输出参数: 无
* 返 回 值: 位变量.写入成功返回0
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
********************************************************************************/
bit WriteByte(unsigned char ucDataWrite, unsigned int uiAddWrite)
{
g_ucTimer24C04Ack = WAIT_ACK_TIME;
g_FlagWaiting24C04Ack = 0;
do{
if ((g_FlagWaiting24C04Ack) && (0 == g_ucTimer24C04Ack)) //10ms等待
{
I2CStop();
return ERR_TIME_OV;
}
I2CStart();
//判断地址范围,是否超出24C04范围,要选第一页还是第二页
if (0 != (uiAddWrite >> 9))
{
I2CStop();
return ERR_ILLEGAL_ADD;
}
else if (0 != (uiAddWrite >> 8))
{
Send8Bit(ADD_WRITE_24C04 | 0x02);
}
else
{
Send8Bit(ADD_WRITE_24C04);
}
g_FlagWaiting24C04Ack = 1;
}while (ReadAck()); //判断24C04是否忙
Send8Bit(uiAddWrite);
ReadAck();
Send8Bit(ucDataWrite);
ReadAck();
I2CStop();
if (ucDataWrite != ReadByte(uiAddWrite))
{
return ERR_WRT_WRONG_RESULT;
}
return WR_SUCC_RTN;
}
/*******************************************************************************
* 函数名称: unsigned char ReadByte(unsigned int uiAddRead);
* 功能描述: 读取指定地址的一个字节数据
* 输入参数: 要读取的字节地址
* 输出参数: 无
* 返 回 值: 读出的地址内容
* 其他说明:
* 修改日期 版 本 号 修 改 人 修改内容
*-------------------------------------------------------------------------------
*
*******************************************************************************/
unsigned char ReadByte(unsigned int idata uiAddRead)
{
unsigned char ucDataRead;
g_ucTimer24C04Ack = WAIT_ACK_TIME;
g_FlagWaiting24C04Ack = 0;
do
{
I2CStart();
if (g_FlagWaiting24C04Ack && (0 == g_ucTimer24C04Ack))
{
I2CStop();
return ERR_TIME_OV;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -