?? i2c.c
字號:
/***************************************************
模塊說明 :I2C控制接口模塊
芯片類型 :Nios II
作 者 :柳軍勝
公 司 :杭州自由電子科技
:http://www.freefpga.com
電 話 :0571-85084089
修 改 :
日期時間 :20060522
說 明 :本程序模塊僅提供I2C接口設備底層讀寫流程,不涉及
具體應用芯片控制邏輯。
****************************************************/
#include <stdio.h>
#include <io.h>
#include <system.h>
#include <i2c_master.h>
static void *gBaseAddr=NULL;
/*********************************************
函數名:init_i2c
功 能:初始化I2C控制器、應用環境參數初始化設置
輸 入:外設地址
返 回:
備 注:
應用I2C函數前必須先調用此函數設置I2C外設基地址
預分頻允許100K~400K
**********************************************/
int init_i2c(void *baseAddr)
{
unsigned char uc,rdata;
if(gBaseAddr==NULL)
gBaseAddr=baseAddr;
//setup prer
IOWR(gBaseAddr , OC_I2C_PRER_LO ,0x63 );
IOWR(gBaseAddr, OC_I2C_PRER_HI, 0x00);
//setup ctr
IOWR(gBaseAddr , OC_I2C_CTR ,0x80 );
//read_status
//uc=IORD(gBaseAddr,OC_I2C_SR);
//send stop
IOWR(gBaseAddr,OC_I2C_TXR,0x55);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
return 0;
}
/*********************************************
函數名:wait_nTip_ACK
功 能:等待傳輸結束和應答
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷狀態寄存器標志位完成功能
**********************************************/
//wait transmit over and wait ACK
int wait_nTip_ACK()
{
unsigned char uc;
int i;
if(gBaseAddr==NULL)
return -1;
i=0;
while(1){
//read_status TIP
uc=IORD(gBaseAddr,OC_I2C_SR);
if(OC_ISCLEAR(uc,OC_I2C_TIP))break;
i++;
if(i>10000)return -2;
}
i=0;
while(1){
//read_status ACK
uc=IORD(gBaseAddr,OC_I2C_SR);
if(OC_ISCLEAR(uc,OC_I2C_RXACK))break;
i++;
if(i>10000)
{
//I2C器件沒有應答時加入STOP發送 20060523
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STO);
return -3;
}
}
return 0;
}
/*********************************************
函數名:wait_nTip
功 能:等待傳輸結束
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷狀態寄存器標志位完成功能
**********************************************/
//wait transmit over
int wait_nTip()
{
unsigned char uc;
int i;
if(gBaseAddr==NULL)
return -1;
i=0;
while(1){
//read_status TIP
uc=IORD(gBaseAddr,OC_I2C_SR);
if(OC_ISCLEAR(uc,OC_I2C_TIP))break;
i++;
if(i>10000)return -1;
}
return 0;
}
/*********************************************
函數名:wait_idle
功 能:等待空閑
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷狀態寄存器標志位完成功能
**********************************************/
//wait i2c idle
int wait_idle()
{
unsigned char uc;
int i;
if(gBaseAddr==NULL)
return -1;
i=0;
while(1){
//read_status TIP
uc=IORD(gBaseAddr,OC_I2C_SR);
if(OC_ISCLEAR(uc,OC_I2C_BUSY))break;
i++;
if(i>10000)return -1;
}
return 0;
}
/*********************************************
函數名:start_write_waitack()
功 能:I2C啟動、寫數據、等待ACK
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int start_write_waitack(unsigned char data)
{
int iRet;
if(wait_idle()<0){
printf("i2c control is busy\n");
return -1;
}
IOWR(gBaseAddr,OC_I2C_TXR,data);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
iRet=wait_nTip_ACK();
if(iRet<0){
printf("1wait _nTip_ACK timeover\n");
return -2;
}
return 0;
}
/*********************************************
函數名:start_read_waitack()
功 能:I2C啟動、寫數據、等待ACK
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int start_read_waitack(unsigned char data)
{
int iRet;
/* restart時狀態不是 IDLE 所以不需要等待idle */
/*
if(wait_idle()<0){
printf("i2c control is busy\n");
return -1;
}
*/
/* 這里寫的數據里面 R/W位為1,但是控制標志置OC_I2C_WR控制輸出從機地址 */
IOWR(gBaseAddr,OC_I2C_TXR,data);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
iRet=wait_nTip_ACK();
if(iRet<0){
printf("1wait _nTip_ACK timeover\n");
return -2;
}
return 0;
}
/*********************************************
函數名:write_waitack()
功 能:寫數據、等待ACK
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int write_waitack(unsigned char data)
{
int iRet;
IOWR(gBaseAddr,OC_I2C_TXR,data);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
iRet=wait_nTip_ACK();
if(iRet<0){
printf("1wait _nTip_ACK timeover\n");
return -2;
}
return 0;
}
/*********************************************
函數名:write_waitack_stop()
功 能:寫數據、等待ACK、發送STOP
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int write_waitack_stop(unsigned char data)
{
int iRet;
IOWR(gBaseAddr,OC_I2C_TXR,data);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
iRet=wait_nTip_ACK();
if(iRet<0){
printf("1wait _nTip_ACK timeover\n");
return -2;
}
return 0;
}
/*********************************************
函數名:read_sendack()
功 能:讀數據、發送ACK
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int read_sendack(unsigned char *data)
{
int iRet;
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_ACK);
iRet=wait_nTip();
if(iRet<0)
return -1;
*data=IORD(gBaseAddr,OC_I2C_RXR);
return 0;
}
/*********************************************
函數名:read_sendack_stop()
功 能:讀數據、發送ACK、STOP
輸 入:外設地址
返 回: 0 成功 <0失敗
備 注:
判斷I2C狀態寄存器標志位完成功能
**********************************************/
int read_sendack_stop(unsigned char *data)
{
int iRet;
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_ACK|OC_I2C_STO);
iRet=wait_nTip();
if(iRet<0)
return -1;
*data=IORD(gBaseAddr,OC_I2C_RXR);
return 0;
}
/*********************************************
函數名:read_I2c_EEprom
功 能:讀EEPROM
輸 入:外設地址,設備地址,字節地址
返 回: 讀取的數據
備 注:
**********************************************/
unsigned char read_I2C_EEprom(unsigned char slaveAddr,unsigned char addr)
{
unsigned char rdata;
//write chip addr and write bit
IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
wait_nTip_ACK();
//write eeprom addr
IOWR(gBaseAddr,OC_I2C_TXR,addr);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
wait_nTip_ACK();
//write chip addr and read bit
IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr|0x01);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
wait_nTip_ACK();
//read eeprom data
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_STO|OC_I2C_ACK);
wait_nTip();
rdata=IORD(gBaseAddr,OC_I2C_RXR);
return rdata;
}
/*********************************************
函數名:write_I2c_EEprom
功 能:寫EEPROM
輸 入:外設地址,設備地址,字節地址
返 回:
備 注:
**********************************************/
unsigned char write_I2C_EEprom(unsigned char slaveAddr,unsigned char addr,unsigned char data)
{
unsigned char rdata;
unsigned char rc;
if(wait_idle()<0){
printf("i2c control is busy\n");
return 0;
}
//write chip addr and write bit
IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
printf("w1\n");
rc=wait_nTip_ACK();
//write eeprom addr
IOWR(gBaseAddr,OC_I2C_TXR,addr);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
printf("w2\n");
rc=wait_nTip_ACK();
//write data
IOWR(gBaseAddr,OC_I2C_TXR,data);
IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
printf("w3\n");
rc=wait_nTip_ACK();
return data;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -