TI中文支持网
TI专业的中文技术问题搜集分享网站

TM4C123GXL launchpad 的I2C读到的数据都是0的问题

用TM4C123GH6PM (launchpad) 通过I2C读取 MPU6050 的数据 通过逻辑分析仪看到能得到数据和ACK 但在debug中获得的数据始终为0的问题

源码:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"//时钟
#include "driverlib/gpio.h"//GPIO
#include "driverlib/pwm.h"//PWM
#include "driverlib/i2c.h"//I2C
#include "driverlib/pin_map.h"
#include "sensorlib/hw_mpu6050.h"
#define PERIOD_TIME 12500 *1.25 // 50 Hz //DC_motor

#define MWSR_ADDRESS 0xD0
#define MRSW_ADDRESS 0xD1
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define PWR_MGMT_2 0x6C

void InitPWM();
void Init6050();
void WriteByte( uint8_t reg, uint8_t dat);
uint32_t ReadByte( uint8_t reg );

typedef struct Vector3D{
double x,y,z;
}Vector3D;

Vector3D gyo, acc;
//tMPU6050 *mpu6050;
int main(void) {

SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);//设置系统主频

InitPWM();
Init6050();

//MPU6050Init(mpu6050)
//mpu6050.
//while(1)
{
gyo.x = ReadByte(GYRO_XOUT_H);
gyo.y = ReadByte(GYRO_YOUT_H);
gyo.z = ReadByte(GYRO_ZOUT_H);
acc.x = ReadByte(ACCEL_XOUT_L);
acc.y = ReadByte(ACCEL_YOUT_L);
acc.z = ReadByte(ACCEL_ZOUT_L);
}
/*for(count=0;count<10;++count)
{
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, (2.5+count*0.5)*PERIOD_TIME/100);
SysCtlDelay(SysCtlClockGet() / 6 * 10);
}
//SysCtlDelay(SysCtlClockGet() / 6 * 10);
*/

return 0;
}

void Init6050()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);//使能外设
//上拉端口
GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

//信号端口设置
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

// 初始化I2C主机模块。设置总线速度和使能主机模块
I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet()/3, false);
// 使能I2C主机模块
I2CMasterEnable(I2C0_BASE);

WriteByte(PWR_MGMT_1, 0x00); //解除休眠状态
WriteByte(PWR_MGMT_2, 0x00); //解除休眠状态
WriteByte(SMPLRT_DIV, 0x07);
WriteByte(CONFIG, 0x06);
WriteByte(GYRO_CONFIG, 0x18);
WriteByte(ACCEL_CONFIG, 0x01);

}

void WriteByte( uint8_t reg, uint8_t dat)
{
I2CMasterSlaveAddrSet(I2C0_BASE, 0x68, false);//设置从机地址
I2CMasterDataPut(I2C0_BASE,reg);
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
SysCtlDelay(SysCtlClockGet() / 20000 );
I2CMasterDataPut(I2C0_BASE, dat);
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
SysCtlDelay(SysCtlClockGet() / 20000 );
}

uint32_t ReadByte( uint8_t reg )
{
uint32_t rlt;
I2CMasterSlaveAddrSet(I2C0_BASE, 0x68, false);//设置从机地址

I2CMasterDataPut(I2C0_BASE,reg);
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
SysCtlDelay(SysCtlClockGet() / 20000 );

I2CMasterSlaveAddrSet(I2C0_BASE, 0x68, false);//设置从机地址
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
SysCtlDelay(SysCtlClockGet() / 20000 );
rlt = I2CMasterErr(I2C0_BASE);
rlt = I2CMasterDataGet(I2C0_BASE);
return rlt;
}
void InitPWM()
{
// 设置PWM时钟和系统时钟一致
SysCtlPWMClockSet(SYSCTL_PWMDIV_16);
// 使能PWM外设
// 使能PWM外设
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
// 使能外设端口
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//设置对应管脚的PWM信号功能
GPIOPinConfigure(GPIO_PB7_M0PWM1);
GPIOPinConfigure(GPIO_PB4_M0PWM2);
GPIOPinConfigure(GPIO_PF1_M1PWM5);
GPIOPinConfigure(GPIO_PF3_M1PWM7);
//设置PWM信号端口
GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_7);
GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_3);
//PWM生成器配置
PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
//设置PWM信号周期
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, PERIOD_TIME);
PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, PERIOD_TIME);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, PERIOD_TIME);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, PERIOD_TIME);
//设置PWM信号占空比
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, 3.5 * PERIOD_TIME / 100);
PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, 3.5 * PERIOD_TIME / 100);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5, 3.5 * PERIOD_TIME / 100);
PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7, 3.5 * PERIOD_TIME / 100);
// 使能PWM输出端口
PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT | PWM_OUT_2_BIT , true);
PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT | PWM_OUT_7_BIT, true);
// 使能PWM生成器
PWMGenEnable(PWM0_BASE, PWM_GEN_0);
PWMGenEnable(PWM0_BASE, PWM_GEN_1);
PWMGenEnable(PWM1_BASE, PWM_GEN_2);
PWMGenEnable(PWM1_BASE, PWM_GEN_3);
// 延时同步四路PWM信号
/*PWMSyncTimeBase(PWM0_BASE, PWM_GEN_1_BIT);
SysCtlDelay((PERIOD_TIME / 2) );
PWMSyncTimeBase(PWM0_BASE, PWM_GEN_0_BIT);
SysCtlDelay((PERIOD_TIME * 7/ 8));
PWMSyncTimeBase(PWM1_BASE, PWM_GEN_3_BIT);
SysCtlDelay((PERIOD_TIME / 2));
PWMSyncTimeBase(PWM1_BASE, PWM_GEN_2_BIT);*/

}

这是发送数据的波形

这是读取数据的波形

循环重复的几次基本一致 就不全贴上来了

user151383853:

时序波形上看, 还是蛮正常的. 根据协议, 你都是发的写数据.  如何获得的数据呢?

xyz549040622:

有网友提示说MPU6050上电后是处于休眠状态的,必须唤醒,可以查看6050的这个POWERMANAGEMENT 1寄存器是否在休眠状态

可以参考这个帖子

http://www.deyisupport.com/question_answer/microcontrollers/tiva_arm_cortex/f/96/t/59723.aspx?pi2132219853=2

赞(0)
未经允许不得转载:TI中文支持网 » TM4C123GXL launchpad 的I2C读到的数据都是0的问题
分享到: 更多 (0)