
作者:盧老師,華清遠見教育科技集團講師。
在大多情況下,我們(men)使(shi)(shi)用(yong)MCU控制傳(chuan)感器,節(jie)點以(yi)及相關(guan)從設(she)備(bei),但(dan)在較為復雜(za)的系統中,有時候也(ye)會使(shi)(shi)用(yong)MCU做為從設(she)備(bei)。
下面是關于stm32f051的從模式實現方法,主要思路為從設備(bei)從中斷里面接受(shou) IIC主設備(bei)發送的數據(ju),并加以處理。
下圖為STM32F051的小系(xi)統:

IIC從模式 GPIO的配置
根(gen)據原理(li)圖查ST32F051的datasheet

配置引腳:
void I2C_GPIO_Configuration(void)
              {
                      GPIO_InitTypeDefGPIO_InitStruct; 
              
                      /* Enable  GPIOA clock */
                      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);	
                      /*!< sEE_I2C Periph clock enable */
                      RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
                      /*!< GPIO configuration */  
                      /*!< Configure sEE_I2C pins: SCL */
                      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
                      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//GPIO_Mode_IN
                      GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
                      GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//open-drain
                      GPIO_Init(GPIOB , &GPIO_InitStruct);
              
                      /*!< Configure sEE_I2C pins: SDA */
                      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
                      GPIO_Init(GPIOB , &GPIO_InitStruct);
              
                      /* Connect PXx to I2C_SCL*/
                      GPIO_PinAFConfig( GPIOB , GPIO_PinSource8, GPIO_AF_1); 
                      /* Connect PXx to I2C_SDA*/
                      GPIO_PinAFConfig( GPIOB ,GPIO_PinSource9, GPIO_AF_1);
              }
      
IIC從模式(shi)配置,在配置時,需要設置地址,在這里設置為0XA0,而從設備的時鐘(zhong)屬于被動模式(shi),有IIC的主端確定。
void I2C_Configuration(void)
              {
                      I2C_InitTypeDef  I2C_InitStruct; 
              
                      /* I2C configuration */
                      I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
                      I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
                      I2C_InitStruct.I2C_DigitalFilter = 0x00;
                      I2C_InitStruct.I2C_OwnAddress1 =0xA0;
                      I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
                      I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	
                      I2C_InitStruct.I2C_Timing = 0xb0420f13;//100Kbits
                      /* I2C Peripheral Enable */
                      I2C_Cmd(I2C1, ENABLE);
                      /* Apply I2C configuration after enabling it */
                      I2C_Init(I2C1, &I2C_InitStruct);
              }
      
下面是IIC中斷(duan)函數的實現(xian)
void I2C1_IRQHandler(void)
              {
                      I2C_ClearITPendingBit(I2C1, I2C_ISR_ADDR|I2C_ISR_STOPF );
                      if(I2C_GetITStatus( I2C1, I2C_IT_RXNE));
                      {
                              I2Cbuf[I2C_IT_FLAG++]=I2C_ReceiveData(I2C1);
                      }
              }
      
中(zhong)斷函數(shu)(shu)里(li)面(mian),清中(zhong)斷為2種(zhong),一(yi)種(zhong)為IIC從(cong)地址校(xiao)驗成功,一(yi)種(zhong)是(shi)數(shu)(shu)據(ju)傳輸過程中(zhong)停止。對于從(cong)設備,接(jie)受數(shu)(shu)據(ju)中(zhong)斷才(cai)是(shi)我們需要的(de)(de)(de)(de),這里(li)我們將(jiang)IIC接(jie)受的(de)(de)(de)(de)數(shu)(shu)據(ju)存入定(ding)義好(hao)的(de)(de)(de)(de)數(shu)(shu)組(zu)中(zhong),這樣以備后用,同是(shi),在讀取接(jie)受數(shu)(shu)據(ju)時,硬件已經將(jiang)接(jie)受數(shu)(shu)據(ju)的(de)(de)(de)(de)中(zhong)斷清楚掉(diao)。