?? i2c_24c04.c
字號:
/*****************************************************************************
* i2c.c: I2C C file for Philips LPC214x Family Microprocessors
*
* Copyright(C) 2006, Philips Semiconductor
* All rights reserved.
*
* History
* 2005.10.01 ver 1.00 Prelimnary version, first Release
*
*****************************************************************************/
#include "LPC213x.h" /* LPC21xx definitions */
#include "type.h"
#include "irq.h"
//#include "i2c.h"
#define BUFSIZE 0x20
#define MAX_TIMEOUT 0x00FFFFFF
#define I2CMASTER 0x01
#define I2CSLAVE 0x02
/* For more info, read Philips's SE95 datasheet */
#define SE95_ADDR 0x9E
#define SE95_ID 0x05
#define SE95_CONFIG 0x01
#define SE95_TEMP 0x00
#define RD_BIT 0x01
#define GET_DEVICE_ID 0x01
#define GET_TEMPERATURE 0x02
#define SET_CONFIGURATION 0x03
#define I2C_IDLE 0
#define I2C_STARTED 1
#define I2C_RESTARTED 2
#define I2C_REPEATED_START 3
#define DATA_ACK 4
#define DATA_NACK 5
#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */
#define I2CONSET_AA 0x00000004
#define I2CONSET_SI 0x00000008
#define I2CONSET_STO 0x00000010
#define I2CONSET_STA 0x00000020
#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
#define I2CONCLR_SIC 0x00000008
#define I2CONCLR_STAC 0x00000020
#define I2CONCLR_I2ENC 0x00000040
#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
#define I2SCLH_SCLH 0x000000c8 /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL 0x000000c8 /* I2C SCL Duty Cycle Low Reg */
/*
DWORD I2CMasterState = I2C_IDLE;
DWORD I2CSlaveState = I2C_IDLE;
DWORD I2CCmd;
DWORD I2CMode;
BYTE I2CMasterBuffer[BUFSIZE];
BYTE I2CSlaveBuffer[BUFSIZE];
DWORD I2CCount = 0;
DWORD I2CReadLength;
DWORD I2CWriteLength;
DWORD RdIndex = 0;
DWORD WrIndex = 0;
*/
BYTE IIC_Chip_Addr; //第一個送至24C04的數據
//為24C04的地址以及讀寫操作的最高位地址,及讀寫控制信號
BYTE IIC_Addr; //第二個送至24C04的數據
//為讀寫操作的地址數據
BYTE IIC_Byte_Number; //數據個數
BYTE IIC_Data; //數據緩沖器
BOOL IIC_Busy = FALSE; //IIC忙標志位
/*
From device to device, the I2C communication protocol may vary,
in the example below, the protocol uses repeated start to read data from or
write to the device:
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO
for master write: the sequence is: STA,Addr(W),length,RE-STA,Addr(r),data...STO
Thus, in state 8, the address is always WRITE. in state 10, the address could
be READ or WRITE depending on the I2CCmd.
*/
/*****************************************************************************
** Function name: I2C0MasterHandler
**
** Descriptions: I2C0 interrupt handler, deal with master mode
** only.
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void I2C0MasterHandler (void) __irq
{
BYTE StatValue;
/* this handler deals with master read and master write only */
StatValue = I2C0STAT; //讀取IIC狀態,以便后面針對不同狀態進行分支處理
// IENABLE;
//
switch ( StatValue )
{
case 0x08: //IIC 啟動條件已發送完畢,緊接要發送從器件地址
I2C0DAT = IIC_Chip_Addr&(~0x01);//I2CMasterBuffer[0]; //發送從器件地址以及讀寫標志位
I2C0CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); //清標志
break;
case 0x10: //讀操作重發,當讀操作時,在啟動條件后發送完從器件地址
I2C0DAT = IIC_Chip_Addr;
I2C0CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
break;
case 0x18: //從器件地址發送完后,接收到ACK,接著要發送操作地址
I2C0DAT = IIC_Addr;
I2C0CONCLR = I2CONCLR_SIC;
break;
case 0x20:
I2C0CONSET = I2CONSET_STO;//
I2C0CONSET = I2CONSET_STA;
I2C0CONCLR = I2CONCLR_SIC;
break;
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
case 0x30:
if(IIC_Byte_Number)
{
if(IIC_Chip_Addr&0x01)
{
I2C0CONSET = I2CONSET_STA; //讀重發
}
else
{
I2C0DAT = IIC_Data; //發送有效數據
IIC_Byte_Number--;
}
}
else
{
if(IIC_Chip_Addr&0x01)
{
I2C0CONSET = I2CONSET_STA; //讀重發
}
else
{
I2C0CONSET = I2CONSET_STO;//
IIC_Busy = FALSE;
}
}
I2C0CONCLR = I2CONCLR_SIC;
break;
case 0x40: //主接收器,讀重發已發完,收到ACK,這里將設置在接收到數據后發NACK
I2C0CONCLR = I2CONCLR_AAC;
I2C0CONCLR = I2CONCLR_SIC;
break;
case 0x50: /* Data byte has been received, regardless following ACK or NACK */
case 0x58:
IIC_Data = I2C0DAT;
IIC_Busy = FALSE;
//這里也一樣,應將IIC停掉
// I2C0CONSET = I2CONSET_AA; /* assert ACK after data is received */
I2C0CONSET = I2CONSET_STO;
I2C0CONCLR = I2CONCLR_SIC;
while( I2C0CONSET & I2CONSET_STO );
break;
case 0x48:
I2C0CONSET = I2CONSET_STO;//
I2C0CONSET = I2CONSET_STA;
I2C0CONCLR = I2CONCLR_SIC;
break;
case 0x38:
default:
I2C0CONSET = I2CONSET_STO;//
I2C0CONCLR = I2CONCLR_SIC;
break;
}
// IDISABLE;
VICVectAddr = 0; /* Acknowledge Interrupt */
}
/*****************************************************************************
** Function name: I2CStart
**
** Descriptions: Create I2C start condition, a timeout
** value is set if the I2C never gets started,
** and timed out. It's a fatal error.
**
** parameters: None
** Returned value: true or false, return false if timed out
**
*****************************************************************************/
/*
DWORD I2CStart( void )
{
DWORD timeout = 0;
DWORD returnValue = FALSE;
//--- Issue a start condition ---
I2C0CONSET = I2CONSET_STA; // Set Start flag //
//--- Wait until START transmitted ---
while( 1 )
{
if ( I2CMasterState == I2C_STARTED )
{
returnValue = TRUE;
break;
}
if ( timeout >= MAX_TIMEOUT )
{
returnValue = FALSE;
break;
}
timeout++;
}
return ( returnValue );
}
*/
/*****************************************************************************
** Function name: I2CStop
**
** Descriptions: Set the I2C stop condition, if the routine
** never exit, it's a fatal bus error.
**
** parameters: None
** Returned value: true or never return
**
*****************************************************************************/
/*
DWORD I2CStop( void )
{
I2C0CONSET = I2CONSET_STO; // Set Stop flag
I2C0CONCLR = I2CONCLR_SIC; // Clear SI flag
//--- Wait for STOP detected ---
while( I2C0CONSET & I2CONSET_STO );
return TRUE;
}*/
/*****************************************************************************
** Function name: I2CInit
**
** Descriptions: Initialize I2C controller
**
** parameters: I2c mode is either MASTER or SLAVE
** Returned value: true or false, return false if the I2C
** interrupt handler was not installed correctly
**
*****************************************************************************/
DWORD I2CInit( void)
{
PINSEL0 = 0x50; /* set PIO0.2 and PIO0.3 to I2C0 SDA and SCK */
IODIR0 = 0x0C; /* set port 0.2 and port 0.3 to output, high */
IOSET0 = 0x0C;
I2C0CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
I2C0SCLL = I2SCLL_SCLL;
I2C0SCLH = I2SCLH_SCLH;
if ( install_irq( I2C0_INT, (void *)I2C0MasterHandler ) == FALSE )
{
return( FALSE );
}
I2C0CONSET = I2CONSET_I2EN;
return( TRUE );
}
//=====================================================================//
//函數:char SM_Receive (unsigned int byte_address)
//描述:讀單字節數據從指定的AT24C04的地址空間
//參數:byte_address 地址,9位有效
//返回:Dat 數據
//注意:無
//=====================================================================//
unsigned char SM_Receive (unsigned int byte_address)
{
unsigned char ucTemp;
ucTemp = (unsigned char)(byte_address>>7);
ucTemp = ucTemp&0x02;
while (IIC_Busy); // 等待總線空閑
// I2CMasterState = I2C_IDLE;
IIC_Busy = TRUE; //占用SMBus(設置為忙)
// SMB0CN = 0x44; // 允許SMBus,應答周期發ACK
IIC_Byte_Number = 1; // 1 地址字節
IIC_Chip_Addr = (0xA0|0x01|ucTemp); // 片選+ READ + 一個高位的地址
IIC_Addr = (unsigned char)(byte_address&0x00FF); // 8 位地址
I2C0CONSET = I2CONSET_STA;//I2CStart(); // 啟動傳輸過程
while (IIC_Busy==TRUE); // 等待傳輸結束
while( I2C0CONSET & I2CONSET_STO );
return IIC_Data;
}
//=====================================================================//
//函數:void SM_Send (unsigned int byte_address, unsigned char out_byte)
//描述:寫單字節數據至指定的AT24C04的地址空間
//參數:byte_address 地址,9位有效
// out_byte 數據
//返回:無
//注意:無
//=====================================================================//
// SMBus 字節寫函數-----------------------------------------------------
void SM_Send (unsigned int byte_address, unsigned char out_byte)
{
unsigned char ucTemp;
ucTemp = (unsigned char)(byte_address>>7);
ucTemp = ucTemp&0x02;
while (IIC_Busy==TRUE); // 等待SMBus 空閑
IIC_Busy = 1; // 占用SMBus(設置為忙)
IIC_Byte_Number = 1; // 1 地址字節
IIC_Chip_Addr = (0xA0|ucTemp); // 片選+ READ + 一個高位的地址
IIC_Addr = (unsigned char)(byte_address&0x00FF); // 8 位地址
IIC_Data = out_byte; // 待寫數據
I2C0CONSET = I2CONSET_STA;//I2CStart(); // 啟動傳輸過程
while (IIC_Busy==TRUE); // 等待傳輸結束
while( I2C0CONSET & I2CONSET_STO );
}
/*****************************************************************************
** Function name: I2CEngine
**
** Descriptions: The routine to complete a I2C transaction
** from start to stop. All the intermitten
** steps are handled in the interrupt handler.
** Before this routine is called, the read
** length, write length, I2C master buffer,
** and I2C command fields need to be filled.
** see i2cmst.c for more details.
**
** parameters: None
** Returned value: true or false, return false only if the
** start condition can never be generated and
** timed out.
**
*****************************************************************************/
/*
DWORD I2CEngine( void )
{
I2CMasterState = I2C_IDLE;
RdIndex = 0;
WrIndex = 0;
if ( I2CStart() != TRUE )
{
I2CStop();
return ( FALSE );
}
while ( 1 )
{
if ( I2CMasterState == DATA_NACK )
{
I2CStop();
break;
}
}
return ( TRUE );
} */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -