?? i2cint.c
字號(hào):
/****************************************************************************
* 文件名:I2CINT.C
* 功能:硬件I2C軟件包,利用中斷方式操作。
* 說(shuō)明:主程序要配置好I2C總線接口(I2C引腳功能和I2C中斷,并已使能I2C主模式)
****************************************************************************/
#include "config.h"
/* 以下為I2C操作時(shí)所需要的變量 */
volatile uint8 I2C_sla; // 從機(jī)地址(即器件地址)
volatile uint8 I2C_suba; // 子地址
volatile uint8 *I2C_buf; // 數(shù)據(jù)緩沖區(qū)指針 (讀操作時(shí)會(huì)被更改)
volatile uint8 I2C_num; // 操作數(shù)據(jù)個(gè)數(shù) (會(huì)被更改)
volatile uint8 I2C_end; // 操作結(jié)束標(biāo)志,為1時(shí)表示操作結(jié)束,為0xFF時(shí)表示操作失敗 (會(huì)被設(shè)置)
volatile uint8 I2C_suba_en; // 子地址使能控制,讀操作時(shí)請(qǐng)?jiān)O(shè)置為1,寫(xiě)操作時(shí)請(qǐng)?jiān)O(shè)置為2 (會(huì)被更改)
/****************************************************************************
* 名稱(chēng):IRQ_I2C()
* 功能:I2C中斷,通過(guò)判斷I2C狀態(tài)字進(jìn)行相應(yīng)的操作。
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
****************************************************************************/
void __irq IRQ_I2C(void)
{ uint8 sta;
sta = I2C0STAT; // 讀出I2C狀態(tài)字
switch(sta)
{ case 0x08: // 己發(fā)送起始條件
if(1==I2C_suba_en) I2C0DAT = I2C_sla&0xFE; // 指定子地址讀時(shí),先寫(xiě)入地址
else I2C0DAT = I2C_sla; // 否則直接發(fā)送從機(jī)地址
I2C0CONCLR = 0x28; // SI=0
break;
case 0x10:
I2C0DAT = I2C_sla; // 重啟動(dòng)總線后,發(fā)送從地址
I2C0CONCLR = 0x28; // SI=0
break;
case 0x18: // 已發(fā)送SLA+W,并已接收應(yīng)答
if(0==I2C_suba_en) // 無(wú)子地址,則直接發(fā)送數(shù)據(jù)
{ if(I2C_num>0)
{ I2C0DAT = *I2C_buf++;
I2C0CONCLR = 0x28;
I2C_num--;
}
else
{ I2C0CONSET = 0x10; // 無(wú)數(shù)據(jù)發(fā)送,結(jié)束總線
I2C0CONCLR = 0x28;
I2C_end = 1; // 設(shè)置總線操作結(jié)束標(biāo)志
}
break;
}
if(1==I2C_suba_en) // 發(fā)送子地址
{ I2C0DAT = I2C_suba;
I2C0CONCLR = 0x28;
}
if(2==I2C_suba_en)
{ I2C0DAT = I2C_suba;
I2C0CONCLR = 0x28;
I2C_suba_en = 0; // 子地址己處理
}
break;
case 0x28: // 已發(fā)送I2C數(shù)據(jù),并接收到應(yīng)答
if(0==I2C_suba_en) // 無(wú)子地址,則直接發(fā)送數(shù)據(jù)
{ if(I2C_num>0)
{ I2C0DAT = *I2C_buf++;
I2C0CONCLR = 0x28;
I2C_num--;
}
else
{ I2C0CONSET = 0x10; // 無(wú)數(shù)據(jù)發(fā)送,結(jié)束總線
I2C0CONCLR = 0x28;
I2C_end = 1;
}
break;
}
if(1==I2C_suba_en) // 若是指定地址讀,則重新啟動(dòng)總線
{ I2C0CONSET = 0x20;
I2C0CONCLR = 0x08;
I2C_suba_en = 0; // 子地址己處理
}
break;
case 0x20:
case 0x30:
case 0x38:
I2C0CONCLR = 0x28; // 總線進(jìn)入不可尋址從模式
I2C_end = 0xFF; // 總線出錯(cuò),設(shè)置標(biāo)志
break;
case 0x40: // 己發(fā)送SLA+R,并已接收到應(yīng)答
if(1==I2C_num) // 最后一字節(jié),接收數(shù)據(jù)后發(fā)送非應(yīng)答信號(hào)
{ I2C0CONCLR = 0x2C; // AA=0,接收到數(shù)據(jù)后產(chǎn)生非應(yīng)答
}
else // 接收數(shù)據(jù)并發(fā)送應(yīng)答信號(hào)
{ I2C0CONSET = 0x04; // AA=1,接收到數(shù)據(jù)后產(chǎn)生應(yīng)答
I2C0CONCLR = 0x28;
}
break;
case 0x50:
*I2C_buf++ = I2C0DAT; // 讀取數(shù)據(jù)
I2C_num--;
if(1==I2C_num)
{ I2C0CONCLR = 0x2C; // AA=0,接收到數(shù)據(jù)后產(chǎn)生非應(yīng)答
}
else
{ I2C0CONSET = 0x04; // AA=1,接收到數(shù)據(jù)后產(chǎn)生應(yīng)答
I2C0CONCLR = 0x28;
}
break;
case 0x58:
*I2C_buf++ = I2C0DAT; // 讀取最后一字節(jié)數(shù)據(jù)
I2C0CONSET = 0x10; // 結(jié)束總線
I2C0CONCLR = 0x28;
I2C_end = 1;
break;
case 0x48:
I2C0CONCLR = 0x28; // 總線進(jìn)入不可尋址從模式
I2C_end = 0xFF;
break;
default:
break;
}
VICVectAddr = 0x00; // 中斷處理結(jié)束
}
/****************************************************************************
* 名稱(chēng):ISendByte()
* 功能:向無(wú)子地址器件發(fā)送一字節(jié)數(shù)據(jù)。
* 入口參數(shù):sla 器件地址
* dat 要發(fā)送的數(shù)據(jù)
* 出口參數(shù):返回值為0時(shí)表示出錯(cuò),為1時(shí)表示操作正確。
* 說(shuō)明:使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
****************************************************************************/
uint8 ISendByte(uint8 sla, uint8 dat)
{ /* 參數(shù)設(shè)置 */
I2C_sla = sla; // 寫(xiě)操作的器件地址
I2C_buf = &dat; // 待發(fā)送的數(shù)據(jù)
I2C_num = 1; // 發(fā)送1字節(jié)數(shù)據(jù)
I2C_suba_en = 0; // 無(wú)子地址
I2C_end = 0;
I2C0CONCLR = 0x2C;
I2C0CONSET = 0x60; // 設(shè)置為主機(jī),并啟動(dòng)總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
/****************************************************************************
* 名稱(chēng):ISendStr()
* 功能:向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)。
* 入口參數(shù):sla 器件從機(jī)地址
* suba 器件子地址
* s 數(shù)據(jù)發(fā)送緩沖區(qū)指針
* no 發(fā)送數(shù)據(jù)個(gè)數(shù)
* 出口參數(shù):返回值為0時(shí)表示出錯(cuò),為1時(shí)表示操作正確。
* 說(shuō)明:使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
****************************************************************************/
uint8 ISendStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
{ /* 參數(shù)設(shè)置 */
I2C_sla = sla; // 寫(xiě)操作的器件地址
I2C_suba = suba; // 子地址
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 2; // 有子地址寫(xiě)
I2C_end = 0;
I2C0CONCLR = 0x2C;
I2C0CONSET = 0x60; // 設(shè)置為主機(jī),并啟動(dòng)總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
/****************************************************************************
* 名稱(chēng):IRcvByte()
* 功能:向無(wú)子地址器件讀取一字節(jié)數(shù)據(jù)。
* 入口參數(shù):sla 器件地址
* dat 接收數(shù)據(jù)的變量指針
* 出口參數(shù):返回值為0時(shí)表示操作出錯(cuò),為1時(shí)表示操作正確。
* 說(shuō)明:使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
****************************************************************************/
uint8 IRcvByte(uint8 sla, uint8 *dat)
{ /* 參數(shù)設(shè)置 */
I2C_sla = sla+1; // 讀操作的器件地址
I2C_buf = dat;
I2C_num = 1;
I2C_suba_en = 0; // 無(wú)子地址
I2C_end = 0;
I2C0CONCLR = 0x2C;
I2C0CONSET = 0x60; // 設(shè)置為主機(jī),并啟動(dòng)總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
/****************************************************************************
* 名稱(chēng):IRcvStr()
* 功能:向有子地址器件讀取多字節(jié)數(shù)據(jù)。
* 入口參數(shù):sla 器件地址
* suba 器件子地址
* s 數(shù)據(jù)接收緩沖區(qū)指針
* no 讀取數(shù)據(jù)個(gè)數(shù)
* 出口參數(shù):返回值為0時(shí)表示操作出錯(cuò),為1時(shí)表示操作正確。
* 說(shuō)明:使用前要初始化好I2C引腳功能和I2C中斷,并已使能I2C主模式
****************************************************************************/
uint8 IRcvStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
{ if(0==no) return(0);
/* 參數(shù)設(shè)置 */
I2C_sla = sla+1; // 讀操作的器件地址
I2C_suba = suba;
I2C_buf = s;
I2C_num = no;
I2C_suba_en = 1; // 有子地址讀
I2C_end = 0;
I2C0CONCLR = 0x2C;
I2C0CONSET = 0x60; // 設(shè)置為主機(jī),并啟動(dòng)總線
while(0==I2C_end);
if(1==I2C_end) return(1);
else return(0);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -