?? drv_i2c.c
字號:
** 入口參數 :無
** 出口參數 :無
** 說明 :注意處理子地址為2字節的情況。
**************************************************************************
//定義用于和I2C中斷傳遞信息的全局變量
volatile uint8 I2C_dveAddr; //I2C器件從地址
volatile uint32 I2C_subAddr; //I2C器件內部子地址
volatile uint8 I2C_subAddrNum; //I2C子地址字節數
volatile uint8 *I2C_dbuf_Pt; //數據緩沖區指針
volatile uint8 I2C_byteNum; //要讀取/寫入的數據個數
volatile uint8 I2C_endFlag; //I2C總線結束標志:結束總線是置1
volatile uint8 I2C_subAddrFlag; // 子地址控制。
// 0--子地址已經處理或者不需要子地址
// 1--讀取操作
// 2--寫操作
*/
/////////////////////////////////////////////////////////////////////////
/* 讀取I2C狀態寄存器I2STAT */
/* 按照全局變量的設置進行操作及設置軟件標志 */
/* 清除中斷邏輯,中斷返回 */
void __irq IRQ_I2C_Serving(void)
{
switch (I2STAT & 0xF8) { /* 根據狀態碼進行相應的處理 */
/*(1)*/ case 0x08: /* 已發送起始條件 */ //will send SLA+W and receive ACK
/*[1]*/
/*[4]*/
if(I2C_subAddrFlag == 1){ /* SLA+R */ /* 指定子地址,讀*/
/*[1]*/ I2DAT = I2C_dveAddr & I2C_W; //0xFE; /* 先寫入地址 */
}else{ //will send SLA+W or SLA+R.
/*(1)*/ I2DAT = I2C_dveAddr; /* 直接發送從機地址 */
/*[4]*/
}
/* 清零SI位 */
I2CONCLR = I2C_SI|I2C_STA; /* clr SI STA */
break;
////
case 0x10: /*已發送重復起始條件 */ /* 主發送和主接收都有 */
//will send SLA+W or SLA+R.
I2DAT = I2C_dveAddr; /* 重起總線后,重發從地址*/
I2CONCLR = I2C_SI|I2C_STA; //0x28; clr SI,STA
break;
/*(2)*/ case 0x18: // sended SLA+W, got ACK.
/*[2]*/
/*(3)*/ case 0x28: /* 已發送I2DAT中的數據,已接收ACK */
/*(3)*/ if (I2C_subAddrFlag == 0){ //sub address have been sent out.
if (I2C_byteNum > 0){ //data treatment.
I2DAT = *I2C_dbuf_Pt++;
I2CONCLR = I2C_STA|I2C_SI; //0x28; /* 清零SI,STA */
I2C_byteNum--;
}else{ //data sent over, stop I2C bus.
I2CONSET = I2C_STO; //(1 << 4); /* STO */
I2CONCLR = I2C_STA|I2C_SI; //0x28; /* 清零SI,STA */
I2C_endFlag = I2C_DEV_FREE; //1; /*總線已經停止*/
}
/*[2]*/ }else if(I2C_subAddrFlag == 1){ /* 若是指定地址讀,則重新啟動總線 */
if (I2C_subAddrNum == 2){
I2DAT = ((I2C_subAddr >> 8) & 0xff); //will send high address.
I2CONCLR = I2C_STA|I2C_SI; //0x28; /* 清零SI,STA */
I2C_subAddrNum--;
// break;
}else if(I2C_subAddrNum == 1){
I2DAT = (I2C_subAddr & 0xff); //will send low address.
I2CONCLR = I2C_STA|I2C_SI; //0x28; /* 清零SI,STA */
I2C_subAddrNum--;
// break;
/*[3]*/ }else if (I2C_subAddrNum == 0){ //sub address sent out.
I2CONSET = I2C_STA; //0x20; //resend START condition.
I2CONCLR = I2C_SI; //0x08;
I2C_subAddrFlag = 0; /* 子地址己處理 */
// break;
}
/*(2)*/ }else if (I2C_subAddrFlag == 2){ //will send subaddress and get ACK
// if (I2C_subAddrNum>0){ //sub_address treatment.
if (I2C_subAddrNum == 2){
I2DAT = ((I2C_subAddr>>8) & 0xff); //will send high address
I2CONCLR = I2C_STA|I2C_SI; //0x28;
I2C_subAddrNum--;
// break;
}else if (I2C_subAddrNum == 1){
I2DAT = (I2C_subAddr & 0xff); //will send low address.
I2CONCLR = I2C_STA|I2C_SI; //0x28;
I2C_subAddrNum--;
I2C_subAddrFlag = 0; //have treated sub address.
// break;
}
// }
}
break;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//// read data treatment.
/*[5]*/ case 0x40: /* 已發送SLA+R,已接收ACK */
if (I2C_byteNum <= 1){ /* 如果是最后一個字節 */
I2CONCLR = I2C_AA; //1 << 2; /* 下次發送非應答信號 */
}else{
I2CONSET = I2C_AA; //1 << 2; /* 下次發送應答信號 */
}
I2CONCLR = I2C_STA|I2C_SI; //0x28; /* 清零SI,STA */
break;
/*[6]*/ case 0x50: /* 已接收數據字節,已返回ACK */
*I2C_dbuf_Pt++ = I2DAT; //get received data
I2C_byteNum--;
if (I2C_byteNum == 1){ /* 接收最后一個字節 */
I2CONCLR = I2C_STA|I2C_SI|I2C_AA; //0x2C; /* STA,SI,AA = 0 */
}else{
I2CONSET = I2C_AA; //0x04; /* AA=1 */
I2CONCLR = I2C_STA|I2C_SI; //0x28;
}
break;
/*[7]*/ case 0x58: /* 已接收數據字節,已返回非應答 */
*I2C_dbuf_Pt++ = I2DAT; /* 讀取最后一字節數據 */
I2CONSET = I2C_STO ; //0x10; /* 結束總線 */
I2CONCLR = I2C_STA|I2C_SI; //0x28;
I2C_endFlag = I2C_DEV_FREE; //1; //end I2C memory accessing.
break;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// erro case treatment.
case 0x20: /* 已發送SLA+W,已接收非應答 */
case 0x30: /* 已發送I2DAT中的數據,已接收非應答 */
case 0x38: /* 在SLA+R/W或數據字節中丟失仲裁 */
case 0x48: /* 已發送SLA+R,已接收非應答 */
I2CONCLR = I2C_STA|I2C_SI; //0x28;
I2C_endFlag = I2C_DEV_FREE; // //0xFF; original
break;
////
default:
break;
}
VICVectAddr = 0x00; /* 中斷處理結束*/
}
/*
/////////////////////////////////////////////////////////////////////////////
** 函數名稱:I2C_SendByte()
** 函數功能:向無子地址器件發送1字節數據。
** 入口參數:sla 器件地址
** dat 要發送的數據
** 出口參數:返回值為0時表示出錯,為1時表示操作正確。
** 說明: 使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
/////////////////////////////////////////////////////////////////////////////
*/
/*
uint8 I2C_SendByte(uint8 sla, uint8 dat)
{
I2C_StopAct();
DelayMS_(10);
// 參數設置
I2C_dveAddr = sla & I2C_W; // 寫操作的器件地址
I2C_dbuf_Pt = &dat; // 待發送的數據
I2C_byteNum = 1; // 發送1字節數據
I2C_subAddrFlag = 0; // 無子地址
I2C_endFlag = I2C_DEV_BUSY; //0;
I2CONCLR = I2C_STA|I2C_SI |I2C_AA; //0x2C;
I2CONSET = I2C_EN |I2C_STA; //0x60; // 設置為主機,并啟動總線
mSecondTick=I2C_TRANS_LIMIT;
while((I2C_endFlag==I2C_DEV_BUSY)&&(mSecondTick>1));
if(I2C_endFlag ==I2C_DEV_BUSY) DB_SendString("time overflow in I2C_SendByte()");
if(I2C_endFlag==I2C_DEV_FREE) return(TRUE);
else return(FALSE);
}
*/
/*
/////////////////////////////////////////////////////////////////////////////
** 函數名稱:I2C_RcvByte()
** 函數功能:向無子地址器件讀取1字節數據。
** 入口參數:sla 器件地址
** dat 接收數據的變量指針
** 出口參數:返回值為0時表示操作出錯,為1時表示操作正確。
** 說明:使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
/////////////////////////////////////////////////////////////////////////////
*/
/*
uint8 I2C_RcvByte(uint8 sla, uint8 *dat)
{
I2C_StopAct();
DelayMS_(10);
// 參數設置
I2C_dveAddr = sla | I2C_R; //+1; // 讀操作的器件地址
I2C_dbuf_Pt = dat;
I2C_byteNum = 1;
I2C_subAddrFlag = 0; // 無子地址
I2C_endFlag = I2C_DEV_BUSY; //0;
I2CONCLR = I2C_STA|I2C_SI|I2C_AA; //0x2C;
I2CONSET = I2C_EN |I2C_STA; //0x60; // 設置為主機,并啟動總線
mSecondTick=I2C_TRANS_LIMIT;
while((I2C_endFlag==I2C_DEV_BUSY)&&(mSecondTick>1));
if(I2C_endFlag ==I2C_DEV_BUSY) DB_SendString("time overflow in I2C_RcvByte()");
if(I2C_endFlag==I2C_DEV_FREE) return(TRUE);
else return(FALSE);
}
*/
/////////////////////////////////////////////////////////////////////////////
//// end of file
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -