0

我已经在这个项目上工作了一段时间,我似乎无法正确设置 i2c 以读取 MPU6050 输出的数据。按代码顺序,我有 Main.c、i2c.h 和 i2c_MPU.h

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "i2c.h"
#include "i2c_MPU.h"
// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
//These are the values to set baud rate for UART and configure some functions
#define BAUD 9600  
#define FOSC 4000000L  
#define DIVIDER ((int)(FOSC/(16UL * BAUD) -1)) // Should be 25 for9600/4MhZ  
#define NINE_BITS 0  
#define SPEED 0x4  
#define RX_PIN TRISC5  
#define TX_PIN TRISC4  
#define _XTAL_FREQ 4000000.0 /*for 4mhz*/
  
//*Function Prototypes*//  
 
void pinConfig(void);  
void setup_comms(void);  
void putch(unsigned char);  
unsigned char getch(void);  
unsigned char getche(void);  
unsigned int I2C_MPU_Init();


void main(void) 
{
   
   pinConfig();  
   setup_comms();
   
  
  while(1)
  {
   i2c_Init();
   I2C_MPU_Init();
   __delay_ms(1000);
  }
   
   return;
}
void setup_comms(void) 
{  
RX_PIN = 1;  
TX_PIN = 1;  
SPBRG = DIVIDER;  
RCSTA = (NINE_BITS | 0x90);  
TXSTA = (SPEED | NINE_BITS | 0x20);  
TXEN = 1;  
SYNC = 0;  
SPEN = 1;  
BRGH = 1;  
  }  

void putch(unsigned char byte)  
  {  
/* output one byte */  
while(!TXIF) /* set when register is empty */  
continue;  
TXREG = byte;  
  }  

unsigned char getch()  
  {  
/* retrieve one byte */  
while(!RCIF) /* set when register is not empty */  
continue;  
return RCREG;  
  }  

unsigned char getche(void)  
  {  
unsigned char c;  
putch(c = getch());  
return c;  
  }  
  
void pinConfig(void)  {  

 OSCCON = 0x6A; /* b6..4 = 1101 = 4MHz */  
 
 TXCKSEL = 1; // both bits in APFCON0 MUST BE 1 for 1829 0 for 1825  
 RXDTSEL = 1; /* makes RC4 & 5 TX & RX for USART (Allows ICSP)*/  
  
 TRISA = 0x02;  
 ANSELA =0x10;  
 TRISC = 0x0C; /* set as output */  
 ANSELC =0x0C; /* all ADC pins to digital I/O */  
 TRISB = 0xF0;
 ANSELB =0xF0;
 INTCON = 0; // purpose of disabling the interrupts.  
  } 
#define I2C_WRITE 0
#define I2C_READ 1

// Initialise MSSP1 port. (16F1829 on VIVA board - other devices may differ)
void i2c_Init(void){

    // Initialise I2C MSSP 1 module
    // Master 100KHz
    TRISB4=1;               // set SCL and SDA pins as inputs
    TRISB6=1;

    SSP1CON1 = 0b00101000;  // I2C enabled, Master mode
    SSP1CON2 = 0x00;
    // I2C Master mode, clock = FOSC/(4 * (SSP1ADD + 1)) 
    SSP1ADD = 9;            // 100Khz @ 4Mhz Fosc

    SSP1STAT = 0b11000000;  // Slew rate disabled
    

}

// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
    while ( ( SSP1CON2 & 0x1F ) || ( SSP1STAT & 0x04 ) );  
}

// i2c_Start - Start I2C communication
void i2c_Start(void)
{
    i2c_Wait();
    SSP1CON2bits.SEN=1;
}

// i2c_Restart - Re-Start I2C communication
void i2c_Restart(void){
    i2c_Wait();
    SSP1CON2bits.RSEN=1;
}

// i2c_Stop - Stop I2C communication
void i2c_Stop(void)
{
    i2c_Wait();
    SSP1CON2bits.PEN=1;
}

// i2c_Write - Sends one byte of data
void i2c_Write(unsigned char data)
{
    i2c_Wait();
    SSP1BUF = data;
}

