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

📄 i2c state machine.c

📁 基于ADI BLACKFIN 561的I2C接口的驱动程序及应用实例
💻 C
📖 第 1 页 / 共 2 页
字号:
//																			//
// Parameters:	None														//
//																			//
// Return:		Status of I2C Stop condition								//
//					false:	I2C Stop condition not finished					//
//					true:	I2C Stop condition finished						//
//																			//
// Description:	This function is called from within the SPI main state		//
//				machine.													//
//				It executes a state machine that implements the I2C Stop	//
//				condition by setting SDA to 0 while SCL is 1.				//
//--------------------------------------------------------------------------//
bool I2C_Execute_STOP(void)
{
	bool					Return_Value		= false;
	static t_I2C_Sub_States	I2C_STOP_SM_State	= I2C_SET_LOW_SCL_SDA;

	switch(I2C_STOP_SM_State)
	{
		// state SET_LOW_SCL_SDA
		case I2C_SET_LOW_SCL_SDA:

			// state transition SET_LOW_SCL_SDA -> SET_HIGH_SCL
			I2C_STOP_SM_State = I2C_SET_HIGH_SCL;

			I2C_Set_Low_SCL();
			I2C_Set_Low_SDA();

			break;

		// state SET_HIGH_SCL
		case I2C_SET_HIGH_SCL:

			// state transition SET_HIGH_SCL -> SET_HIGH_SDA
			I2C_STOP_SM_State = I2C_SET_HIGH_SDA;

			I2C_Set_High_SCL();

			break;

		// state SET_HIGH_SDA
		case I2C_SET_HIGH_SDA:

			// state transition SET_HIGH_SDA -> SET_LOW_SCL_SDA
			I2C_STOP_SM_State = I2C_SET_LOW_SCL_SDA;

			I2C_Set_High_SDA();

			Return_Value = true;				// SM is finished

			break;
	}

	return(Return_Value);
}

//--------------------------------------------------------------------------//
// Function:	Execute_WRITE												//
//																			//
// Access:		Private														//
//																			//
// Parameters:	None														//
//																			//
// Return:		Status of I2C Write operation								//
//					false:	I2C Byte transfer not finished					//
//					true:	I2C Byte transfer finished						//
//																			//
// Description:	This function is called from within the SPI main state		//
//				machine.													//
//				It executes a state machine that transfers a value, stored	//
//				in member variable m_Current_Transfer.Byte via I2C.			//
//				The number of bits to be transferred is stored in member	//
//				variable m_Current_Transfer.Bit_Count.						//
//--------------------------------------------------------------------------//
bool I2C_Execute_WRITE(void)
{
	bool					Return_Value				= false;
	static t_I2C_Sub_States	I2C_WRITE_SM_State			= I2C_SET_LEVEL_SDA;
	static int				I2C_WRITE_SM_State_Counter	= 0;

	switch(I2C_WRITE_SM_State)
	{
		// state SET_LEVEL_SDA
		case I2C_SET_LEVEL_SDA:

			// state transition SET_LEVEL_SDA -> SET_HIGH_SCL
			I2C_WRITE_SM_State = I2C_SET_HIGH_SCL;

			// extract one bit from byte to be transferred at the time and transfer it
			if((m_Current_Transfer.Byte << I2C_WRITE_SM_State_Counter++) & 0x80)
			{
				I2C_Set_High_SDA();
			}
			else
			{
				I2C_Set_Low_SDA();
			}

			break;

		// state SET_HIGH_SCL
		case I2C_SET_HIGH_SCL:

			// state transition SET_HIGH_SCL -> SET_LOW_SCL
			I2C_WRITE_SM_State = I2C_SET_LOW_SCL;

			I2C_Set_High_SCL();

			break;

		// state SET_LOW_SCL
		case I2C_SET_LOW_SCL:

			// state transition SET_LOW_SCL -> SET_LEVEL_SDA
			I2C_WRITE_SM_State = I2C_SET_LEVEL_SDA;

			I2C_Set_Low_SCL();

			// reset SM counter if all bits transferred
			if(I2C_WRITE_SM_State_Counter == m_Current_Transfer.Bit_Count)
			{
				I2C_WRITE_SM_State_Counter = 0;

				Return_Value = true;			// SM is finished
			}

			break;
	}

	return(Return_Value);
}

