stm32硬件I2C调试

基于标准库StdPeriph_Lib_V3.6.0进行硬件I2C主机调试,通过对从机的寄存器进行读写操作,已通过测试

I2C初始化

    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStructure;
    //时钟配置
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;                                //复用开漏
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                              //输出速率随意
    GPIO_Init(GPIOB,&GPIO_InitStruct);
    
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                                  //I2C模式
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;                          //占空比
    I2C_InitStructure.I2C_OwnAddress1 = 0;                                      //本机地址,主模式下无意义
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                                 //自动应答使能
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   //7位地址
    I2C_InitStructure.I2C_ClockSpeed = 400000;                                  //I2C频率100K~400K
    I2C_Init(I2C1,&I2C_InitStructure);
    I2C_Cmd(I2C1,ENABLE);

I2C写寄存器

	//发送开始信号
	I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    //发送从机地址-写
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    //发送写寄存器地址
    I2C_SendData(I2C1,D_MenAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
    //循环发送数据
    while(bufferSize--)
    {
        I2C_SendData(I2C1,*pBuffer);
        pBuffer++;
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING);
    }
    //发送停止信号
    I2C_GenerateSTOP(I2C1,ENABLE);

I2C读寄存器

	//发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
	//发送从设备地址-写
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    //发送寄存器地址
    I2C_SendData(I2C1,D_MenAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    //重新发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    //发送从设备地址-读
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    //循环读取数据
    while(bufferSize)
    {
        bufferSize--;
        if(bufferSize == 0)
        {
        	//关闭自动应答
            I2C_AcknowledgeConfig(I2C1, DISABLE);
        }
        
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
        *pBuffer = I2C_ReceiveData(I2C1);
        pBuffer++;
    }
	//发送停止信号
    I2C_GenerateSTOP(I2C1,ENABLE);
    //重新打开自动应答
    I2C_AcknowledgeConfig(I2C1, ENABLE);

注意事项:
1.GPIO必须设置为开漏复用模式
2.测试时一直停在busy状态时检查是否开启I2C时钟,通信器件之间是否可靠连接,I2C是否有被强制拉低
3.读写寄存器时设置从机地址时I2C_Send7bitAddress最后一个参数区分读写
4.读寄存器之前需对寄存器先进行从机地址和寄存器地址写入
5.读寄存器最后一个字节时需关闭自动应答,发送停止信号后一定要重新打开

6.可以添加一些返回值,如果(I2Cx->SR2 & 1<<1)提示I2C_Busy,进入发送或者接收后可以添加计时,超时返回I2C_Timeout

你可能感兴趣的:(stm32,arm)