IIC

1.IIC的地址问题

  • IIC中的器件地址DEV_ADDRESS是7位地址,但C语言中没有7bit的数据类型,所以你只能传uint8_t的数据进去。HAL库会把这个变量的高7位提取出来作为地址,根据实际情况对最后一个读写位set或reset。

  • 通常数据手册在表述地址的时候,地址是在一个8位二进制数的低7位,比如6050就是0x68=0110 1000,但HAL库IIC传进去的地址在一个8位二进制数的高7位,就变成了0xD0(写)或者0xD1(读)这点要注意。

  • HAL库你在传地址的时候不需要自己考虑第8位是0还是1,它那个函数内部会自动根据你调用的是IIC读还是IIC写来对那一位进行运算。不过你要是非要传第8位已经写0或1的地址进去也行,因为运算结果不会变,只要你不写反就行了

2. IIC的数据传输

IIC一般根据从机寄存器的位数来确定一次传几个字节的数据。通过以下函数中的 Size参数可以设定传输数据的字节数

1
2
3
4
5
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,

        uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData,

        uint16_t Size, uint32_t Timeout)

就行了。

  • 比如OLED里一次传一个字节的数据
1
2
HAL_I2C_Mem_Write(&hi2c2,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT,
&I2C_Command,1,100);
  • MPU6050封装的一次写指定长度的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//IIC写一个字节 
//reg:寄存器地址
//data:数据
//返回值:0,正常
// 其他,错误代码
u8 MPU_Write_Byte(u8 reg,u8 data)
{
u8 sta;
sta=HAL_I2C_Mem_Write(&hi2c1,MPU_ADDR<<1,reg,I2C_MEMADD_SIZE_8BIT,&data,1,100);
if(sta!=HAL_OK)
return 1;
else
return 0;
}
  • 如何取出多字节的数据呢?
1
2
3
4
5
6
7
8
9
u8 buf[6],res;  
res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
if(res==0)
{
*ax=((u16)buf[0]<<8)|buf[1];
*ay=((u16)buf[2]<<8)|buf[3];
*az=((u16)buf[4]<<8)|buf[5];
}
return res;