//--------------------------------------------------------------------------//
// Function:	Execute_READ												//
//																			//
// Access:		Private														//
//																			//
// Parameters:	None														//
//																			//
// Return:		Status of I2C Read operation								//
//					false:	I2C Byte Read not finished						//
//					true:	I2C Byte Read finished							//
//																			//
// Description:	This function is called	from within the SPI main state		//
//				machine.													//
//				It executes a state machine that reads a value from the		//
//				Slave device and stores it in m_Current_Message.Byte.		//
//				The number of bits to be transferred is stored in member	//
//				variable m_Current_Transfer.Bit_Count.						//
//--------------------------------------------------------------------------//
bool I2C_Execute_READ(void)
{
	bool					Return_Value				= false;
	static t_I2C_Sub_States	I2C_READ_SM_State			= I2C_SET_SDA_INPUT;
	static int				I2C_READ_SM_State_Counter	= 0;

	switch(I2C_READ_SM_State)
	{
		// state SET_SDA_INPUT
		case I2C_SET_SDA_INPUT:

			// state transition SET_SDA_INPUT -> SET_HIGH_SCL
			I2C_READ_SM_State = I2C_SET_HIGH_SCL;

			I2C_Set_SDA_Input();

			break;

		// state SET_HIGH_SCL
		case I2C_SET_HIGH_SCL:

			// state transition SET_HIGH_SCL -> READ_SDA
			I2C_READ_SM_State = I2C_READ_SDA;

			I2C_Set_High_SCL();

			break;

		// state READ_SDA
		case I2C_READ_SDA:

			// state transition READ_SDA -> SET_LOW_SCL
			I2C_READ_SM_State = I2C_SET_LOW_SCL;

			// read next bit and store it in m_Current_Transfer.Byte
			m_Current_Transfer.Byte = (m_Current_Transfer.Byte << 1) | (I2C_Read_SDA() & 0xfe);

			I2C_READ_SM_State_Counter++;

			break;

		// state SET_LOW_SCL
		case I2C_SET_LOW_SCL:

			I2C_Set_Low_SCL();

			// reset SM if all bits have been read, otherwise read next bit
			if(I2C_READ_SM_State_Counter == m_Current_Transfer.Bit_Count)
			{
				// state transition SET_LOW_SCL -> SET_SDA_OUTPUT
				I2C_READ_SM_State = I2C_SET_SDA_OUTPUT;

				I2C_READ_SM_State_Counter = 0;
			}
			else
			{
				// state transition SET_LOW_SCL -> SET_HIGH_SCL
				I2C_READ_SM_State = I2C_SET_HIGH_SCL;
			}

			break;

		// state SET_SDA_OUTPUT
		case I2C_SET_SDA_OUTPUT:

			// state transition SET_SDA_OUTPUT -> SET_SDA_INPUT
			I2C_READ_SM_State = I2C_SET_SDA_INPUT;

			I2C_Set_SDA_Output();

			Return_Value = true;				// SM is finished

			break;
	}

	return(Return_Value);
}

//--------------------------------------------------------------------------//
// Function:	Execute_CHECK_ACK											//
//																			//
// Access:		Private														//
//																			//
// Parameters:	None														//
//																			//
// Return:		Status of I2C Acknowledge operation							//
//					false:	I2C Acknowledge cycle not finished				//
//					true:	I2C Acknowledge cycle finished					//
//																			//
// Description:	This function is called from within the SPI main state		//
//				machine.													//
//				It executes a state machine that reads the value on SDA		//
//				returned during the acknowledge cycle and stores it in		//
//				member variable ACK_State.									//
//--------------------------------------------------------------------------//
bool I2C_Execute_CHECK_ACK(void)
{
	bool					Return_Value			= false;
	static t_I2C_Sub_States	I2C_TEST_ACK_SM_State	= I2C_SET_SDA_INPUT;

	switch(I2C_TEST_ACK_SM_State)
	{
		// state SET_SDA_INPUT
		case I2C_SET_SDA_INPUT:

			// state transition SET_SDA_INPUT -> SET_HIGH_SCL
			I2C_TEST_ACK_SM_State = I2C_SET_HIGH_SCL;

			I2C_Set_SDA_Input();

			break;

		// state SET_HIGH_SCL
		case I2C_SET_HIGH_SCL:

			// state transition SET_HIGH_SCL -> READ_SDA
			I2C_TEST_ACK_SM_State = I2C_READ_SDA;

			I2C_Set_High_SCL();

			break;

		// state READ_SDA
		case I2C_READ_SDA:

			// state transition READ_SDA -> SET_LOW_SCL
			I2C_TEST_ACK_SM_State = I2C_SET_LOW_SCL;

			// read SDA and assign value to variable that holds error state
			m_ACK_Error = I2C_Read_SDA();

			break;

		// state SET_LOW_SCL
		case I2C_SET_LOW_SCL:

			// state transition SET_LOW_SCL -> SET_SDA_OUTPUT
			I2C_TEST_ACK_SM_State = I2C_SET_SDA_OUTPUT;

			I2C_Set_Low_SCL();

			break;

		// state SET_SDA_OUTPUT
		case I2C_SET_SDA_OUTPUT:

			// state transition SET_SDA_OUTPUT -> SET_SDA_INPUT
			I2C_TEST_ACK_SM_State = I2C_SET_SDA_INPUT;

			I2C_Set_SDA_Output();

			Return_Value = true;				// SM is finished

			break;
	}

	return(Return_Value);
}

⌨️ 快捷键说明

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