This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:MPU6050和 TM4C123

Guru**** 2298230 points
Other Parts Discussed in Thread: TM4C123GH6PM
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/603963/tm4c123gh6pm-mpu6050-and-tm4c123

器件型号:TM4C123GH6PM

大家好、我需要帮助!  

我使用的是 mpu6050和我的 TM4C123GH6PM、但它不起作用

-当我使用示波器时、我的"时钟"(SCL)看起来像是干扰、PB2的配置可能错误  

-我不知道我是否必须使用 Fifos。

我只知道一点关于 I2C 的信息、所以... 实际上我不知道我在代码中写什么:(

私营部门司。 因为我来自秘鲁,所以有一些西班牙语的部分

#include "tm4c123ghp6.h"
#include
#include
#include
#include

#include "hw_memmap.h"
#include "hw_i2c.h"
#include "hw_types.h"
#include "hw_gpio.h"

#include "i2c.h"
#include "gpio.h"
#include "sysctl.h"
#include "pin_map.h"

//*********
//根据数据表注册名称。
//根据 InvenSense 文档
//"MPU-6000和 MPU-6050寄存器映射
//和说明版本4.2"

//以_H 和_L 结尾的寄存器名称
//分别包含高字节和低字节、
内部寄存器值的//

#define MPU6050_self_test_X 0x0D // R/W
#define MPU6050_self_test_Y 0x0E // R/W
#define MPU6050_self_test_Z 0x0F // R/W
#define MPU6050_self_test_A 0x10 // R/W
#define MPU6050_SMPLRT_DIV 0x19 // R/W
#define MPU6050_CONFIG 0x1A // R/W
#define MPU6050_gyro_config 0x1B // R/W
#define MPU6050_ACCEL_CONFIG 0x1C // R/W
#define MPU6050_FIFO_EN 0x23 // R/W
#define MPU6050_I2C_MST_CTRL 0x24 // R/W
#define MPU6050_I2C_SLV0_ADDR 0x25 // R/W
#define MPU6050_I2C_SLV0_REG 0x26 // R/W
#define MPU6050_I2C_SLV0_CTRL 0x27 // R/W
#define MPU6050_I2C_SLV1_ADDR 0x28 // R/W
#define MPU6050_I2C_SLV1_REG 0x29 // R/W
#define MPU6050_I2C_SLV1_CTRL 0x2A // R/W
#define MPU6050_I2C_SLV2_ADDR 0x2B // R/W
#define MPU6050_I2C_SLV2_REG 0x2C // R/W
#define MPU6050_I2C_SLV2_CTRL 0x2D // R/W
#define MPU6050_I2C_SLV3_ADDR 0x2E // R/W
#define MPU6050_I2C_SLV3_REG 0x2F // R/W
#define MPU6050_I2C_SLV3_CTRL 0x30 // R/W
#define MPU6050_I2C_SLV4_ADDR 0x31 // R/W
#define MPU6050_I2C_SLV4_REG 0x32 // R/W
#define MPU6050_I2C_SLV4_DO 0x33 // R/W
#define MPU6050_I2C_SLV4_CTRL 0x34 // R/W
#define MPU6050_I2C_SLV4_DI 0x35 // R
#define MPU6050_I2C_MST_STATUS 0x36 // R
#define MPU6050_INT_PIN_CFG 0x37 // R/W
#define MPU6050_INT_ENABLE 0x38 // R/W
#define MPU6050_INT_STATUS 0x3A // R

#define MPU6050_ACCEL_XOUT_H 0x3B // R
#define MPU6050_ACCEL_XOUT_L 0x3C // R
#define MPU6050_ACCEL_OUT_H 0x3D // R
#define MPU6050_ACCEL_OUT_L 0x3E // R
#define MPU6050_ACCEL_ZOUT_H 0x3F // R
#define MPU6050_ACCEL_ZOUT_L 0x40 // R
#define MPU6050_TEMP_OUT_H 0x41 // R
#define MPU6050_TEMP_OUT_L 0x42 // R
#define MPU6050_gyro_XOUT_H 0x43 // R
#define MPU6050_gyro_XOUT_L 0x44 // R
#define MPU6050_gyro_弹 出_H 0x45 // R
#define MPU6050_gyro_弹 出_L 0x46 // R
#define MPU6050_gyro_ZOUT_H 0x47 // R
#define MPU6050_gyro_ZOUT_L 0x48 // R
#define MPU6050_EXT_SENS_DATA_00 0x49 // R
#define MPU6050_EXT_SENS_DATA_01 0x4A // R
#define MPU6050_EXT_SENS_DATA_02 0x4B // R
#define MPU6050_EXT_SENS_DATA_03 0x4C // R
#define MPU6050_EXT_SENS_DATA_04 0x4D // R
#define MPU6050_EXT_SENS_DATA_05 0x4E // R
#define MPU6050_EXT_SENS_DATA_06 0x4F // R
#define MPU6050_EXT_SENS_DATA_07 0x50 // R
#define MPU6050_EXT_SENS_DATA_08 0x51 // R
#define MPU6050_EXT_SENS_DATA_09 0x52 // R
#define MPU6050_EXT_SENS_DATA_10 0x53 // R
#define MPU6050_EXT_SENS_DATA_11 0x54 // R
#define MPU6050_EXT_SENS_DATA_12 0x55 // R
#define MPU6050_EXT_SENS_DATA_13 0x56 // R
#define MPU6050_EXT_SENS_DATA_14 0x57 // R
#define MPU6050_EXT_SENS_DATA_15 0x58 // R
#define MPU6050_EXT_SENS_DATA_16 0x59 // R
#define MPU6050_EXT_SENS_DATA_17 0x5A // R
#define MPU6050_EXT_SENS_DATA_18 0x5B // R
#define MPU6050_EXT_SENS_DATA_19 0x5C // R
#define MPU6050_EXT_SENS_DATA_20 0x5D // R
#define MPU6050_EXT_SENS_DATA_21 0x5E // R
#define MPU6050_EXT_SENS_DATA_22 0x5F // R
#define MPU6050_EXT_SENS_DATA_23 0x60 // R
#define MPU6050_I2C_SLV0_DO 0x63 // R/W
#define MPU6050_I2C_SLV1_DO 0x64 // R/W
#define MPU6050_I2C_SLV2_DO 0x65 // R/W
#define MPU6050_I2C_SLV3_DO 0x66 // R/W

#define MPU6050_I2C_MST_DELAY_CTRL 0x67 // R/W
#define MPU6050_SIGNAL 路径复位0x68 // R/W
#define MPU6050_USER_CTRL 0x6A // R/W
#define MPU6050_PWR_Mgmt_1 0x6B // R/W
#define MPU6050_PWR_Mgmt_2 0x6C // R/W
#define MPU6050_FIFO_COUNTH 0x72 // R/W
#define MPU6050_FIFO_COUNTL 0x73 // R/W
#define MPU6050_FIFO_R_W 0x74 // R/W
#define MPU6050_WHO _AM_I 0x75 // R
//*********

//
//初始化 I2C 模块0
// TI 示例代码的轻微修改版本
void InitI2C0 (void){

//启用 I2C 模块0
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

//复位模块
SysCtlPeripheralReset (SYSCTL_Periph_I2C0);

//启用包含 I2C0的 GPIO 外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

//为端口 B2和 B3上的 I2C0功能配置引脚复用
GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinConfigure (GPIO_PB3_I2C0SDA);

//为这些引脚选择 I2C 功能
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);

//启用并初始化 I2C0主机模块。 使用的系统时钟
//I2C0模块。 最后一个参数设置 I2C 数据传输速率。
//如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为
//设置为400kbps
I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false);

//清除 I2C FIFO
HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000;

void I2CWrite (uint16_t device_address、uint16_t device_register、uint8_t device_data){
//指定我们希望通过目标写入总线来与器件地址通信
I2CMasterSlaveAddrSet (I2C0_BASE、DEVICE_ADDRESS、FALSE);

//要读取的寄存器
I2CMasterDataPut (I2C0_BASE、DEVICE_REGISTER);

//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

I2CMasterSlaveAddrSet (I2C0_BASE、DEVICE_ADDRESS、TRUE);

//指定要写入上述 device_register 的数据
I2CMasterDataPut (I2C0_BASE、DEVICE_DATA);

//在检查 MCU 以完成事务时等待
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_Receive_finish);

//等待 MCU 和器件完成事务
while (I2CMasterBusy (I2C0_BASE));

//此函数接收(或读取) I2C 总线上的数据。

//I2C_MASTER_CMD_BURST_Receive_Start/CONT/完成
//可用于修改函数以读取从器件上的多个寄存器(如果支持)。
//读取从器件上的指定寄存器
uint32_t I2CRead (uint32_t slave_addr、uint8_t reg){

//指定我们要向写入(寄存器地址)
//从器件
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//指定要读取的寄存器
I2CMasterDataPut (I2C0_BASE、reg);

//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);

void ConfiguraMPU (void){
I2CWrite (0x68、MPU6050_PWR_Mgmt_1、0x00);//无唤醒模式

I2CWrite (0x68、MPU6050_gyro_config、0x80);//gyro-eje X

I2CWrite (0x68、MPU6050_USER_CTRL、0x40);//是 FIFO

I2CWrite (0x68、MPU6050_FIFO_EN、0x41);//是 FIFO


I2CWrite (0x68、MPU6050_I2C_SLV0_ADDR、0xE8);
I2CWrite (0x68、MPU6050_I2C_SLV0_REG、MPU6050_GYRO_XOUT_H);
I2CWrite (0x68、MPU6050_I2C_SLV0_CTRL、0xA2);

//此函数用于延迟

//
/*临时临时配置器*
void retardo_SysTick (uint32_t tiempo){//Tiempo EN SEGUNDOS!!!
NVIC_ST_CTRL_R &=~NVIC_ST_CTRL_ENABLE;// SysTick 的可恢复能力
NVIC_ST_RELOAD_R =(NVIC_ST_RELOAD_R &~0xFFFFFF)|(16000000 / tiempo - 1);//cuenta 可编程
NVIC_ST_CURRENT_R =(NVIC_ST_CURRENT_R &~0xFFFFFF);// Renicia la cuenta actual
NVIC_ST_CTRL_R |= NVIC_ST_CTRL_ENABLE + NVIC_ST_CTRL_CLK_SRC;//可用性 el SysTick y la señal de reloj
while ((NVIC_ST_CTRL_R 和 NVIC_ST_CTRL_COUNT)==0);//retraso
}//fin retardo_SysTick

//这些函数配置 UART0

void ConfiguraUART0 (uint32_t velocidad){
uint16_t Divint;
uint8_t Divfrac;
SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA;
SYSCTL_RCGC1_R |= SYSCTL_RCGC1_UART0;
while (((SYSCTL_PRUART_R 和 SYSCTL_PRUART_R0)==0);
GPIO_PORta_AMSEL_R &=~Ω(0x03);
GPIO_Porta_DEN_R |= 0x03;
GPIO_PORta_AFSEL_R |= 0x03;
GPIO_Porta_PCTL_R =(GPIO_Porta_PCTL_R&0xFFFFFF00)|0x00000011;

UART0_CTL_R &=~UART_CTL_UARTEN;//恢复模型 UART0


Divint = 1000000/velocidad;
Divfrac = round ((1000000.00/velocidad - Divint)* 64);

//Fsysclk = 16MHz
UART0_IBRD_R =(UART0_IBRD_R 和0xFFFF0000)| Divint;
UART0_FBRD_R =(UART0_FBRD_R 和0xFFFFFFC0)| Divfrac;

// 8、N、1.
UART0_LCRH_R =(UART0_LCRH_R 和0xFFFFFF00)| 0x70;// 0 11 (1)* 0 0 0 (0)

UART0_CTL_R |= UART_CTL_UARTEN;//能力识别 UART0
}//fin 配置 UART0


//***** funciones para la Comunicacion *********

void txcar (uint32_t car){
while (((UART0_FR_R 和 UART_FR_TXFF)!=0);//esperamos que este LISTO
UART0_DR_R = CAR;
}//fin txcar

uint8_t rxcar (void){
uint8_t temp;
while (((UART0_FR_R 和 UART_FR_RXFE)!=0);//esperamos El Dato
TEMP= UART0_DR_R&0xFF;//8位
返回温度;
}//fin rxcar

void txmens (uint8_t mens[]){
uint8_t letra;
uint8_t i=0;
Tetra= mens[i++];
while (letra!='\0'){
txcar(letra);
Tetra= mens[i++];

}//fin txmens_uart0
//

//主函数

void main (void){
uint32_t GyroTotal = 0;
uint32_t GyroL = 5、GyroH = 5;


配置 UART0 (9600);
InitI2C0();
ConfiguraMPU();

while (1){


GyroL = I2CRead (0x68、MPU6050_EXT_SENS_DATA_00);
GyroH = I2CRead (0x68、MPU6050_EXT_SENS_DATA_01);

陀螺仪=(陀螺仪<< 8)+陀螺仪;

TXCAR(陀螺仪);
Retardo_SysTick (2);


}//FIN while (1)
}//FIN MAIN

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Hola Alejandro

    我们没有太多的工作可以让您满足您的截止日期... 也许、正如妈妈说的、您应该早开始...

    总之、这里有一些提示:

    -首先,如果您着急,请让他人更容易地提供帮助:当您发布代码时,请使用 "Rich Format"选项的按钮。 几乎不可能使用纯文本格式化来可视化程序结构。

    -第二、我没有看到引脚配置(可能是由于上述原因?) 您是否将 GPIO 配置为用作 I2C?

    -第三,当您尝试初始化传感器时,您将会发送一组数据,一组数据就会一个接一个地发送。 处理器比 I2C 总线快得多、在发送新命令之前、您需要等待先前的数据发送。

    -接下来、当您尝试使用 I2C 读取数据时、通常首先需要执行一些操作来"要求数据可用"、然后您需要发送另一个虚拟字节、以便传感器可以回复第一次传输的"问题"。 此外、从快速的角度来看、您的代码中似乎混合了从机和主机情况。。。

    太棒了!

    布鲁诺

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    只要(甚至) Bruno 在这里有点残忍("妈妈会说、你应该早点开始...")  (只有当她心情好的时候) 才可能利用(禁止的)"不工作 和 紧急"的招贴画,实际上保证这种职位将得到"没有反应?"

    此处没有任何原因/促成"错过截止日期!"     这里的所有人都认为他们的岗位值得(公平)的回应-很少有要求的"主管"(把其他人(提前到达)踢到路边!    (绝望不能作为被视为"不礼貌/期待"的理由。)

    试图掌握一个新的主题、并在压力大、"匆忙"的情况下做到这一点、并不以成功著称。   相反、对有限目标进行定期(最多几个小时)审核证明远远优于。    "回避"(此处有很多证据)有许多父亲-但他们的努力很小、重点突出-在截止日期之前-证明是一种(非常)有效的抗词。    (避免"新的或可怕的"-证明是非常常见的-实际上是一种"有模式(重复)的行为"、并且最常确保失败!)

    虽然现在的情况看起来很糟糕-如果你能从这个错误中"学习"-也许(一些)好处(下游)到达了...