STM32F0 Slave I2C配置

F0的I2C与F103不同,Slave I2C接口协议采用寄存器访问的格式。

(1)I2C初始化

void IIC_Slavemode_Init(u8 debug, u8 addr)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;


    if(debug == 1)   return;
    //---------------------------- GPIO pins configuration ------------------
    /* I2C Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    /* Configure the I2C clock source. The clock is derived from the HSI */
    //RCC_I2CCLKConfig(RCC_I2C1CLK_HSI); //RCC_I2C1CLK_SYSCLK
    // Enable I2C1 SCL and SDA Pin Clock
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

 //PA10:SDA  PA9:SCL
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
    // Set GPIO frequency to 50MHz
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // Select Alternate function mode
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    //Select output Open Drain type
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    // Disable internal Pull-up
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;

    GPIO_Init((GPIO_TypeDef*)GPIOA, &GPIO_InitStructure);




    // Connect PXx to I2C_SCL I2C_SDA    PA10:SDA  PA9:SCL  meilh 201024 GPIO_AF_1->GPIO_AF_4
    GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource9,GPIO_AF_4);
    GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource10,GPIO_AF_4);

   //---------------------------- Deinitialize I2C1 clock ------------------
    // Reset I2C1 device clock in order to avoid non-cleared error flags 
    //RCC_APB1PeriphResetCmd((RCC_APB1Periph_I2C1),ENABLE);
    //RCC_APB1PeriphResetCmd((RCC_APB1Periph_I2C1),DISABLE);

    //I2C1 Configuration
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
    I2C_InitStructure.I2C_DigitalFilter = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_OwnAddress1 = addr<<1;
    //I2C_InitStructure.I2C_Timing = 0x10805D88;//0x50E30000;//0x20D22E37;//slave: 0x20D20000;
    I2C_Cmd(I2C1,ENABLE);
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_ITConfig(I2C1, I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE | I2C_CR1_RXIE, ENABLE); //meilh 20171025 remove  I2C_CR1_ERRIE|I2C_CR1_NACKIE|
   
    //---------------------------- Peripheral and DMA interrupts Initialization ------------------
    // Initialize I2C1 interrupts
    /* Configure NVIC for I2C1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);
}

要注意的地方是:GPIO_PinAFConfig((GPIO_TypeDef*)GPIOA,GPIO_PinSource9,GPIO_AF_4);

之前看例子是用的 GPIO_AF_1,I2C死活没反应,后来找厂家提供了一个可以跑的例子比较寄存器,发现此地方要用GPIO_AF_4,就正常工作了。

(2)中断处理接口

void I2C1_IRQHandler(void)
{
   __IO uint32_t I2CFlagStatus = 0x00000000;
   uint8_t data;
   
   I2CFlagStatus = (uint32_t)(I2C1->ISR & (uint16_t)0x0000100FE);
   if ((I2CFlagStatus & I2C_ISR_ADDR) != 0)
  	{
	    if(I2C1->ISR&I2C_ISR_DIR) //tx mode
	    {
             Tx_count = 0;
         	I2C1->ISR |= I2C_ISR_TXE;
             I2C1->ICR |= I2C_ICR_ADDRCF; 
	   } 
		
	 if((I2C1->ISR&I2C_ISR_DIR)==0) //rx mode
        {           
	    Rx_buffer[0] = 0;
	    Rx_count= 1;
           I2C1->ICR |= I2C_ICR_ADDRCF; 
        }
    }
   else if ((I2CFlagStatus & I2C_ISR_RXNE) != 0)
   {
   	 data = I2C_ReceiveData(I2C1);
	 if(Rx_count < Rx_MAX){
            Rx_buffer[Rx_count++] = data ;
	     if(Rx_count == 2){
	 	   reg_offset = Rx_buffer[1];
	     }
	 }
   }
  else if ((I2CFlagStatus & I2C_ISR_TXIS) != 0)
  {
		I2C_SendData(I2C1,Tx_buffer[reg_offset+Tx_count]);
		Tx_count++;
		if(Tx_count >= Tx_MAX)
		{
			Tx_count = 0; //tx ok
		}
  }
  else if ((I2CFlagStatus & I2C_ISR_STOPF) != 0)
  {
 		I2C1->ICR |= I2C_ICR_STOPCF;
		Rx_buffer[0] = Rx_count;
 		Rx_count = 0;
 		Tx_count = 0;
  } 
  
}
F0的I2C状态判断比较容易,不过可能也因为使用的频率低暂未发现问题,后来F103也仿照这个形式进行了修改。

其它就没什么好说的,自己根据自己的协议接口进行修改。

你可能感兴趣的:(stm32开发)