?? i2cint.c
字號:
/****************************************************************************
* File:I2CINT.C
* 功能:硬件I2C軟件包,利用中斷方式操作。
* 說明:主程序要配置好I2C總線接口(GPIO、總線時鐘)
****************************************************************************/
#include "config.h"
/* 以下為I2C操作時所需要的變量,在調用I2C子程序前要設置好這些變量 */
volatile uint8 I2C_sla; // 從機地址
volatile uint8 I2C_suba; // 子地址
volatile uint8 *I2C_buf; // 數據緩沖區指針 (讀操作時會被更改)
volatile uint8 I2C_num; // 操作數據個數 (會被更改)
volatile uint8 I2C_end; // 操作結束標志,為1時表示操作結束,為0xFF時表示操作失敗 (會被設置)
volatile uint8 I2C_suba_en; // 子地址使能控制,讀操作時請設置為1,寫操作時請設置為2 (會被更改)
/****************************************************************************
* 名稱:IRQ_I2C()
* 功能:I2C中斷,通過判斷I2C狀態字進行相應的操作。
* 入口參數:無
* 出口參數:無
****************************************************************************/
void __irq IRQ_I2C(void)
{ uint8 sta;
sta = I2STAT; // 讀出I2C狀態字
switch(sta)
{ case 0x08: // 己發送起始條件
if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE; // 指定子地址讀時,先寫入地址
else I2DAT = I2C_sla; // 否則直接發送從機地址
I2CONCLR = 0x28; // SI=0
break;
case 0x10:
I2DAT = I2C_sla; // 重啟動總線后,發送從地址
I2CONCLR = 0x28; // SI=0
break;
case 0x18: // 已發送SLA+W,并已接收應答
if(0==I2C_suba_en) // 無子地址,則直接發送數據
{ if(I2C_num>0)
{ I2DAT = *I2C_buf++;
I2CONCLR = 0x28;
I2C_num--;
}
else
{ I2CONSET = 0x10; // 無數據發送,結束總線
I2CONCLR = 0x28;
I2C_end = 1; // 設置總線操作結束標志
}
break;
}
if(1==I2C_suba_en) // 發送子地址
{ I2DAT = I2C_suba;
I2CONCLR = 0x28;
}
if(2==I2C_suba_en)
{ I2DAT = I2C_suba;
I2CONCLR = 0x28;
I2C_suba_en = 0; // 子地址己處理
}
break;
case 0x28: // 已發送I2C數據,并接收到應答
if(0==I2C_suba_en) // 無子地址,則直接發送數據
{ if(I2C_num>0)
{ I2DAT = *I2C_buf++;
I2CONCLR = 0x28;
I2C_num--;
}
else
{ I2CONSET = 0x10; // 無數據發送,結束總線
I2CONCLR = 0x28;
I2C_end = 1;
}
break;
}
if(1==I2C_suba_en) // 若是指定地址讀,則重新啟動總線
{ I2CONSET = 0x20;
I2CONCLR = 0x18;
I2C_suba_en = 0; // 子地址己處理
}
break;
case 0x20:
case 0x30:
case 0x38:
I2CONCLR = 0x28; // 總線進入不可尋址從模式
I2C_end = 0xFF; // 總線出錯,設置標志
break;
case 0x40: // 己發送SLA+R,并已接收到應答
if(1==I2C_num) // 最后一字節,接收數據后發送非應答信號
{ I2CONCLR = 0x2C; // AA=0,接收到數據后產生非應答
}
else // 接收數據并發送應答信號
{ I2CONSET = 0x04; // AA=1,接收到數據后產生應答
I2CONCLR = 0x28;
}
break;
case 0x50:
*I2C_buf++ = I2DAT; // 讀取數據
I2C_num--;
if(1==I2C_num)
{ I2CONCLR = 0x2C; // AA=0,接收到數據后產生非應答
}
else
{ I2CONSET = 0x04; // AA=1,接收到數據后產生應答
I2CONCLR = 0x28;
}
break;
case 0x58:
*I2C_buf++ = I2DAT; // 讀取最后一字節數據
I2CONSET = 0x10; // 結束總線
I2CONCLR = 0x28;
I2C_end = 1;
break;
case 0x48:
I2CONCLR = 0x28; // 總線進入不可尋址從模式
I2C_end = 0xFF;
break;
}
VICVectAddr = 0x00; // 中斷處理結束
}
/****************************************************************************
* 名稱:ISendStr()
* 功能:使用硬件I2C發送數據。
* 入口參數:無
* 出口參數:返回值為0時表示出錯,為1時表示操作正確。
* 說明:使用前設置好參數
****************************************************************************/
uint8 ISendStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
{ /* 參數設置 */
I2C_sla = sla;
I2C_suba = suba;
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 2;
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 設置為主機,并啟動總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
/****************************************************************************
* 名稱:IRcvStr()
* 功能:使用硬件I2C讀取數據。
* 入口參數:無
* 出口參數:返回值為0時表示出錯,為1時表示操作正確。
* 說明:使用前設置好參數
****************************************************************************/
uint8 IRcvStr(uint8 sla,uint8 suba,uint8 *s,uint8 no)
{ if(0==no) return(0);
/* 參數設置 */
I2C_sla = sla+1;
I2C_suba = suba;
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 1;
I2C_end = 0;
I2CONCLR = 0x2C;
I2CONSET = 0x60; // 設置為主機,并啟動總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -