⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic_avr.c

📁 串口转发IIC程序
💻 C
字号:
///////////////////////////////////////////
//		IIC_AVR.C
//	Function:	IIC driver for atmel mega16
//	Create : Guobg
//	Date :	20060113
//	Revision:	0.0
///////////////////////////////////////////
//	Modify History
//
///////////////////////////////////////////
#include "IIC_AVR.H"
struct IIC_BUFFER	IIC_Buffer_In;						// IIC Input Buffer
struct IIC_BUFFER	IIC_Buffer_Out;						// IIC Output Buffer

//U8 ucIICSLA;					// IIC Master Mode Destination Address,R/W
U8					ucIICTimeoutCount;					// IIC Time out counter
U8					ucIICMode;							// IIC Mode
U8					ucIICError;							// IIC Error code
U8					ucIICAddress;						// Myself IIC Address
BP_CODE U8			IIC_BaudrateConfig[2][2] =
{
	{ IIC_BAUDRATE_TWBR_200K, IIC_BAUDRATE_TWPS_NODIV }
	,													// Config for 200K
	{ IIC_BAUDRATE_TWBR_100K, IIC_BAUDRATE_TWPS_NODIV } // Config for 100K
};

///////////////////////////////////////////
//		IIC_Init
//	Function:	Initlize IIC interface
//	Input:	
//		ucSlaveAddr: SlaveAddr (1--127)
//		ucBaudrate:	 Baudrate index see IIC.H
//	Output:

//		NONE
///////////////////////////////////////////
void IIC_Init(U8 ucSlaveAddr, U8 ucBaudrate)
{
	unsigned char	i;

	//Initlize baudrate
	TWBR = IIC_BaudrateConfig[ucBaudrate][0];
	TWSR = IIC_BaudrateConfig[ucBaudrate][1];

	//Set IIC Slave address, enable broadcast respond
	TWAR = (ucSlaveAddr << 1 | _BV(TWGCE));
	ucIICMode = IIC_MODE_SLAVE_RECEIVE;							//Default mode
	ucIICError = IIC_ERROR_NOERROR;

	//Clear IIC buffer
	for(i = 0; i < IIC_MAX_BUFFER_LEN; i++)
	{
		IIC_Buffer_In.IIC_BUFFER_UNION.ucData[i] = 0;
		IIC_Buffer_Out.IIC_BUFFER_UNION.ucData[i] = 0;
	}

	//Clear buffer status
	IIC_Buffer_In.ucReadP = 0;
	IIC_Buffer_In.ucWriteP = 0;
	IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 0;				//In Buffer Disable Access
	IIC_Buffer_Out.ucReadP = 0;
	IIC_Buffer_Out.ucWriteP = 0;
	IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;				//Out Buffer Enable Access	

	// Clear TWINT , enabel TWI ack ,enable TWI port ,enable TWI Interrupt
	TWCR = (_BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE));
}

///////////////////////////////////////////
//		IIC_handle
//	Function:	IIC Interrupt handler
//	Input:	
//		NONE
//	Output:
//		NONE
///////////////////////////////////////////
#ifdef ICC_AVR
void IIC_handler (void)
#endif
#ifdef GCC_AVR
SIGNAL(SIG_2WIRE_SERIAL)
#endif
{
	U8	ucTwiStatus;
	ucTwiStatus = (TWSR & TW_NO_INFO);
	switch(ucTwiStatus)
	{
	case TW_START:												// A START has transmit to IIC bus
	case TW_REP_START:											//A REPEAT START has transmit to IIC bus
		ucIICMode = IIC_MODE_MASTER_TRANSMIT;
		IIC_SLA;												//Send SLA+R/W to IIC bus

		//		cbi(TWCR,TWSTA);	//Clear TWSTA
		TWCR = (_BV(TWEN) | _BV(TWEA) | _BV(TWIE) | _BV(TWINT));
		break;

	case TW_MT_SLA_ACK:
	case TW_MT_DATA_ACK:										//Send data to Slave IIC device
		if(IIC_Buffer_Out.ucWriteP != IIC_Buffer_Out.ucReadP)
		{														// Data transmit not finish
			IIC_BUFFER_TO_BUS;
			TWCR = (_BV(TWEN) | _BV(TWEA) | _BV(TWIE) | _BV(TWINT));
			break;
		} else
		{
			IIC_STOP;											//Data transmit finish,Release IIC bus

			//Enable user program write a new command to IIC transmit buffer
			IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
			IIC_Buffer_Out.ucReadP = 0;
			IIC_Buffer_Out.ucWriteP = 0;
			ucIICMode = IIC_MODE_SLAVE_RECEIVE;
			break;
		}

	case TW_MT_SLA_NACK:										//Slave IIC device did not return a NACK during
		//address phase
		IIC_STOP;												//Slave address error,Release IIC bus

		//Enable user program write a new command to IIC transmit buffer
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		ucIICError = IIC_ERROR_NOT_ACK_SLA;
		IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
		IIC_Buffer_Out.ucReadP = 0;
		IIC_Buffer_Out.ucWriteP = 0;
		break;

	case TW_MT_DATA_NACK:										//Slave IIC device did not return a NACK during
		//data transfer phase
		IIC_STOP;												//Data transmit error,Release IIC bus

		//Enable user program write a new command to IIC transmit buffer
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		ucIICError = IIC_ERROR_NOT_ACK_DATA;
		IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
		IIC_Buffer_Out.ucReadP = 0;
		IIC_Buffer_Out.ucWriteP = 0;
		break;

	case TW_MT_ARB_LOST:

		//Enable user program write a new command to IIC transmit buffer
		if(ucIICMode == IIC_MODE_MASTER_TRANSMIT)
		{
			IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
			IIC_Buffer_Out.ucReadP = 0;
			IIC_Buffer_Out.ucWriteP = 0;
		} else
		{
			IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 0;
			IIC_Buffer_In.ucReadP = 0;
			IIC_Buffer_In.ucWriteP = 0;
		}
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		ucIICError = IIC_ERROR_ARBITRATION_LOST;
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
		break;

	///////////////////////////////////////////
	//		Slave Recieve Mode
				///////////////////////////////////////////
	case TW_SR_SLA_ACK:
	case TW_SR_GCALL_ACK:
	case TW_SR_ARB_LOST_SLA_ACK:
	case TW_SR_ARB_LOST_GCALL_ACK:
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		IIC_Buffer_In.ucWriteP = 0;
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWIE) | _BV(TWEA));
		break;

	case TW_SR_DATA_ACK:
	case TW_SR_GCALL_DATA_ACK:
		if(IIC_Buffer_In.ucWriteP < IIC_MAX_BUFFER_LEN)
		{
			IIC_BUS_TO_BUFFER;
			TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWIE) | _BV(TWEA));
		} else
		{														//Buffer Overlow
			//			cbi(TWCR,TWEA);	//Clear TWEA Disable data ACK and address ACK
			TWCR = _BV(TWINT);
			ucIICError = IIC_ERROR_BUFFER_OVERLOW;
		}
		break;

	case TW_SR_DATA_NACK:
	case TW_SR_GCALL_DATA_NACK:
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
		break;

	case TW_SR_STOP:
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));

		//		sbi(TWCR,TWEA);		//Set TWEA Enable data ACK and address ACK
		if(ucIICError == IIC_ERROR_NOERROR)
		{
			IIC_Buffer_In.ucReadP = 0;
			IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 1;
		}
		break;

	///////////////////////////////////////////
	//		Master Recieve Mode
				///////////////////////////////////////////
	case TW_MR_SLA_ACK:
		ucIICMode = IIC_MODE_MASTER_RECEIVE;
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));

	case TW_MR_DATA_ACK:										//Recieve data from slave IIC device
		if(IIC_Buffer_In.ucWriteP != IIC_Buffer_In.ucReadP - 1) //ucReadP must initlize

		//with Bytes to read before
		//Call IICMasrRecieve
		{					// Not last byte to recieve
			IIC_BUS_TO_BUFFER;
			TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
			break;
		} else
		{					//Last byte has come to IIC Bus
			IIC_BUS_TO_BUFFER;
			TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWIE));

			//			cbi(TWCR,TWEA);		//Clear TWEA send NACK to finish recieve
			break;
		}

	case TW_MR_SLA_NACK:	//Slave IIC device did not return a NACK during
		//address phase
		IIC_STOP;			//Slave address error,Release IIC bus
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		ucIICError = IIC_ERROR_NOT_ACK_SLA;
		IIC_Buffer_In.ucReadP = 0;
		IIC_Buffer_In.ucWriteP = 0;
		break;

	case TW_MR_DATA_NACK:
		IIC_STOP;

		//		sbi(TWCR,TWEA);		//Set TWEA to enable ACK
		if(IIC_Buffer_In.ucReadP == IIC_Buffer_In.ucWriteP)
		{					//Data receive success
			//Enable user program get command from IIC recieve buffer
			IIC_Buffer_In.ucIICBufferStatus.bEnAccess = 1;
			ucIICError = IIC_ERROR_NOERROR;
		} else
		{
			ucIICError = IIC_ERROR_NOT_ACK_DATA;
		}
		IIC_Buffer_In.ucWriteP = 0;
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		break;

	//Same as TW_MT_ARB_LOST
	//	case TW_MR_ARB_LOST:
	//		ucIICMode=IIC_MODE_SLAVE_RECEIVE;
	//		ucIICError=IIC_ERROR_ARBITRATION_LOST;
	//		IIC_Buffer_In.ucReadP=0;
	//		IIC_Buffer_In.ucWriteP=0;
	//		break;
				
				
				///////////////////////////////////////////
	//		Slave Transmit Mode
				///////////////////////////////////////////
	case TW_ST_SLA_ACK:
		ucIICMode = IIC_MODE_SLAVE_TRANSMIT;
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));

	case TW_ST_DATA_ACK:
		if(IIC_Buffer_Out.ucReadP != IIC_Buffer_Out.ucWriteP)
		{					// Data transmit not finish
			IIC_BUFFER_TO_BUS;
			TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
			break;
		}

	// Buffer Empty!!
	case TW_ST_ARB_LOST_SLA_ACK:
	case TW_ST_DATA_NACK:
	case TW_ST_LAST_DATA:

		//Transfer complet
		IIC_Buffer_Out.ucIICBufferStatus.bEnAccess = 1;
		IIC_Buffer_Out.ucReadP = 0;
		IIC_Buffer_Out.ucWriteP = 0;
		ucIICMode = IIC_MODE_SLAVE_RECEIVE;
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
		break;

	case TW_BUS_ERROR:
	case TW_NO_INFO:
	default:
		TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE));
		break;
	}

	//	TWCR |= _BV(TWINT);		//Write 1 to Clear TWINT
}

///////////////////////////////////////////
//U8 I2C_Send(U8  I2C_Addr,  U8*  I2C_MsgData , U8  MsgDataLen, U8 s_Timeout )
//其中U8 为 unsigned char。
//参数说明:
//I2C_Addr:发送的目标地址,每个板卡都应该有唯一的I2C通讯地址。
//I2C_MsgData:存放消息数据的缓冲区。
//Msg_DataLen:发送消息的数据长度。
//S_Timeout:发送消息超时的时间,单位为毫秒(ms)。

//返回值:是否发送成功,0:成功;~0:错误代码
///////////////////////////////////////////
U8 I2C_Send(U8 I2C_Addr, U8 *I2C_MsgData, U8 MsgDataLen, U8 s_Timeout)
{
	return 0;
}

///////////////////////////////////////////
//U8 I2C_Rcvd(U8 *  I2C_MsgData ,U8 * MsgDataLen ,U8 r_Timeout)
//I2C_MsgData:接收消息数据的缓冲区。
//Msg_DataLen:接收消息的数据长度。
//r_Timeout:接收消息超时的时间,单位为毫秒(ms)。

//返回值:是否接收成功,0:成功;~0:错误代码
///////////////////////////////////////////
I8 I2C_Rcvd(U8 *I2C_MsgData, U8 *MsgDataLen, U8 r_Timeout)
{
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -