×
单片机 > 单片机程序设计 > 详情

STM32F0 Slave I2C配置

发布时间:2020-06-01 发布时间:
|

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单片机的复用端口初始化的步骤及方法