📄 drv_eeprom.c
字号:
// while(I2C_end == 0);
WatchDogClear(); //clr watchdog
mSecondTick=WHILE_DELAY_TIME;
while((I2C_end == 0)&&(mSecondTick>1));
if(mSecondTick<=1) Uart0SendString("Time overflow in I2C_WriteNByte");
WatchDogClear(); //clr watchdog
IO0SET=EEP_P0_9; //eeprom write protection pin
if (I2C_end == 1) return (TRUE);
else return (FALSE);
}
return (FALSE);
}
/*
**************************************************************************************
** 函数名称 :__irq IRQ_I2C_Serving()
** 函数名次 :硬件I2C中断服务程序。
** 入口参数 :无
** 出口参数 :无
** 说明 :注意处理子地址为2字节的情况。
**************************************************************************
//定义用于和I2C中断传递信息的全局变量
volatile uint8 I2C_sla; //I2C器件从地址
volatile uint32 I2C_suba; //I2C器件内部子地址
volatile uint8 I2C_suba_num; //I2C子地址字节数
volatile uint8 *I2C_buf; //数据缓冲区指针
volatile uint32 I2C_num; //要读取/写入的数据个数
volatile uint8 I2C_end; //I2C总线结束标志:结束总线是置1
volatile uint8 I2C_suba_en; // 子地址控制。
// 0--子地址已经处理或者不需要子地址
// 1--读取操作
// 2--写操作
*/
/////////////////////////////////////////////////////////////////////////
void __irq IRQ_I2C_Serving(void)
{
////
TraceFunAddr((void*)IRQ_I2C_Serving); //for watchdog tracing
////
/* 读取I2C状态寄存器I2STAT */
/* 按照全局变量的设置进行操作及设置软件标志 */
/* 清除中断逻辑,中断返回 */
switch (I2STAT & 0xF8)
{ /* 根据状态码进行相应的处理 */
case 0x08: /* 已发送起始条件 */ /* 主发送和主接收都有 */
/* 装入SLA+W或者SLA+R */
if(I2C_suba_en == 1)/* SLA+R */ /* 指定子地址读 */
{ I2DAT = I2C_sla & 0xFE; /* 先写入地址 */
}
else /* SLA+W */
{ I2DAT = I2C_sla; /* 否则直接发送从机地址 */
}
/* 清零SI位 */
I2CONCLR = (1 << 3)| /* SI */
(1 << 5); /* STA */
break;
case 0x10: /*已发送重复起始条件 */ /* 主发送和主接收都有 */
/* 装入SLA+W或者SLA+R */
I2DAT = I2C_sla; /* 重起总线后,重发从地址 */
I2CONCLR = 0x28; /* 清零SI,STA */
break;
case 0x18:
case 0x28: /* 已发送I2DAT中的数据,已接收ACK */
if (I2C_suba_en == 0)
{
if (I2C_num > 0)
{ I2DAT = *I2C_buf++;
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_num--;
}
else /* 没有数据发送了 */
{ /* 停止总线 */
I2CONSET = (1 << 4); /* STO */
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_end = 1; /* 总线已经停止 */
}
}
else if(I2C_suba_en == 1) /* 若是指定地址读,则重新启动总线 */
{
if (I2C_suba_num == 2)
{ I2DAT = ((I2C_suba >> 8) & 0xff);
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_suba_num--;
break;
}
else if(I2C_suba_num == 1)
{ I2DAT = (I2C_suba & 0xff);
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_suba_num--;
break;
}
else if (I2C_suba_num == 0)
{ I2CONSET = 0x20;
I2CONCLR = 0x08;
I2C_suba_en = 0; /* 子地址己处理 */
break;
}
}
else if (I2C_suba_en == 2)/* 指定子地址写,子地址尚未指定,则发送子地址 */
{
if (I2C_suba_num > 0)
{ if (I2C_suba_num == 2)
{ I2DAT = ((I2C_suba >> 8) & 0xff);
I2CONCLR = 0x28;
I2C_suba_num--;
break;
}
else if (I2C_suba_num == 1)
{ I2DAT = (I2C_suba & 0xff);
I2CONCLR = 0x28;
I2C_suba_num--;
I2C_suba_en = 0;
break;
}
}
}
break;
case 0x40: /* 已发送SLA+R,已接收ACK */
if (I2C_num <= 1) /* 如果是最后一个字节 */
{ I2CONCLR = 1 << 2; /* 下次发送非应答信号 */
}
else
{ I2CONSET = 1 << 2; /* 下次发送应答信号 */
}
I2CONCLR = 0x28; /* 清零SI,STA */
break;
case 0x20: /* 已发送SLA+W,已接收非应答 */
case 0x30: /* 已发送I2DAT中的数据,已接收非应答 */
case 0x38: /* 在SLA+R/W或数据字节中丢失仲裁 */
case 0x48: /* 已发送SLA+R,已接收非应答 */
I2CONCLR = 0x28;
I2C_end = 0xFF;
break;
case 0x50: /* 已接收数据字节,已返回ACK */
*I2C_buf++ = I2DAT;
I2C_num--;
if (I2C_num == 1)/* 接收最后一个字节 */
{ I2CONCLR = 0x2C; /* STA,SI,AA = 0 */
}
else
{ I2CONSET = 0x04; /* AA=1 */
I2CONCLR = 0x28;
}
break;
case 0x58: /* 已接收数据字节,已返回非应答 */
*I2C_buf++ = I2DAT; /* 读取最后一字节数据 */
I2CONSET = 0x10; /* 结束总线 */
I2CONCLR = 0x28;
I2C_end = 1;
break;
default:
break;
}
VICVectAddr = 0x00; /* 中断处理结束*/
}
/////////////////////////////////////////////////////////////////////////////////////////////
void I2C_StopAct(void)
{
I2CONSET = 0x10; /* 结束总线*/
I2CONCLR = 0x28;
I2C_end = 1;
VICVectAddr = 0x00; /* 中断处理结束*/
}
/*
********************************************************************************************
** 函数名称 :I2C_Initialize()
** 函数功能 :I2C初始化
** 入口参数 :Fi2c I2C总线频率(最大400K)
** 出口参数 :无
********************************************************************************************
*/
void I2C_Initialize(uint32 Fi2c)
{
if (Fi2c > 400000) Fi2c = 400000;
// PINSEL0 = (PINSEL0 & 0xFFFFFF0F)|0x50; /* 设置I2C控制口有效*/
PINSEL0 = (PINSEL0 & (~0xF0))|0x50; // 不影响其它管脚连接
I2SCLH = (LPC_FPCLK/Fi2c + 1)/2; /* 设定I2C时钟*/
I2SCLL = (LPC_FPCLK/Fi2c)/2;
I2CONCLR = 0x2C;
I2CONSET = 0x40; /* 使能主I2C*/
/* 设置I2C中断允许 */
// VICIntSelect = 0x00000000; /* 设置所有通道为IRQ中断*/
VICVectCntl3 = (0x20|INT_IIC0); /* I2C通道分配到IRQ slot3*/
VICVectAddr3 = (int32)IRQ_I2C_Serving; /* 设置I2C中断向量*/
VICIntEnable = 1<<INT_IIC0; /* 使能I2C中断*/
}
////////////////////////////////////////////////////////////////////////////
// I2C_ReadNByte(CHIP_CAT1025,ONE_BYTE_SUBA,ADDR_LINE_NUM,&Line_Num,2);
////////////////////////////////////////////////////////////////////////////
void TestEEprom(void)
{
uint8 i;
uint8 page,addr;
char dbuffer[100];
uint8 data_buf[EEPROM_P_NUM][EEPROM_P_SIZE];
uint8 comp_buf[EEPROM_P_NUM][EEPROM_P_SIZE];
uint8 databuff[2];
uint16 ix;
////
Uart0SendEnter(); RF_SendEnter();
sprintf(dbuffer,"Start test EEprom");
Uart0SendString(dbuffer); RF_SendString(dbuffer);
////
I2C_ReadNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEP_INIT_FLAG,databuff,2);
ix = databuff[1]*0x100+databuff[0];
if(ix==EEPROM_INIT_FLAG){
// Uart0SendEnter();
sprintf(dbuffer,"find data in EEprom, EEprom OK.");
Uart0SendString(dbuffer); RF_SendString(dbuffer);
return;
}
////
Uart0SendEnter();
sprintf(dbuffer,"find New EEprom in system, initializing...");
Uart0SendString(dbuffer); RF_SendString(dbuffer);
////
i=0;
for (page=0; page<EEPROM_P_NUM; page++){
for (addr=0; addr<EEPROM_P_SIZE; addr++){
data_buf[page][addr]=i++; // 数据0~9,转换成ASCII码
}
}
for (page=0; page<EEPROM_P_NUM; page++){
for (addr=0; addr<EEPROM_P_SIZE; addr++){
comp_buf[page][addr]=0; // 数据0~9,转换成ASCII码
}
}
/////////////////////////////////////////////////////////////////////////////
for (page=0; page<EEPROM_P_NUM; page++){
WatchDogClear(); //clr watchdog
I2C_WriteNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEPROM_P_SIZE*page,data_buf[page],EEPROM_P_SIZE); // 往起始地址0x00开始写入10个数据
DelayMS_(10);
}
for (page=0; page<EEPROM_P_NUM; page++){
I2C_ReadNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEPROM_P_SIZE*page,comp_buf[page],EEPROM_P_SIZE); // 读回刚才写入的数据
}
for (page=0; page<EEPROM_P_NUM; page++){
for (addr=0; addr<EEPROM_P_SIZE; addr++){
if (comp_buf[page][addr] != data_buf[page][addr]){
sprintf(dbuffer,"find EEprom error at [%d,%d].",page,addr);
Uart0SendString(dbuffer); RF_SendString(dbuffer);
ix=EEPROM_INIT_FLAG+1;
databuff[1]=ix>>8; databuff[0]=ix; // 往起始地址EEP_INIT_FLAG开始写入2个byte
WatchDogClear(); //clr watchdog
I2C_WriteNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEP_INIT_FLAG,databuff,2);
DelayMS_(10);
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// erase all data in EEProm
for (page=0; page<EEPROM_P_NUM; page++){
for (addr=0; addr<EEPROM_P_SIZE; addr++){
data_buf[page][addr]=0x00;
}
}
sprintf(dbuffer,"Warning!!! Erase all data in EEprom");
Uart0SendString(dbuffer); RF_SendString(dbuffer);
// Uart0SendEnter();
for (page=0; page<EEPROM_P_NUM; page++){ // 往起始地址0x00开始写入10个数据
WatchDogClear(); //clr watchdog
I2C_WriteNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEPROM_P_SIZE*page,data_buf[page],EEPROM_P_SIZE);
DelayMS_(10);
}
///////////////////////////////////////////////////////////////////////////////
// write init flag to eeprom
ix=EEPROM_INIT_FLAG;
databuff[1]=ix>>8; databuff[0]=ix; // 往起始地址EEP_INIT_FLAG开始写入2个byte
I2C_WriteNByte(CHIP_CAT1025,ONE_BYTE_SUBA,EEP_INIT_FLAG,databuff,2);
DelayMS_(10);
}
///////////////////////////////////////////////////////////////////////////////
//// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -