📄 i2c_module1.c
字号:
/*===========================================================================
* 2006年。三星仪表SOC芯片开发项目
*
*
* 文件名称:Show_Module.c
* 文件标识:
* 摘 要:
*
*
* 当前版本:Ver 1.0
* 作 者:罗冬生
* 修改内容:
* 修改日期:
* 完成日期:
===============================================================================================*/
#ifndef _I2C_Module_
#define _I2C_Module_
//===============================================================================================
#include "includes.h"
//===============================================================================================
void DelayMs(unsigned char delay)
{
unsigned char i;
while (delay--)
{
for (i=0;i<255;i++)
{
asm(" NOP ");
asm(" NOP ");
asm(" NOP ");
}
}
}
//------------------------------------------------------------------------------------------------
#define E2promSlv_Adr 0xA8
#define I2C_SDA P0_bit.D4
#define I2C_SCL P0_bit.D6
#define NOP2 {asm(" NOP "); asm(" NOP ");}
#define NOP1 {asm(" NOP ");}
__code const unsigned char Byte_Bit[8] = {
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
}; //add
//------------------------------------------------------------------------------------------------
/***** 启动I2C 工作 ****/
void I2C_Start(void)
{
I2C_SDA = 1; //I2c_Sda_High
NOP2;
NOP1;
I2C_SCL = 1; //I2c_Scl_High
NOP2;
NOP2;
I2C_SDA = 0; //I2c_Sda_Low
NOP2;
NOP1;
I2C_SCL = 0; //I2c_Scl_Low
}
/********* 结束I2C 工作 *********/
void I2C_Stop(void)
{
I2C_SCL = 0; //I2c_Scl_Low
NOP2;
I2C_SDA = 0; //I2c_Sda_Low
NOP2;
NOP1;
I2C_SCL = 1; //I2c_Scl_High
NOP2;
NOP2;
I2C_SDA = 1; //I2c_Sda_High
}
/******* 测试从器件应答 ***************/
//return non-zero if ACK received
unsigned char Test_ACk(void)
{
register unsigned char ack;
I2C_SCL = 0; //I2c_Scl_Low
I2C_SDA = 1; //I2c_Sda_High
NOP2;
ack = ErrorFalse;
I2C_SCL = 1; //I2c_Scl_High
NOP2;
if(I2C_SDA)
ack = ErrorTrue;
I2C_SCL = 0; //I2c_Scl_Low
// I2C_SDA = 0; //I2c_Sda_Low
return ack;
}
/********* 正常应答 *********/
void I2C_ACK(void)
{
I2C_SCL = 0; //I2c_Scl_Low
NOP2;
I2C_SDA = 0; //I2c_Sda_Low
NOP2;
I2C_SCL = 1; //I2c_Scl_High
NOP2;
// I2C_SCL = 0; //I2c_Scl_Low
}
/************* 不应答 *************/
void I2C_NACK(void)
{
I2C_SCL = 0; //I2c_Scl_Low
NOP2;
I2C_SDA = 1; //I2c_Sda_High
NOP2;
I2C_SCL = 1; //I2c_Scl_High
NOP2;
// I2C_SCL = 0; //I2c_Scl_Low
}
/******** 通过I2C总线发送一个字节 *********/
void I2C_SendByte(unsigned char data)
{
register unsigned char k=8;
for(k=0; k<8; k++)
{
I2C_SCL = 0; //I2c_Scl_Low
if(data & Byte_Bit[k]) // output bit of data
I2C_SDA = 1; //I2c_Sda_High
else
I2C_SDA = 0; //I2c_Sda_Low
NOP2;
I2C_SCL = 1; //I2c_Scl_High
NOP1;
}
NOP1;
I2C_SCL = 0; //I2c_Scl_Low
}
/******** 通过I2C总线接收一个字节 *********/
unsigned char I2C_RcvByte(void)
{
register unsigned char data, i;
I2C_SCL = 0; //I2c_Scl_Low
I2C_SDA = 1; //I2c_Sda_High
data = 0;
for(i=0;i<8;i++)
{
I2C_SCL = 1; //I2c_Scl_High
if(I2C_SDA)
data |= Byte_Bit[i];
NOP2;
I2C_SCL = 0; //I2c_Scl_Low
NOP1;
}
return data;
}
/******** I2C总线接收启动的头 *********/
unsigned char I2C_SendHand(unsigned int e2Adr)
{
unsigned char err;
err = ErrorFalse;
I2C_Start();
I2C_SendByte(E2promSlv_Adr | ((unsigned char)(e2Adr>>7) & 0x06));
err = Test_ACk();
I2C_SendByte ((unsigned char)e2Adr);
err |= Test_ACk();
return err;
}
//------------------------------------------------------------------------------------------------
/*
摘 要: 比较e2prom中的数据
输 入:1、 e2prom中的地址(实物地址)
2、 比较数据存放的地址(idata+iRAM_Adr或xdata+xRAM_Adr或PROM+pROM_Adr),硬件统一编定地址
3、 读取数据长度(char类型)
输 出: 函数返回比较结果,比较正确返回"ErrorFalse",比较错误或I2C操作错误返回"ErrorTrue"
*/
unsigned char CompareE2prom(unsigned int e2Adr,unsigned int DataAdr,unsigned char Len)
{
register unsigned char k,temp,i,err;
k =DataAdrCheck(DataAdr); //判断数据源是在iRAM、xRAM、pROM中
DataAdr &= 0x3fff;
if (Len==0)
return ErrorFalse;
err = I2C_SendHand(e2Adr);
I2C_Start();
I2C_SendByte((E2promSlv_Adr | 0x01) | ((unsigned char)(e2Adr>>7) & 0x06)); //准备读
err |= Test_ACk();
for (i=0;i<Len;i++)
{
temp = I2C_RcvByte();
if (i==(Len-1))
I2C_NACK();
else
I2C_ACK();
if (GetData_Api(DataAdr+i,k)!=temp)
err = ErrorTrue;
}
I2C_Stop();
return err;
}
//------------------------------------------------------------------------------------------------------------
/*
摘 要: 从e2prom中读取数据
输 入:1、 e2prom中的地址(实物地址)
2、 数据存放的地址(idata+iRAM_Adr或xdata+xRAM_Adr),硬件统一编定地址
3、 读取数据长度(char类型)
输 出: 函数I2C操作结果,操作正确返回"ErrorFalse",I2C操作错误返回"ErrorTrue"
*/
unsigned char E2prom_Read(unsigned int e2Adr,unsigned int DataBuf,unsigned char Len)
{
register unsigned char k,temp,i,err;
k =DataAdrCheck(DataBuf); //判断数据源是在iRAM、xRAM、pROM中
DataBuf &= 0x3fff;
if (Len==0)
return ErrorFalse;
err = I2C_SendHand(e2Adr);
I2C_Start();
I2C_SendByte((E2promSlv_Adr | 0x01) | ((unsigned char)(e2Adr>>7) & 0x06)); //准备读
err |= Test_ACk();
for (i=0;i<Len;i++)
{
temp = I2C_RcvByte();
if (i==(Len-1))
I2C_NACK();
else
I2C_ACK();
PutData_Api(temp,DataBuf+i,k); //保存数据
}
I2C_Stop();
return err;
}
//------------------------------------------------------------------------------------------------
/*
摘 要: 将数据写入e2prom中
输 入:1、 e2prom中的地址(实物地址)
2、 写入数据存放的地址(idata+iRAM_Adr或xdata+xRAM_Adr或PROM+pROM_Adr),硬件统一编定地址
3、 写入数据长度(char类型)
输 出: 函数返回I2C操作结果,操作正确返回"ErrorFalse",I2C操作错误返回"ErrorTrue"
*/
unsigned char E2prom_Write(unsigned int e2Adr,unsigned int DataBuf,unsigned char Len)
{
register unsigned char k,i,err;
k = DataAdrCheck(DataBuf); //判断数据源是在iRAM、xRAM、pROM中
DataBuf &= 0x3fff;
err = ErrorFalse;
while (Len)
{
i = 16-(((unsigned char)e2Adr) & 0x0F); //AT24C08存储器写缓冲区为16Byte,并且地址对齐。
if (Len < i)
i = Len;
err |= I2C_SendHand(e2Adr);
Len -=i; //修改长度
e2Adr +=i; //修改eeprom地址
while (i--)
{
I2C_SendByte ( GetData_Api(DataBuf,k)); //取数据并写e2prom
err |= Test_ACk();
DataBuf++;
}
I2C_Stop();
//加喂狗程序
DelayMs(15); //延时10ms
}
return err;
}
//------------------------------------------------------------------------------------------------
/*
摘 要: 将数据设置到e2prom中(对e2prom设置固定数据,用于清零等操作)
输 入:1、 e2prom中的地址(实物地址)
2、 被设置的数据(char类型)
3、 写入数据长度(int类型)
输 出: 函数返回I2C操作结果,操作正确返回"ErrorFalse",I2C操作错误返回"ErrorTrue"
*/
unsigned char E2prom_Set(unsigned int e2Adr,unsigned char DataVal,unsigned int Len)
{
register unsigned char i,err;
err = ErrorFalse;
while (Len)
{
i = 16-(((unsigned char)e2Adr) & 0x0F); //AT24C08存储器写缓冲区为16Byte,并且地址对齐。
if (Len < i)
i = Len;
err |= I2C_SendHand(e2Adr);
Len -=i; //修改长度
e2Adr +=i; //修改eeprom地址
while (i--)
{
I2C_SendByte ( DataVal); //设数据到e2prom
err |= Test_ACk();
}
I2C_Stop();
//加喂狗程序
DelayMs(15); //延时10ms
}
return err;
}
//----------------------------------------------------------------------------------------------------
/*
摘 要: 将数据写入e2prom中,同时判断操作正确性,操作错误时作3次同样的处理,3次都不正确,置错误标志。
输 入:1、 e2prom中的地址(实物地址)
2、 写入数据存放的地址(idata+iRAM_Adr或xdata+xRAM_Adr或PROM+pROM_Adr),硬件统一编定地址
3、 写入数据长度(int类型)
输 出: 函数返回I2C操作结果,操作正确返回"ErrorFalse",I2C操作错误返回"ErrorTrue"
*/
unsigned char WriteE2prom_Api(unsigned int e2Adr,unsigned int DataBuf,unsigned char Len)
{
unsigned char loop;
loop=3;
E2PROM_ERR=0;
while (loop--)
{
if (E2prom_Write(e2Adr, DataBuf,Len)==ErrorFalse)
{
if (CompareE2prom(e2Adr, DataBuf,Len)==ErrorFalse)
return ErrorFalse;
else
E2PROM_ERR=1;
}
}
if (E2PROM_ERR)
SysErrNumb = SysErr_E2prom ; // E2PROM 读写数据错误
else
SysErrNumb = SysErr_I2C; //I2C操作错误
return ErrorTrue;
}
//----------------------------------------------------------------------------------------------------
/*
摘 要: 从e2prom读取数据中,同时判断操作正确性,操作错误时作3次同样的处理,3次都不正确,置错误标志。
输 入:1、 e2prom中的地址(实物地址)
2、 读出的数据存放地址(idata+iRAM_Adr或xdata+xRAM_Adr),硬件统一编定地址
3、 读取数据长度(char类型)
输 出: 函数返回I2C操作结果,操作正确返回"ErrorFalse",I2C操作错误返回"ErrorTrue"
*/
unsigned char ReadE2prom_Api(unsigned int e2Adr,unsigned int DataBuf,unsigned char Len)
{
unsigned char loop;
loop=3;
while (loop--)
{
if (E2prom_Read(e2Adr, DataBuf,Len)==ErrorFalse)
return ErrorFalse;
}
SysErrNumb = SysErr_I2C; //I2C操作错误
return ErrorTrue;
}
//===============================================================================================
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -