?? drv_i2c.c
字號:
////////////////////////////////////////////////////////////////////////
#include "config_60_61.h"
#include "config_GD61.h"
#include "include_GD61.h"
////////////////////////////////////////////////////////////////////////
#define ONE_BYTE_SUBA 1
#define TWO_BYTE_SUBA 2
#define X_ADD_8_SUBA 3
#define I2C_EN 0x40 //I2CONSET bits define
#define I2C_STA 0x20
#define I2C_STO 0x10
#define I2C_SI 0x08
#define I2C_AA 0x04
#define I2C_W 0xFE
#define I2C_R 0x01
#define I2C_DEV_FREE 0x01
#define I2C_DEV_BUSY 0x00
#define I2C_TRANS_LIMIT 100 //100 milsecond, about 100 bytes
extern volatile uint16 mSecondTick;
///////////////////////////////////////////////////////////////////////
/* 定義用于和I2C中斷傳遞信息的全局變量 */
volatile uint8 I2C_dveAddr; //I2C器件從地址
volatile uint8 I2C_subAddrNum; //I2C子地址字節數
volatile uint32 I2C_subAddr; //I2C器件內部子地址
volatile uint8 *I2C_dbuf_Pt; //數據緩沖區指針
volatile uint8 I2C_byteNum; //要讀取/寫入的數據個數
volatile uint8 I2C_endFlag; //I2C總線結束標志:結束總線是置1
volatile uint8 I2C_subAddrFlag; // 子地址控制。
// 0--子地址已經處理或者不需要子地址
// 1--讀取操作
// 2--寫操作
///////////////////////////////////////////////////////////////////////
void I2C_StopAct(void);
void I2C_Initialize(uint32 FrqI2C);
//uint8 I2C_SendByte(uint8 sla, uint8 dat);
//uint8 I2C_RcvByte(uint8 sla, uint8 *dat);
uint8 I2C_ReadNByte (uint8 sla, uint8 suba_type, uint32 suba, uint8*s, uint8 num);
uint8 I2C_WriteNByte(uint8 sla, uint8 suba_type, uint32 suba, uint8*s, uint8 num);
void __irq IRQ_I2C_Serving(void);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
void I2C_StopAct(void)
{
IRQDisable();
I2CONSET = I2C_STO; //0x10; /*結束總線*/
I2CONCLR = I2C_STA|I2C_SI; //0x28;
I2C_endFlag = I2C_DEV_FREE; //1;
VICVectAddr = 0x00; /*中斷處理結束*/
IRQEnable(); // 使能IRQ中斷
}
/*
///////////////////////////////////////////////////////////////////////
** 函數名稱 :I2C_Initialize()
** 函數功能 :I2C初始化
** 入口參數 :FrqI2C I2C總線頻率(最大400K)
** 出口參數 :無
///////////////////////////////////////////////////////////////////////
*/
void I2C_Initialize(uint32 FrqI2C)
{
IRQDisable();
if (FrqI2C > 400000) FrqI2C = 400000;
PINSEL0 = (PINSEL0 & (~0xF0))|0x50; // 不影響其它管腳連接
I2SCLH = (LPC_FPCLK/FrqI2C + 1)/2; /* 設定I2C時鐘*/
I2SCLL = (LPC_FPCLK/FrqI2C)/2;
I2CONCLR = I2C_STA|I2C_SI |I2C_AA; //0x2C;
I2CONSET = I2C_EN; //0x40; /* 使能主I2C*/
/* 設置I2C中斷允許 */
VICVectCntl3 = (0x20|INT_IIC0); /* I2C通道分配到IRQ slot3*/
VICVectAddr3 = (int32)IRQ_I2C_Serving; /* 設置I2C中斷向量*/
VICIntEnable = 1<<INT_IIC0; /* 使能I2C中斷*/
IRQEnable(); // 使能IRQ中斷
}
/*
**********************************************************************************
** 函數名稱 :I2C_ReadNByte()
** 函數功能 :從有子地址器件任意地址開始讀取N字節數據
** 入口參數 : sla 器件從地址
** suba_type 子地址結構 1-單字節地址 2-8+X結構 2-雙字節地址
** suba 器件子地址
** s 數據接收緩沖區指針
** num 讀取的個數
** 出口參數 : TRUE 操作成功
** FALSE 操作失敗
**********************************************************************************
*/
//#define ONE_BYTE_SUBA 1
//#define TWO_BYTE_SUBA 2
//#define X_ADD_8_SUBA 3
uint8 I2C_ReadNByte (uint8 sla, uint8 suba_type, uint32 suba, uint8 *s, uint8 num)
{
I2C_StopAct(); DelayMS_(1);
if (num>0){ /* 判斷num個數的合法性 *//* 參數設置 */
if (suba_type == ONE_BYTE_SUBA){ /* 子地址為單字節 */
I2C_dveAddr = sla|I2C_R; //+ 1; /* 讀器件的從地址,R=1 */
I2C_subAddr = suba; /* 器件子地址 */
I2C_subAddrNum = 1; /* 器件子地址為1字節 */
}else if (suba_type == TWO_BYTE_SUBA){ /* 子地址為2字節 */
I2C_dveAddr = sla|I2C_R; // + 1; /* 讀器件的從地址,R=1 */
I2C_subAddr = suba; /* 器件子地址 */
I2C_subAddrNum = 2; /* 器件子地址為2字節 */
}else if (suba_type == X_ADD_8_SUBA){ /* 子地址結構為8+X*/
I2C_dveAddr = (sla+((suba>>7)&0x0e))|I2C_R; //1;/* 讀器件的從地址,R=1 */
I2C_subAddr = suba & 0x0ff; /* 器件子地址 */
I2C_subAddrNum = 1; /* 器件子地址為8+x */
}
I2C_dbuf_Pt = s; /* 數據接收緩沖區指針 */
I2C_byteNum = num; /* 要讀取的個數 */
I2C_subAddrFlag = 1; /* 有子地址, 讀操作 */
I2C_endFlag = I2C_DEV_BUSY; //0;
I2CONCLR = I2C_AA|I2C_SI|I2C_STA; /* AA SI STA ,清除STA,SI,AA標志位 */
I2CONSET = I2C_STA|I2C_EN; /* STA I2CEN ,置位STA,啟動I2C總線 */
/* 等待I2C操作完成 */
mSecondTick=I2C_TRANS_LIMIT;
while((I2C_endFlag == I2C_DEV_BUSY)&&(mSecondTick>1));
if(I2C_endFlag == I2C_DEV_BUSY) DB_SendString("time overflow in I2C_ReadNByte()");
if (I2C_endFlag == I2C_DEV_FREE) return (TRUE);
else return (FALSE);
}
return (FALSE);
}
/*
***********************************************************************************
** 函數名稱 :I2C_WriteNByte()
** 函數功能 :向有子地址器件寫入N字節數據
** 入口參數 : sla 器件從地址
** suba_type 子地址結構 1-單字節地址 3-8+X結構 2-雙字節地址
** suba 器件內部物理地址
** *s 將要寫入的數據的指針
** num 將要寫入的數據的個數
** 出口參數 : TRUE 操作成功
** FALSE 操作失敗
**********************************************************************************
*/
//#define ONE_BYTE_SUBA 1
//#define TWO_BYTE_SUBA 2
//#define X_ADD_8_SUBA 3
uint8 I2C_WriteNByte(uint8 sla, uint8 suba_type, uint32 suba, uint8 *s, uint8 num)
{
I2C_StopAct(); DelayMS_(1);
if (num>0){ /* 如果讀取的個數為0,則返回錯誤 */ /* 設置參數 */
if (suba_type == ONE_BYTE_SUBA){ /* 子地址為單字節 */
I2C_dveAddr = sla & I2C_W; /* 讀器件的從地址 */
I2C_subAddr = suba; /* 器件子地址 */
I2C_subAddrNum = 1; /* 器件子地址為1字節 */
}
else if (suba_type == TWO_BYTE_SUBA){ /* 子地址為2字節 */
I2C_dveAddr = sla & I2C_W; /* 讀器件的從地址 */
I2C_subAddr = suba; /* 器件子地址 */
I2C_subAddrNum = 2; /* 器件子地址為2字節 */
}else if (suba_type == X_ADD_8_SUBA){ /* 子地址結構為8+X */
I2C_dveAddr = (sla+((suba>>7)&0x0e)) & I2C_W; /*讀器件的從地址*/
I2C_subAddr = suba & 0x0ff; /* 器件子地址 */
I2C_subAddrNum = 1; /* 器件子地址為8+X */
}
I2C_dbuf_Pt = s; /* 數據 */
I2C_byteNum = num; /* 數據個數 */
I2C_subAddrFlag = 2; /* 有子地址,寫操作 */
I2C_endFlag = I2C_DEV_BUSY; //0;
I2CONCLR = I2C_AA|I2C_SI|I2C_STA; /* AA SI STA 清除STA,SI,AA標志位 */
I2CONSET = I2C_STA|I2C_EN; /* STA I2CEN, 置位STA,啟動I2C總線 */
/* 等待I2C操作完成 */
mSecondTick=I2C_TRANS_LIMIT;
while((I2C_endFlag == I2C_DEV_BUSY)&&(mSecondTick>1));
if((I2C_endFlag == I2C_DEV_BUSY)) DB_SendString("time overflow in I2C_WriteNByte()");
if (I2C_endFlag == I2C_DEV_FREE) return (TRUE);
else return (FALSE);
}
return (FALSE);
}
/*
**************************************************************************
** 函數名稱 :__irq IRQ_I2C_Serving()
** 函數名次 :硬件I2C中斷服務程序。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -