STM32F207上I2C作為從機的硬體中斷實現的程式碼及註釋
阿新 • • 發佈:2019-02-17
人家都說,寫驅動簡單,一般網上都有參考程式,或者官網有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; } }