// i2c_Address - Sends Slave Address and Read/Write mode
// mode is either I2C_WRITE or I2C_READ
void i2c_Address(unsigned char address, unsigned char mode)
{
    unsigned char l_address;

    l_address=address<<1;
    l_address+=mode;
    i2c_Wait();
    SSP1BUF = l_address;
}

// i2c_Read - Reads a byte from Slave device
unsigned char i2c_Read(unsigned char ack)
{
    // Read data from slave
    // ack should be 1 if there is going to be more data read
    // ack should be 0 if this is the last byte of data read
    unsigned char i2cReadData;

    i2c_Wait();
    SSP1CON2bits.RCEN=1;
    i2c_Wait();
    i2cReadData = SSP1BUF;
    i2c_Wait();
    if ( ack ) SSP1CON2bits.ACKDT=0;            // Ack
    else       SSP1CON2bits.ACKDT=1;            // NAck
    SSP1CON2bits.ACKEN=1;                       // send acknowledge sequence

    return( i2cReadData );
}
#define I2C_WRITE 0
#define I2C_READ 1
#define _XTAL_FREQ 4000000.0 /*for 4mhz*/
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>



unsigned int I2C_MPU_Init()
{
    
    int Gx, Gy, Gz;
    float GX, GY, GZ;
    char data[14];
/*
    i2c_Start(); 
    i2c_Address(0x68, 0x00);
    i2c_Write(0x75);
    i2c_Restart();
    i2c_Address(0x68, 0x01);
    
    data=i2c_Read(0);

    printf("Test = %i\n\r",data);
   */ 
    RA5=1;//green
    RA2=1;//blue
    RC6=1;//red
  
    //SMPLRT_DIV
    i2c_Start();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x19);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x07);
    i2c_Restart();
    
    
    //PWR_MGMT_1
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x6B);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x00);
    i2c_Restart();
    
    //DLPF CONFIG
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x1A);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x00);
    i2c_Restart();
    
    //GRYO_CONFIG
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x1B);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x18);
    i2c_Restart();
    
    //Data Ready Interrupts(just incase) 
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x38);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x00);
    i2c_Restart();
 // here new   
   
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x43);
    i2c_Restart();
    
    i2c_Address(0x68, I2C_READ);
    
    //0,2,4 shifted 8 added to 1,3,5
  Gx = ((int)i2c_Read(1)<<8) | (int)i2c_Read(1);
  Gy = ((int)i2c_Read(1)<<8) | (int)i2c_Read(1);
  Gz = ((int)i2c_Read(1)<<8) | (int)i2c_Read(0);
    i2c_Stop();
    
  GX = (float)Gx/131.0;
  GY = (float)Gy/131.0;
  GZ = (float)Gz/131.0;
       
printf("\n\rGx = %.2f ,Gy = %.2f , Gz = %.2f  ",GX,GY,GZ);

}

(int)i2c_Read(0) 末尾的 0 用于知道何时停止阅读以进行澄清。

Gz = ((int)i2c_Read(1)<<8) | (int)i2c_Read(0);

我试图用 1kHz 的采样率初始化采样率

    i2c_Start();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x19);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x07);
    i2c_Restart();

将 PLL 与 X 轴陀螺仪参考一起使用的电源管理

    //PWR_MGMT_1
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x6B);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x01);
    i2c_Restart();

使用最高带宽频率 (256Hz) 配置 e 数字低通滤波器 (DLPF)

    //DLPF CONFIG
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x1A);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x00);
    i2c_Restart();

陀螺仪配置使用完整的 ±2000°/s

    //GRYO_CONFIG
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x1B);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x18);
    i2c_Restart();

和数据就绪中断

    //Data Ready Interrupts
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x38);
    i2c_Restart();
    i2c_Address(0x68, I2C_WRITE);
    i2c_Write(0x00);
    i2c_Restart();

如果我能在正确的方向上获得一些关于我做错了什么的帮助,那就太好了,谢谢!

4

0 回答 0