?? i2c.c
字號:
/******************************************************************************************************
** File Name: I2C.c
** Description: S3C2410的I2C軟件包
** 查詢控制方式
********************************************************************************************************/
#define IN_I2C
#include "config.h"
// I2C總線設置宏定義
#define IICCON_DACK ((1<<7) | (1<<6) | (1<<5) | (3<<0)) /* 使能ACK位,IICCLK=PCLK/512=97656 */
#define IICCON_DNACK ((0<<7) | (1<<6) | (1<<5) | (3<<0)) /* 中斷使能(這樣才能正確操作I2C) */
/*********************************************************************************************************
** Function name: InitI2C
** Descriptions: 初始化總線 (100KHz總線速率)
** 設FCLK=200MHz,HCLK=100MHz,PCLK=50MHz。
** Input: 無
** Output: 無
********************************************************************************************************/
void InitI2C(void)
{
// 設置管腳連接
rGPECON = (rGPECON & 0x0FFFFFFF) | 0xA0000000; // 設置I2C口使能
rGPEUP = rGPEUP | 0xC000; // 禁止內部上拉電阻
// 設置I2C控制寄存器 (使能ACK位時才能接收從機的應答位)
rIICCON = IICCON_DACK;
// 設置I2C為主機模式
rIICSTAT = (3<<6)|(1<<4);
// 從機地址 (作主機時沒有用)
rIICADD = 0x10;
}
/*********************************************************************************************************
** Function name: START_I2C
** Descriptions: 啟動總線,發送從機地址,并發送從機地址
** Input: sla 從機動地址
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
** Note: sla位最低位為讀寫控制位
********************************************************************************************************/
int StartI2C(uint8 sla)
{
uint32 i;
rIICDS = sla; // 設置從機地址
if(sla&0x01)
{
rIICSTAT = (2<<6)|(1<<5)|(1<<4); // 主接收模式,發送使能,啟動總線
rIICCON = IICCON_DACK; // 若是重啟總線,則需要有此操作
}
else
{
rIICSTAT = (3<<6)|(1<<5)|(1<<4); // 主發送模式,發送使能,啟動總線
}
// 等待操作完成
while((rIICCON&0x10) == 0);
// 判斷操作是否成功 (總線仲裁和從機應答)
if((rIICSTAT&0x09) == 0)
{
return(TRUE);
}
else
{
// 發送結束信號
if(sla&0x01) rIICSTAT = (2<<6)|(0<<5)|(1<<4);
else rIICSTAT = (3<<6)|(0<<5)|(1<<4);
rIICCON = IICCON_DACK;
for(i=0; i<5000; i++); // 等待結束信號產生完畢
return(FALSE);
} // end of if((rIICSTAT&0x09) == 0)...else...
}
/*********************************************************************************************************
** Function name: I2C_SendByte
** Descriptions: 發送一字節數據,并接收應答位
** Input: dat 要發送的數據
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
********************************************************************************************************/
int I2C_SendByte(uint8 dat)
{
uint32 i;
rIICDS = dat; // 將數據寫入I2C數據寄存器
rIICCON = IICCON_DACK; // 清除中斷標志,允許發送數據操作
// 等待操作完成
while((rIICCON&0x10) == 0);
// 判斷操作是否成功 (總線仲裁和從機應答)
if((rIICSTAT&0x09) == 0)
{
return(TRUE);
}
else
{
// 發送結束信號
rIICSTAT = (3<<6)|(0<<5)|(1<<4);
rIICCON = IICCON_DACK;
for(i=0; i<5000; i++); // 等待結束信號產生完畢
return(FALSE);
}
}
/*********************************************************************************************************
** Function name: I2C_RcvByteNA
** Descriptions: 接上I2C總線上一字節數據,并發送非應答位
** Input: dat 用于接收數據的指針
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
********************************************************************************************************/
int I2C_RcvByteNA(uint8 *dat)
{
uint32 i;
// 允許接收數據
rIICCON = IICCON_DNACK;
// 等待接收數據操作完成
while((rIICCON&0x10) == 0);
// 判斷操作是否成功 (總線仲裁)
if((rIICSTAT&0x08) != 0)
{
// 發送結束信號
rIICSTAT = (2<<6)|(0<<5)|(1<<4);
rIICCON = IICCON_DACK;
for(i=0; i<5000; i++); // 等待結束信號產生完畢
return(FALSE);
}
*dat = rIICDS; // 讀取數據
return(TRUE);
}
/*********************************************************************************************************
** Function name: I2C_RcvByteA
** Descriptions: 接上I2C總線上一字節數據,并發送應答位
** Input: dat 用于接收數據的指針
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
********************************************************************************************************/
int I2C_RcvByteA(uint8 *dat)
{
uint32 i;
// 允許接收數據
rIICCON = IICCON_DACK;
// 等待接收數據操作完成
while((rIICCON&0x10) == 0);
// 判斷操作是否成功 (總線仲裁)
if((rIICSTAT&0x08) != 0)
{
// 發送結束信號
rIICSTAT = (2<<6)|(0<<5)|(1<<4);
rIICCON = IICCON_DACK;
for(i=0; i<5000; i++); // 等待結束信號產生完畢
return(FALSE);
}
*dat = rIICDS; // 讀取數據
return(TRUE);
}
/*********************************************************************************************************
** Function name: STOP_I2C
** Descriptions: 結束總線
** Input: send I2C當前模模式。主發送模式時為1,否則為0(主接收模式)
** Output: 無
********************************************************************************************************/
void StopI2C(uint8 send)
{
uint32 i;
if(send)
{
rIICSTAT = (3<<6)|(0<<5)|(1<<4);// 發送結束信號
}
else
{
rIICSTAT = (2<<6)|(0<<5)|(1<<4);// 發送結束信號
}
rIICCON = IICCON_DACK;
for(i=0; i<5000; i++); // 等待結束信號產生完畢
}
/*********************************************************************************************************
** Function name: ISendStr
** Descriptions: 使用硬件I2C發送數據。
** Input: sla 從機地址
** suba 器件子地址(第一字節用來表示子地址字節個數)
** s 發送數據緩沖區
** no 發送數據個數
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
** Note: 使用前設置好參數。程序不會更改s、suba緩沖區的數據
********************************************************************************************************/
int ISendStr(uint8 sla, uint8 *suba, uint8 *s, uint8 no)
{
int bak;
sla = sla & 0xFE;
if(!StartI2C(sla))
{
if(!StartI2C(sla)) return(FALSE); // 啟動總線,發送從機地址
}
// 發送器件子地址
bak = *suba++;
for(; bak>0; bak--)
{
if(!I2C_SendByte(*suba++)) return(FALSE);
}
// 發送數據
for(; no>0; no--)
{
if(!I2C_SendByte(*s)) return(FALSE);
s++;
}
StopI2C(1); // 結束總線
return(TRUE);
}
/*********************************************************************************************************
** Function name: IRcvStr
** Descriptions: 使用硬件I2C讀取數據。
** Input: sla 從機地址
* suba 器件子地址緩沖區指針(第一字節用來表示子地址字節個數)
* s 接收數據緩沖區
* no 接收數據個數
** Output: 操作成功返回TRUE,仲載失敗/無從機應答返回FALSE
** Note: 使用前設置好參數。程序不會更改suba緩沖區的數據
********************************************************************************************************/
int IRcvStr(uint8 sla,uint8 *suba,uint8 *s,uint8 no)
{
int bak;
bak = *suba++; // 子地址個數
if(bak > 0)
{
sla = sla & 0xFE;
if(!StartI2C(sla))
{
if(!StartI2C(sla)) return(FALSE); // 啟動總線,發送從機地址(寫)
}
// 發送器件子地址
for(; bak>0; bak--)
{
if(!I2C_SendByte(*suba++)) return(FALSE);
}
}
// 重啟總線
sla = sla | 0x01;
if(!StartI2C(sla)) return(FALSE); // 啟動總線,發送從機地址(讀)
// 讀取數據
for(; no>1; no--)
{
if(!I2C_RcvByteA(s)) return(FALSE); // 發送數據
s++;
}
if(!I2C_RcvByteNA(s)) return(FALSE);
StopI2C(0); // 結束總線
return(TRUE);
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -