STM32F407单片机使用HAL库读取MPU6050 IIC数据附带代码(1)

本次会尝试使用hal库软件模拟iic来读取mpu6050中的数据。

使用的核心板为stm32f407ZGT6。使用器件为mpu6050

会通过软件iic读取mpc6050中的数据

同时本次实验参考江协科技实验。

首先了解iic协议规则

iic协议特点:有两根通信线构成:SCL和SDA,同步半双工传输信息。带数据应答。

iic电路中,我们需要保证所有从机的SCL和SDA连接在一起,同时端口配置为开漏输出模式。并在在sda和scl各自添加一个上拉电阻。在通信中主机具有scl的绝对控制权,同时从机不可主动控制sda,除非在应答器件或者主机发送读取信号时,从机可以短暂获取sda控制权。

这里先对串口进行初始化,这里使用PB5.6两个口进行模拟,

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB5 PB6 */
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_SET);
}

这里将PB5,6设置为上拉,开漏输出模式。

同时我们将设置PB5,6的电平代码进行封装,这里我们根据江协科技所给案例进行封装

void myiicwscl(uint8_t bitvalue)
{
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, (GPIO_PinState)(bitvalue));
    HAL_Delay(20);
}

void myiicwsda(uint8_t bitvalue)
{
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6, (GPIO_PinState)(bitvalue));
    HAL_Delay(20);
}

这里注意,在hal库中我们要使用函数

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6, (GPIO_PinState)(bitvalue));

来进行电平的翻转,这与标准库有所不同

下面是iic的通信步骤,这里我们根据逻辑时序图来进行代码的编写

通信协议:

通信开始

SCL在高电平器件检测到SDA由高电平转换为低电平,示意图

代码如下

void myiicstart()
{
    myiicwsda(1);
    myiicwscl(1);
    myiicwsda(0);
    myiicwscl(0);

}

通信结束

SCL在低电平器件检测到SDA由低电平转换为高电平,示意图

代码如下

void myiicstop()
{
    myiicwsda(0);
    myiicwscl(1);
    myiicwsda(1);

}

发送数据

当SCL时钟线处于高电平时,在这一时刻,从机会读取SDA此时的电平,通俗来奖,就是数据应当在 SCL处于低电平时被放置在SDA线上,当SCL处于高电平时,该数据会被读取。

如图所示

代码示例

void myiicsent(uint8_t Byte)
{
    uint8_t i;
    for(i=0;i<8;i++)
    {
   myiicwsda(Byte & (0x80>>i));
     myiicwscl(1);
     myiicwscl(0);
    }

}

接收数据

接收数据与发送数据逻辑相同,都是在SCL高电平器件放置SDA 上的数据,随后当SCL转变为高电平时候读取SDA 数据。二者区别是,在接受中,要先释放主机对SDA线的主动权,将控制权下放给从机,由于我们将串口设置为开漏输出,且为上拉模式,因此我们只需要控制主机将SDA 置一就可以将控制权交给从机。从机会再随后的SCL低电平期间,进行数据的放置。

uint8_t myiicreceive(uint8_t Byte)
{
    uint8_t i,byte = 0x00;
    myiicwsda(1);
        for(i=0;i<8;i++)
    {
        myiicwscl(1);
        if(myiicread()==1) 
        {
        byte|=(0x80>>i);}
        myiicwscl(0);        
  }
    return byte;
}

发送与接受应答信号

主机SCL拉高,读取从机SDA的电平,为低电平表示产生应答

代码如下

void myiicsentack(uint8_t ackByte)
{

   myiicwsda(ackByte);
     myiicwscl(1);
     myiicwscl(0);

}

uint8_t myiicreceiveack(void)
{
      uint8_t ackByte = 0x00;
      myiicwsda(1);
        myiicwscl(1);
      ackByte = myiicread();
        myiicwscl(0);
      return ackByte;

}

截至至此,我们对iic的基础通信部分已经完成,下面我们先对mpu6050进行呼叫,看他是否对我们的信息产生应答

这里我们在我们的主函数中,调用我们的iic头文件,并写下下面语句

    myiicstart();
    myiicsent(0xD0);
    uint8_t ack = myiicreceiveack();
    myiicstop();

    uint8_t message = ack;

在写完之后我们编译运行烧录到我们的板子中,并根据线路连接到我们的mpu6050,随后我们开启硬件调试模式,进行查看message的数据是否为0x00.

数据正确,

这里我们再将地址进行更改进行检验

     myiicstart();
    myiicsent(0xA0);
    uint8_t ack = myiicreceiveack();
    myiicstop();

  uint8_t message = ack;

    数据显示0x01,证明代码编写正确。

下一步我会综合mpu6050文档对mpu6050数据进行读取,需要代码的可以发送到我的邮箱。后续在考虑怎么把数据展示出来,是直接串口还是用oled显示出来。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32F407单片机使用HAL库读取MPU6050 IIC数据附带代码(1)

发表评论