MPU6050을 사용할 때 발생하는 다양한 문제를 기록합니다.


참고: 내 코드는 Punctual Atom에서 공식적으로 제공한 MPU6050 실험 코드를 기반으로 하며 dmp 라이브러리를 사용하여 오일러 각도를 찾습니다.

1. 질문 1: MPU6050 초기화가 실패하고 while 루프에 들어가지 않습니다.

이유: MPU6050은 전원을 켤 때 초기화하는 동안 자체 테스트를 수행해야 합니다. 하드웨어가 너무 기울어진 상태에 있으면 멈추게 됩니다. 평평하게 유지하거나 무작위로 흔들리지 않아야 합니다.

2. 질문 2: MPU6050을 AD0 핀에 연결해야 합니까?

답변: AD0 핀이 접지에 연결되면 하드웨어 주소는 0x68입니다. 3V3에 연결되면 주소는 0x69입니다. 여기에 배선할 필요가 없습니다. 주소는 코드에 정의된 0x68입니다. 동시에 시간이 지나면 MPU6050의 초기화 기능에서 AD0 주석을 핀의 초기화 문에 넣을 수도 있습니다.

3. 질문 3: MPU6050은 5V 또는 3V3으로 전원을 공급받을 수 있습니까?

답변: 제가 구입한 일반 버전은 두 가지를 모두 수용할 수 있습니다.

4. 질문 4: MPU6050의 IIC 통신에 하드웨어 IIC 또는 소프트웨어 IIC를 사용하는 것이 더 낫습니까?

답: 상황에 따라 다르다고밖에 말씀드릴 수 없습니다. MPU6050의 경우 하드웨어 IIC는 속도가 더 빠르고 CPU 사용량이 적습니다. 소프트웨어 IIC 통신에는 더 많은 CPU 시간과 컴퓨팅 리소스가 필요하지만 하드웨어 IIC는 온라인에서 불안정하고 문제가 발생하기 쉽다고 합니다. 여기서는 필요한 전송 속도가 높지 않기 때문에 소프트웨어 IIC 시뮬레이션을 사용하는 것이 더 좋습니다. 더 빠른 속도의 전송이 필요한 경우 하드웨어 IIC를 사용하십시오.
이는 하드웨어 IIC의 초기화 기능입니다.

void IIC_Init( u32 bound , u16 address )
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;
	I2C_InitTypeDef I2C_InitTSturcture;

	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );
//	GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOB, &GPIO_InitStructure );

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOB, &GPIO_InitStructure );

	I2C_InitTSturcture.I2C_ClockSpeed = bound;
	I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;
	I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_16_9;
	I2C_InitTSturcture.I2C_OwnAddress1 = address;
	I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;
	I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init( I2C2, &I2C_InitTSturcture );
	I2C_Cmd( I2C2, ENABLE );
	I2C_AcknowledgeConfig( I2C2, ENABLE );
}

이는 소프트웨어 IIC의 초기화 기능입니다.

//初始化IIC接口引脚
void IIC_Init(void)
{
    
    
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    //GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_7|GPIO_Pin_6);
}

하드웨어 IIC의 편리함은 통신, 읽기, 쓰기 작업을 위해 미리 만들어진 멤버 변수와 라이브러리 함수를 호출할 수 있다는 것이고, 소프트웨어 IIC의 편리함은 SCL 및 SDA 핀을 사용자 정의하고 GPIO의 상위 및 하위 레벨을 사용할 수 있다는 것입니다. IIC 효과를 시뮬레이션하려면 start, Stop, ack 및 기타 기능을 작성해야 하지만 이제 관련 코드를 온라인에서 쉽게 찾을 수 있습니다.

5. 질문 5: 수정이 권장되는 코드

소스 코드는 다음과 같습니다

  if(mpu_dmp_get_data(&Pitch, &Roll, &Yaw)==0){
    
    
     //xxxxxx
           }

이제 다음으로 변경하세요.

  while(mpu_dmp_get_data(&Pitch, &Roll, &Yaw)!=0){
    
    

           }

이러한 수정 후에는 새 데이터가 버퍼 영역에 너무 빨리 진입하여 FIFO 오버플로가 발생하고 MPU6050이 멈추는 것을 효과적으로 방지할 수 있습니다.

6. 질문 6: 매우 형이상학적인 질문: 연결

문제점 설명 : 정상적으로 전원을 켰 는데, MPU6050이 흔들리지 않으면 정상적으로 데이터를 인쇄하지만, 너무 빨리 흔들리면 멈춥니다 . 처음에는 케이블 문제인 줄 알고 케이블을 바꿔봤는데 여전히 문제가 발생했습니다. 그러다가 코드 문제인가 의심했는데 디버깅을 해보면 특정 프로그램에서 막히는 게 아니라 완전히 랜덤하게 인터럽트가 걸리더라구요. 그 후 핫멜트 접착제를 사용하여 VCC, GND, SCL, SDA 포트 및 듀폰 전선을 단단히 붙였으나 문제는 여전히 지속되었습니다. 매우 형이상학적입니다.

해결책: 좀 더 형이상학적인 태도를 취하세요. 며칠간의 테스트 끝에 실제로 듀폰 라인의 길이와 관련이 있다는 것을 알게 되었습니다. 저는 40cm 길이의 듀폰 와이어를 사용하고 있는데 항상 문제가 있습니다. 하지만 20cm의 짧은 듀폰 와이어로 바꿔보니 문제가 없었어요! ! ! 특이한 점은 듀퐁의 긴 선은 SCL과 SDA에는 연결이 가능하지만 VCC와 GND에는 연결이 안 된다는 점인데, VCC와 GND 중 적어도 하나는 짧은 선에 연결해야 재밍 없이 정상적으로 동작한다.

7. 소프트웨어 IIC의 포트 구성 문제에 대해

코드는 아래와 같이 표시됩니다.

//IO方向设置
#define SDA_IN() {
      
      GPIOB->CFGLR&=0X0FFFFFFF;GPIOB->CFGLR|=(u32)8<<28;}
#define SDA_OUT() {
      
      GPIOB->CFGLR&=0X0FFFFFFF;GPIOB->CFGLR|=(u32)3<<28;}

//IO操作函数
//#define IIC_SCL PBout(6)
//#define IIC_SDA PBout(7)
//#define READ_SDA PBin(9)

#define IIC_SCL_0 GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define IIC_SDA_0 GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define IIC_SCL_1 GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define IIC_SDA_1 GPIO_SetBits(GPIOB,GPIO_Pin_7)


stm32의 비트밴드 연산을 다른 플랫폼에 이식하는 것이 불가능하다는 점을 고려하여 다시 작성해야 하며, 다시 작성한 형식은 위와 같습니다.

Ich denke du magst

Origin blog.csdn.net/qq_53092944/article/details/132240114
Empfohlen
Rangfolge