我已经在这个项目上工作了一段时间,我似乎无法正确设置 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();
如果我能在正确的方向上获得一些关于我做错了什么的帮助,那就太好了,谢谢!