1. 程式人生 > >STM32F207上I2C作為從機的硬體中斷實現的程式碼及註釋

STM32F207上I2C作為從機的硬體中斷實現的程式碼及註釋

人家都說,寫驅動簡單,一般網上都有參考程式,或者官網有demo,可是要是看不懂例程程式碼,怎麼辦?確實也沒什麼好辦法,只能硬著頭皮,自己花時間研究研究嘍。

一般看懂程式碼最起碼知道其中的原理,才能推測出每一行程式碼的作用。今天要寫的是I2C作為從機的硬體實現,原理在我上一篇日誌中基本上講得非常清楚了。今天直接上程式碼。

/*****************首先三個函式為初始化函式****************************/

/*!
 * @brief	配置I2C1的GPIO
 * @param	none
 * @return	NONE
 * @note	PB6-SCL,PB7-SDA
 * @note	注意函式中的 GPIO_PinSource6 與 GPIO_Pin_6 不是同一個巨集定義,
 */
void I2C1_GPIO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);	//!SR1 &= 0x00FF;							            	//!<清除錯誤標誌
	}
}

/*!
 * @brief	I2C1接收和傳送中斷
 * @param	none
 * @return	NONE
 * @note	PB6-SCL,PB7-SDA I2C1_EV_IRQHandler
 * @note	作為從機的I2C中斷處理函式
 * @note	這裡只涉及到五種事件
 */
void I2C1_EV_IRQHandler(void)
{
	switch (I2C_GetLastEvent(I2C1)){//!<獲取I2C事件
		/*從機發送中斷*/
		case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:	    //!
/********************接下來是中斷處理函式**************************/
/*!
 * @brief	I2C1錯誤中斷
 * @param	none
 * @return	NONE
 * @note	PB6-SCL,PB7-SDA
 */
void I2C1_ER_IRQHandler(void)
{
	if ((I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0xFF00) != 0x00){	//!<讀狀態暫存器,獲取I2C錯誤
		I2C1->SR1 &= 0x00FF;						//!<清除錯誤標誌
	}
}

/*!
 * @brief	I2C1接收和傳送中斷
 * @param	none
 * @return	NONE
 * @note	PB6-SCL,PB7-SDA I2C1_EV_IRQHandler
 * @note	作為從機的I2C中斷處理函式
 * @note	這裡只涉及到五種事件
 */
void I2C1_EV_IRQHandler(void)
{
	switch (I2C_GetLastEvent(I2C1)){//!<獲取I2C事件
		/*從機發送中斷*/
		case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:	//!<EV1,地址匹配,並且從地址位元組上檢測到主機讀操作,
			I2C_SendData(I2C1, data[num++]);		//!<向主機發送資料
			I2C_ITConfig(I2C1, I2C_IT_BUF , ENABLE);	//!<做一個使能操作
			break;
		case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:			//!<EV3,傳送完一個位元組
		case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:			//!<並且檢測到主機發送過來的ACK後產生中斷
			I2C_SendData(I2C1, data[num++]);		//!<繼續向主機發送資料
			break;
		/*從機接收中斷*/ 
		case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:	//!<EV1,地址匹配並且從地址位元組上檢測到主機寫操作
			num= 0;						//!<傳送位元組數清零
			break;
		case I2C_EVENT_SLAVE_BYTE_RECEIVED: 			//!<EV2,正常接收資料
		case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF):  
			num = I2C_ReceiveData(I2C1);
			break;
		case I2C_EVENT_SLAVE_STOP_DETECTED:			//!<EV4,檢測到停止位
			I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF);
			I2C_Cmd(I2C1, ENABLE);
			num= 0;
			break;
		default:
			break;
	} 
}