STM32 IIC 通信 库函数实现

reading stucture                              
  device address   read command write address to board     device address read data from board    
start 0xb0 ack 0x01 ack address high ack address low ack start 0xb1 ack data high ack data low nack stop
example to read   address 0x1234 and result 0x789A                        
start 0xb0 ack 0x01 ack 0x12 ack 0x34 ack start 0xb1 ack 0x78 ack 0x9a nack stop
                                 
                                 
                                 
                                 
writing   stucture                              
  device address   write command write address to board read data from board          
start 0xb0 ack 0x81 ack address high ack address low ack data high ack data low ack stop      
example to write   address 0x5678 with data 0xcdef                        
start 0xb0 ack 0x81 ack 0x56 ack 0x78 ack 0xcd ack 0xef ack stop 0x9a  
Read Register
void Read_Reg(u8 *DataBuff,u8 ByteQuantity,uint16_t RegAddress,u8 SlaveAddress)
{
     //这句去掉也正常
     while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008

    /* Send START condition */     
     I2C_GenerateSTART(I2C1, ENABLE);
     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
     /* 发送器件地址(写)*/
     I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */

     //这句去掉也正常
     /* Clear EV6 by setting again the PE bit */
     I2C_Cmd(I2C1, ENABLE);

    I2C_SendData(I2C1,01);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,RegAddress>>8);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,RegAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
     /* 发送器件地址(写)*/
    I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */

    while (ByteQuantity)
    {
        if(ByteQuantity==1)
        {
             I2C_AcknowledgeConfig(I2C1, DISABLE);    //最后一位后要关闭应答的
            I2C_GenerateSTOP(I2C1, ENABLE);            //发送停止位
        }
        
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
        *DataBuff = I2C_ReceiveData(I2C1);
        DataBuff++;
        /* Decrement the read bytes counter */
        ByteQuantity--;
    }
    //再次允许应答模式
    I2C_AcknowledgeConfig(I2C1, ENABLE);
    //errorflag=0;
    //break;
    
}
Write Register
void Write_Reg(uint16_t WriteValue,uint16_t RegAddress,u8 SlaveAddress)
{


  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008
    
  /* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
  
  /* Send EEPROM address for write */
  I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
  
  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

      I2C_SendData(I2C1,0x81);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,RegAddress>>8);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,RegAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_SendData(I2C1,WriteValue>>8);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    I2C_SendData(I2C1,WriteValue);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send STOP condition */
  I2C_GenerateSTOP(I2C1, ENABLE);
}
I2C_Send7bitAddress
/**
  * @brief  Transmits the address byte to select the slave device.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  Address: specifies the slave address which will be transmitted
  * @param  I2C_Direction: specifies whether the I2C device will be a
  *   Transmitter or a Receiver. This parameter can be one of the following values
  *     @arg I2C_Direction_Transmitter: Transmitter mode
  *     @arg I2C_Direction_Receiver: Receiver mode
  * @retval None.
  */
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
{
  /* Check the parameters */
  assert_param(IS_I2C_ALL_PERIPH(I2Cx));
  assert_param(IS_I2C_DIRECTION(I2C_Direction));
  /* Test on the direction to set/reset the read/write bit */
  if (I2C_Direction != I2C_Direction_Transmitter)
  {
    /* Set the address bit0 for read */
    Address |= OAR1_ADD0_Set;
  }
  else
  {
    /* Reset the address bit0 for write */
    Address &= OAR1_ADD0_Reset;
  }
  /* Send the address */
  I2Cx->DR = Address;
}

#define  I2C_Direction_Transmitter      ((uint8_t)0x00)
#define  I2C_Direction_Receiver         ((uint8_t)0x01)

7位模式下,地址字节最低位若是0则说明主机要进入发送模式,若是1则是接收模式

原文地址:https://www.cnblogs.com/wwjdwy/p/2945742.html