STM32 I2C从机

STM32 I2C slave

I2C Slave配置

  1. I2C默认工作在从模式
  2. 需要在I2C_CR2寄存器设置输入时钟频率!
    初始化代码 I2C2

    /*GPIO与IIC初始化结构体*/  
    GPIO_InitTypeDef GPIO_InitStructure;  
    I2C_InitTypeDef I2C_InitStructure;  
    
    /*GPIO与IIC时钟使能*/  
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE );     //GPIOB时钟使能  
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );      //IIC2时钟使能  
    
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10|GPIO_Pin_11 ;   //初始化GPIO.B10(IIC2_SCL),GPIO.B11(IIC2_SDA)  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //最高输出速度50Hz  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;             //输入输出模式为复用功能开漏输出  
    GPIO_Init( GPIOB, &GPIO_InitStructure );                    //根据GPIO初始化结构体初始化GPIOB  
    I2C_DeInit(I2C2);                                           //复位I2C
    /*初始化IIC2*/  
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                  //设置为IIC模式  
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;          //设置IIC的占空比,低电平除以高电平值为2  
    I2C_InitStructure.I2C_OwnAddress1 = addr;                   //指定第一个设备的地址为7位地址 从设备地址为函数参数addr 
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                 //使能ACK信号  
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   //指定7位地址  
    I2C_InitStructure.I2C_ClockSpeed = 100000;                  //时钟频率,必须小于等于400KHz  
    I2C_Init( I2C2, &I2C_InitStructure );   
    I2C2->CR2&=0xff00;                 **//设置I2C输入时钟频率为4Mhz**  根据时钟树配置
    I2C2->CR2|=0x04; 
    I2C_Cmd( I2C2, ENABLE );                                 //使能硬件IIC2  
    I2C_ITConfig(I2C2,I2C_IT_EVT|I2C_IT_BUF,ENABLE); 

地址匹配:

1. ack置1产生应答
2. ADDR置位,会产生ITEVFEN中断

数据发送

TRA 位指示I2C处于发送模式还是接收模式,TRA = 1为发送

从发送:

1. 接收地址清除ADDR位后,从发送器发送数据到sda上
2. 当ADDR位未被清除或者待发送数据未被写入DR寄存器,SCL会被拉低
3.  当收到ack后,TxE置位,产生中断(使能ITEVFEN和ITBUFFEN)。

如果TxE被置位,但在下一个数据发送结束之前没有新数据写入到I2C_DR,BTF会被置位,读SR1写DR可清除BTF位

从接收:

1. 接收地址清除ADDR位后,从接收器从SDA收取数据到DR寄存器中。
2. I2C接口在收到每个字节收据后都会做如下操作:
3. 若ack位置位,则产生应答
4. RxNE置位,产生中断
5. 若RxNE置位,DR数据尚未被读出,BTF置位,BTF位未被清除之前,SCL拉低
6. 读SR1写DR可清除BTF位

结束通信:

主设备产生停止条件,从机检测到停止条件后,stopf=1,产生中断。
I2c等待读sr1写cr1
中断处理函数

void I2C2_EV_IRQHandler(void)
{
    uint8_t temp;
    gwTimeout=0;
    if(I2C_GetFlagStatus(I2C2,I2C_FLAG_BERR)){//
        I2C_ClearFlag(I2C2,I2C_FLAG_BERR);
    }
    if(I2C_GetFlagStatus(I2C2,I2C_FLAG_ADDR)){

        if(I2C_GetFlagStatus(I2C2,I2C_FLAG_TRA)){
            I2C_SendData(I2C2,arryBuffer_Tx[gwOffset++]);
        }
        else{
            gwOffset= I2C_ReceiveData(I2C2);
        }
    }
    if(I2C_GetFlagStatus(I2C2,I2C_FLAG_RXNE)){
        arryBuffer_Rx[gwOffset]= I2C_ReceiveData(I2C2);
     }
    if(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE))
     {  
        I2C_SendData(I2C2,arryBuffer_Tx[gwOffset]);
        gwOffset++;
     } 
    if(I2C_GetFlagStatus(I2C2,I2C_FLAG_STOPF))
     {
        addr=0;
        I2C2->CR1|= 0x0001;//清除I2C_FLAG_STOPF
     }                  
}

你可能感兴趣的:(stm32)