?? e2prom.c
字號:
/*************************************************************
WPD800 Cat1161驅動 E2PROM
修改歷史 2007-10-11 zaken create version 1.0
*************************************************************/
#include "main.h"
#include "sample.h"
#include "E2PROM.h"
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 I2C_Process(void);
bool Eeprom_Init(DWORD speed)
{
static int status;
int i;
BYTE testbuf[10];
//初始化I2C接口
if (speed > 400000)
speed = 400000;
PINSEL0 = (PINSEL0 & (~0xF0)) | 0x50; // 不影響其它管腳連接
I2SCLH = (Fpclk/speed + 1) / 2; /* 設定I2C時鐘 */
I2SCLL = (Fpclk/speed)/2;
I2CONCLR = 0x2C;
I2CONSET = 0x40;
for(i=0;i<10;i++)
testbuf[i]=0x10+i;
status=Eeprom_Write(testbuf,0,10);
for(i=0;i<10;i++)
testbuf[i]=0;
status=Eeprom_Read(testbuf,0,10);
/* 使能主I2C */
return TRUE;
}
//E2PROM寫入處理
bool Eeprom_Write(BYTE *pSrc,WORD addr,WORD size)
{
DWORD timer;//計算執行時間
I2C_sla=EEPROM_ADDR;
if(addr>255)
I2C_suba_num=2;
else
I2C_suba_num=1;
I2C_suba = addr;
I2C_buf = pSrc; /* 數據 */
I2C_num = size; /* 數據個數 */
I2C_suba_en = 2; /* 有子地址,寫操作 */
I2C_end = 0;
timer_start();//計算執行時間
I2C_Process();
timer=get_timer();//clk
timer=clk_to_time(timer);//ms
return (I2C_end==1);
}
//E2PROM讀取處理
//流程:
// 先假寫
//
//
//
//
//
//
//
//
bool Eeprom_Read(BYTE *pSrc,WORD addr,WORD size)
{
DWORD timer;//計算執行時間
I2C_sla=EEPROM_ADDR|0x01;
if(addr>255)
I2C_suba_num=2;
else
I2C_suba_num=1;
I2C_suba = addr;
I2C_buf = pSrc; /* 數據 */
I2C_num = size; /* 數據個數 */
I2C_suba_en = 1; /* 有子地址,寫操作 */
I2C_end = 0;
timer_start();//計算執行時間
I2C_Process();
timer=get_timer();//clk
timer=clk_to_time(timer);//ms
return (I2C_end==1);
}
void I2C_Process(void)
{
/* 清除STA,SI,AA標志位 */
I2CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,啟動I2C總線 */
I2CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN*/
while(I2C_end==0)
{
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; /* 總線已經停止 */
}
}
if(I2C_suba_en == 1) /* 若是指定地址讀,則重新啟動總線 */
{
if (I2C_suba_num == 2)
{ I2DAT = ((I2C_suba >> 8) & 0xff);
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_suba_num--;
break;
}
if(I2C_suba_num == 1)
{ I2DAT = (I2C_suba & 0xff);
I2CONCLR = 0x28; /* 清零SI,STA */
I2C_suba_num--;
break;
}
if (I2C_suba_num == 0)
{ I2CONSET = 0x20;
I2CONCLR = 0x08;
I2C_suba_en = 0; /* 子地址己處理 */
break;
}
}
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;
}
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;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -