STM32入门学习笔记之MPU6050传感器解析实验4

发布时间:2024-05-27  

(2)创建mpu6050.c文件,输入以下代码。


/*********************************************************************************************************

                MUP6050    驱    动    程    序

*********************************************************************************************************/

#include "mpu6050.h"

#include "delay.h"

/***************************************************

Name    :MPU_IIC_Init

Function  :初始化IIC

Paramater  :None

Return    :None

***************************************************/

void MPU_IIC_Init()

{

   RCC->APB2ENR |= 1<<3 ;                                        //先使能PB时钟

  GPIOB->CRH &= 0xFFFF00FF ;                                      //PB10/11 推挽输出

  GPIOB->CRH |= 0x00003300 ;

  GPIOB->ODR |= 3<<10 ;                                        //PB10,11 输出高

}

/***************************************************

Name    :MPU_IIC_Wait_Ack

Function  :开始时序

Paramater  :None

Return    :None

***************************************************/

void MPU_IIC_Start()

{

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00003000 ;

  MPU_IIC_SDA = 1 ;

  MPU_IIC_SCL = 1 ;

  delay_us( 2 ) ;

  MPU_IIC_SDA = 0 ;

  delay_us( 2 ) ;

  MPU_IIC_SCL = 0 ;

}

/***************************************************

Name    :MPU_IIC_Wait_Ack

Function  :停止时序

Paramater  :None

Return    :None

***************************************************/

void MPU_IIC_Stop()

{

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00003000 ;

  MPU_IIC_SCL = 0 ;

  MPU_IIC_SDA = 0 ;

  delay_us( 2 ) ;

  MPU_IIC_SCL = 1 ;

  MPU_IIC_SDA = 1 ;

  delay_us( 2 ) ;

}

/***************************************************

Name    :MPU_IIC_Wait_Ack

Function  :应答时序

Paramater  :None

Return    :

      0:成功

      1:失败

***************************************************/

u8 MPU_IIC_Wait_Ack()

{

  u8 ucErrTime=0 ;

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00008000 ;

  MPU_IIC_SDA = 1 ;

  delay_us( 2 ) ;

  MPU_IIC_SCL = 1 ;

  delay_us( 2 ) ;

  while( MPU_READ_SDA )

  {

    ucErrTime ++ ;

    if( ucErrTime>250 )

    {

      MPU_IIC_Stop() ;

      return 1 ;

    }

  }

  MPU_IIC_SCL = 0 ;                                          //时钟输出0

  return 0 ;

}

/***************************************************

Name    :MPU_IIC_Send_Byte

Function  :IIC发送1个字节

Paramater  :

      Ack:应答控制

        0:不应答

        1:应答

Return    :None

***************************************************/

void MPU_IIC_Send_Byte( u8 Byte )

{

  u8 i ;

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00003000 ;

  MPU_IIC_SCL = 0 ;                                          //拉低时钟开始数据传输

  for( i=0; i<8; i++ )

  {

    if( ( Byte&0x80 )==0x80 )

      MPU_IIC_SDA = 1 ;

    else

      MPU_IIC_SDA = 0 ;

        Byte <<= 1 ;

    MPU_IIC_SCL = 1 ;

    delay_us( 2 ) ;

    MPU_IIC_SCL = 0 ;

    delay_us( 2 ) ;

  }

}

/***************************************************

Name    :MPU_IIC_Read_Byte

Function  :IIC读取1个字节

Paramater  :

      Ack:应答控制

        0:不应答

        1:应答

Return    :读取的字节

***************************************************/

u8 MPU_IIC_Read_Byte( u8 Ack )

{

  u8 i, Byte=0;

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00008000 ;

    for( i=0; i<8; i++ )

  {

    MPU_IIC_SCL = 0 ;

    delay_us( 2 ) ;

    MPU_IIC_SCL = 1 ;

    Byte <<= 1 ;

    if( MPU_READ_SDA )

      Byte ++ ;

    delay_us( 2 ) ;

  }

  MPU_IIC_SCL = 0 ;

  GPIOB->CRH &= 0xFFFF0FFF ;

  GPIOB->CRH |= 0x00003000 ;

  MPU_IIC_SDA = 1-Ack ;

  delay_us( 2 ) ;

  MPU_IIC_SCL = 1 ;

  delay_us( 2 ) ;

  MPU_IIC_SCL = 0 ;

  return Byte ;

}

/***************************************************

Name    :MPU_Write_Byte

Function  :IIC写一个字节

Paramater  :

      reg:寄存器地址

      data:数据

Return    :

      0:正常

      其他:错误代码

***************************************************/

u8 MPU_Write_Byte( u8 reg, u8 data )

    MPU_IIC_Start() ; 

  MPU_IIC_Send_Byte( MPU_ADDR<<1 ) ;                                  //发送器件地址+写命令

  //等待应答

  if( MPU_IIC_Wait_Ack() )

  {

    MPU_IIC_Stop() ;

    return 1 ;

  }

    MPU_IIC_Send_Byte( reg ) ;                                      //写寄存器地址

    MPU_IIC_Wait_Ack() ;                                        //等待应答

  MPU_IIC_Send_Byte( data ) ;                                      //发送数据

  //等待ACK

  if( MPU_IIC_Wait_Ack() )

  {

    MPU_IIC_Stop() ;

    return 1 ;

  }

    MPU_IIC_Stop() ;

  return 0 ;

}

/***************************************************

Name    :MPU_Read_Byte

Function  :IIC读一个字节

Paramater  :

      reg:寄存器地址

Return    :读到的数据

***************************************************/

u8 MPU_Read_Byte( u8 reg )

{

  u8 res ;

    MPU_IIC_Start() ;

  MPU_IIC_Send_Byte( MPU_ADDR<<1 ) ;                                  //发送器件地址+写命令

  MPU_IIC_Wait_Ack() ;                                        //等待应答

    MPU_IIC_Send_Byte( reg ) ;                                      //写寄存器地址

    MPU_IIC_Wait_Ack() ;                                        //等待应答

    MPU_IIC_Start() ;

  MPU_IIC_Send_Byte( ( MPU_ADDR<<1 )|1 ) ;                              //发送器件地址+读命令

    MPU_IIC_Wait_Ack() ;                                        //等待应答

  res = MPU_IIC_Read_Byte( 0 ) ;                                    //读取数据,发送nACK

    MPU_IIC_Stop() ;                                          //产生一个停止条件

  return res ;

}

/***************************************************

Name    :MPU_Read_Byte

Function  :设置MPU6050的采样率(假定Fs=1KHz)

Paramater  :

      rate:4~1000(Hz)

Return    :

      0:成功

      其他:失败

***************************************************/

u8 MPU_Set_Rate( u16 rate )

{

  u8 data ;

  if( rate>1000 )

    rate=1000 ;

  if( rate<4 )

    rate = 4 ;

  data = 1000/rate-1 ;

  data = MPU_Write_Byte( MPU_SAMPLE_RATE_REG, data ) ;                        //设置数字低通滤波器

  //自动设置LPF为采样率的一半

  if( ( rate/2 )>=188 )

    data = 1 ;

  else if( ( rate/2 )>=98 )

    data = 2 ;

  else if( ( rate/2 )>=42 )

    data = 3 ;

  else if( ( rate/2 )>=20 )

    data = 4;

  else if( ( rate/2 )>=10 )

    data = 5 ;

  else

    data = 6 ;

  return MPU_Write_Byte( MPU_CFG_REG, data ) ;                            //设置数字低通滤波器

}

/***************************************************

Name    :MPU_Init

Function  :初始化MPU6050

Paramater  :None

Return    :

      0:成功

      其他:错误代码

***************************************************/

u8 MPU_Init()

  u8 res ;

  RCC->APB2ENR |= 1<<2 ;                                        //使能PORTA时钟 

  GPIOA->CRH &= 0x0FFFFFFF ;                                      //PA15设置成推挽输出    

  GPIOA->CRH |= 0x30000000 ; 

  JTAG_Set( 1 ) ;                                            //禁止JTAG,从而PA15可以做普通IO使用,否则PA15不能做普通IO

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>