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.

[参考译文] CCS/TM4C123GH6PM:如何将 GY-80的 I2C 与 TM4C123GH6PM 与 CCS v7相连

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/630665/ccs-tm4c123gh6pm-how-to-interfacing-i2c-of-gy-80-with-tm4c123gh6pm-with-ccs-v7

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

大家好、这是我第一次在这里写文章。

最近、我正在通过 Tivaware 读取 GY-80加速数据。

以下是我的问题。

问题1. 通过以下过程写入 ctrl 寄存器是否正常?

   I2CMasterDataPut (I2C0_BASE、0x2D);// ADX345的电源控制寄存器
   I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
   I2CMasterDataPut (I2C0_BASE、0x08);//将 Ctrl reg 写入 测量模式
   I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
问题2. 请查看下面的代码。
我只能看到"0 0 0\n 0 0\n 0 0 0..." 或"255 255 255 255 255 255 \n255 255 255 255 255 255..." 串行监视器上。
/*
* main.c
*/
/*----------------------------
GPIO_Pin PIN_FUNCTION 器件
PF4. GPIO SW1
PF0 GPIO SW2
PF1 GPIO RGB LED (红色)
PF2 GPIO RGB LED (蓝色)
PF3 GPIO RGB LED (绿色)
PC4. PWM SERVO0
PC5. PWM SERVO1
Pb7. PWM SERVO2
PD0 DOUT
PD1 DOUT
PD2 DOUT
PE1 DIN
PE2. DIN
PE3. DIN
PB2. I2C SCL
Pb3. I2C SDA
-------------------------------------------- */

//------------ 包括标头--- //
#include 
#include 
include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_i2c.h"
#include "driverlib/pin_driverlib-"driverlib-#-/driverh-#include

"driverlib-/driver.h"








///////---


定义宏------------------ //
#define SERVO0 0//PC4
#define SERVO1 1//PC5
#define SERVO2 2 //PB7
#define PD0
#define PD1
1 #define PD2
#define PE1 3
#define PE2 4
#define PE3 5
#define HIGH 0x01
#define LOW 0x0
#define ACCEL_SLAVE_ADDR_ADDR#define 0x32
#define CCEL_DATA
#define 0xCEL_CEM_E0x34 #define 0xCEM_CEM_CEM_32 #define 0xCEM_CEM_CEM_DATA #define #define

num_I2C_data 3
//../../--------------- ///////---


TivaWare 驱动程序初始化函数--- //
void sys_init ();
void clk_set ();
void GPIO_init ();
void PWM_init ();
void i2c_init ();
//---------------------------------------------- ///////---


用户界面函数------------------------------------------------------- //
void Servo_write (int server_N、int Duty_cycle);
void digitalWrite (int PIN_N、int State);
int32_t digitalRead (int PIN_N);
int8_t ReadAccel (uint8_t reg);
uint32_t I2CRead (uint32_t slave_addr、uint8_t reg);
void ConfigureUART (void);

//----- //

#ifdef debug
void
__error__(char *pcFilename、uint32_t ui32Line)
{
#endif


int main (void){

sys_init();
ConfigureUART();
uint8_t Ax、ay、az=32;
//int32_t temp=0;
UARTprintf ("开始 I2C 通信!\n");

while (1)
{
Ax = ReadAccel (ACCEL_X_DATA);
AY = ReadAccel (ACCEL_Y_DATA);
AZ = ReadAccel (ACCEL_Z_DATA);
UARTprintf ("%d %d %d\n"、Ax、AY、Az);

};

//return 0;
}

void sys_init()
{
clk_set();
GPIO_init();
PWM_init();
I2C_init();
}

void clk_set()
{
SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_main | SYSCTL_XTAL_16MHz);
}

void GPIO_init ()
{
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);

while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD));
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOE));

GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);
GPIOPinTypeGPIOInput (GPIO_Porte _BASE、GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
}

void PWM_init ()
{
//配置 PWM 时钟以匹配系统
SysCtlPWMClockSet (SYSCTL_PWMDIV_64);

//启用 PWM0外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
SysCtlPeripheralEnable (SYSCTL_Periph_PWM0);

//等待 PWM0模块准备就绪。
while (!SysCtlPeripheralReady (SYSCTL_Periph_PWM0));

//HWREG (GPIO_PORTF_BASE + GPIO_LO_LOCK)= GPIO_LOCK_KEY;
//HWREG (GPIO_PORTF_BASE + GPIO_O_CR)|= 0x01;

GPIOPinConfigure (GPIO_PB7_M0PWM1);
GPIOPinConfigure (GPIO_PC4_M0PWM6);
GPIOPinConfigure (GPIO_PC5_M0PWM7);
GPIOPinTypePWM (GPIO_PORTB_BASE、GPIO_PIN_7);
GPIOPinTypePWM (GPIO_PORTC_BASE、GPIO_PIN_4 | GPIO_PIN_5);
//GPIOPinTypePWM (GPIO_PORTC_BASE、GPIO_PIN_5);
//将 PWM 发生器配置为带有立即数的递减模式
//更新参数。
PWMGenConfigure (PWM0_BASE、PWM_GEN_0、PWM_GEN_MODE_DOWN|PWM_GEN_MODE_NO_SYNC);
PWMGenConfigure (PWM0_BASE、PWM_GEN_3、PWM_GEN_MODE_DOWN|PWM_GEN_MODE_NO_SYNC);

//这些设置是专为运行伺服电机而设计的
//预计在1ms 到2ms 的高电平时间内有20ms 的周期

// PWM 分频器为64时、系统时钟为16MHz
// 16000000/64 = 250000/50 = 5000 ### 1S/50 = 20ms、这是除数的来源

//将高电平时间设置为2ms
PWMGenPeriodSet (PWM0_BASE、PWM_GEN_0、5000);
PWMGenPeriodSet (PWM0_BASE、PWM_GEN_3、5000);

//将 PWM1的脉冲宽度设置为10%占空比。
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_1、500);//PB7 M0PWM1

//将 PWM6的脉冲宽度设置为10%占空比。
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_6、500);//PC4 M0PWM6

//将 PWM7的脉冲宽度设置为20%占空比。
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_7、1000);//PC5 M0PWM7

//启动发生器3中的计时器。
PWMGenEnable (PWM0_BASE、PWM_GEN_0);
PWMGenEnable (PWM0_BASE、PWM_GEN_3);

//启用输出。
PWMOutputState (PWM0_BASE、(PWM_OUT_1_BIT | PWM_OUT_6_BIT | PWM_OUT_7_BIT)、true);

//数据表
//Table 20-1。 PWM 信号(64LQFP)--> PWM 模块,发生器,引脚编号
}

void i2c_init()
{

//启用 I2C0外设
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

//等待 I2C0模块准备就绪。
while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C0));

//复位模块
SysCtlPeripheralReset (SYSCTL_Periph_I2C0);
//GPIO 端口 B 需要启用、以便可以使用这些引脚。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

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

//将引脚配置为 I2C 外设使用的 SDA。GPIO_PB3_I2C0SDA
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
//将引脚配置为 I2C 外设的 SCL。GPIO_PB2_I2C0SCL
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);

//不知道如何使用--jw
I2CMasterEnable (I2C0_BASE);

//初始化主从设备
//它将设置总线速度并启用主机模块。
I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、true);

//I2CSlaveEnable (I2C0_BASE);
//I2CSlaveInit (I2C0_BASE、ACCEL_SLAVE_ADDR);

//指定从机地址
//第一个数据,定义主发送或接收
// true ->主器件正在从从器件发起读取
// false -> addr 表示 I2C 主设备正在向从设备发起写入操作。
I2CMasterSlaveAddrSet (I2C0_BASE、ACCEL_SLAVE_ADDR、false);/0x3B

//将功率寄存器设置为测量模式
I2CMasterDataPut (I2C0_BASE、0x2D);
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
I2CMasterDataPut (I2C0_BASE、0x08);
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);

//将数据格式寄存器设置为全分辨率
I2CMasterDataPut (I2C0_BASE、0x31);
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
I2CMasterDataPut (I2C0_BASE、0x08);
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);



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

}

void ConfigureUART (void)
{

//启用 UART 使用的 GPIO 外设。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);


//启用 UART0
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);


//为 UART 模式配置 GPIO 引脚。
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

//使用内部16MHz 振荡器作为 UART 时钟源。
UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);

//初始化控制台 I/O 的 UART
UARTStdioConfig (0、115200、16000000);
}

void Servo_write (int server_N、int Duty_cycle)
{
// 0~180 -->占空比:3%~12%(在 Arduino 中)
Duty_cycle = 150+(Duty_cycle*2.5);//将整数转换为度数

开关(SERVO_N)
{
案例0://PC4
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_6、Duty_cycle);//PC4 M0PWM6
中断;
案例1://PC5
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_7、Duty_cycle);//PC5 M0PWM6
中断;
案例2://PB7
PWMPulseWidthSet (PWM0_BASE、PWM_OUT_1、Duty_cycle);//PB7 M0PWM1
中断;
默认值:
中断;
}
}

void digitalWrite (int PIN_N、int State)//테스트 필요
{
开关(PIN_N)
{
情况0:
if (状态=低电平)
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_0、0x0);
其他
GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_0、GPIO_PIN_0);
中断;
案例1:
if (状态=低电平)
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_1、0x0);
其他
GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_1、GPIO_PIN_1);
中断;
案例2:
if (状态=低电平)
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_2、0x0);
其他
GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_2、GPIO_PIN_2);
中断;
默认值:
中断;
}
}

int32_t digitalRead (int PIN_N)
{
开关(PIN_N)
{
案例3://PE1
返回 GPIOPinRead (GPIO_Porte _BASE、GPIO_PIN_1);
案例4:
返回 GPIOPinRead (GPIO_Porte _BASE、GPIO_PIN_2);
情况5:
返回 GPIOPinRead (GPIO_Porte _BASE、GPIO_PIN_3);
默认值:
返回0;
}
}

int8_t ReadAccel (uint8_t reg)//读取加速数据
{
uint8_t accelData = I2CRead (ACCEL_SLAVE_ADDR、reg);

返回 accelData;
}

uint32_t I2CRead (uint32_t slave_addr、uint8_t reg)//进行测试。 正在接收传感器数据
{

I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

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

//将 ctrl 字节和 reg addr 字节发送到从设备
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);

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

I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);

//等待
while (I2CMasterBusy (I2C0_BASE));

//数据返回
返回 I2CMasterDataGet (I2C0_BASE);

} 

对于 I2CRead 用户函数、我之前也尝试过这种方法。
/*试用版1

//I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_Receive);

//等待
//while (I2CMasterBusy (I2C0_BASE));

I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);

//等待
//while (I2CMasterBusy (I2C0_BASE));

//数据返回
返回 I2CMasterDataGet (I2C0_BASE);
*/





/*试用2
*

/0926.
uint32_t pui32DataTx[NUM_I2C_DATA];
uint32_t pui32DataRx[NUM_I2C_DATA];
uint32_t ui32Index;

I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);
//I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
//while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_TREQ))
//{
//}
//初始化接收缓冲区。
//
for (ui32Index = 0;ui32Index < NUM_I2C_DATA;ui32Index++)
{
pui32DataRx[ui32Index]= 0;
}+

I2CSlaveDataPut (I2C0_BASE、pui32DataTx[ui32Index]);
// I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
// while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_TREQ))/
{//
}
pui32DataRx[ui32Index]= I2CMasterDataGet (I2C0_BASE);

返回 pui32DataRx[ui32Index];

//重置接收缓冲区。
//for (ui32Index = 0;ui32Index < NUM_I2C_DATA;ui32Index++)
//{
// pui32DataRx[ui32Index]= 0;
//}

*
*
*// 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ryu、
    请确认 SCL 和 SDA 总线上是否有合适的上拉电阻器。 另请参阅 www.ti.com/.../spma073.pdf 上的 I2C 应用手册 、其中包含一些 I2C 示例供您参考。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、我们祝贺您:

    • 创建清晰且沟通的"主题行"-将读者"吸引到您的帖子中。  (与无定义的"TM4Cxyx:TM4Cxyz"不同-最近论坛降级的副产品)
    • 以首选的"Syntax Highlighter"方式演示您的代码

    最常见的建议是、"掌握"您刚刚接触到"的 MCU 外设最好通过"kiss"(使用最简单、最具体(重点最突出)和受监控的技术!)来实现!   您选择的外部 I2C 器件的"复杂性"明显违反了 kiss!   (您的外部设备太复杂、无法用作"起点"-大多数情况下都"让您觉得麻烦"-因此、您在这里的入住"如预期!"

    而是通过使用基于 I2C 的小容量 EEPROM 来"加速、优化、增强"对 I2C 的掌握!   这样的小型 EEPROM 价格低廉、而且在您目前的环境中"一定要查看使用情况"、并且可能也适用于您未来的大多数项目。   由于"缺乏(不必要)复杂性"、您的理解将会迅速增长、您的"斗争"将大大减少!   这是理想的-不是吗?

    相反-"(甚至)现在可以从何处开始分析您的困境(失败)?"   也请注意、熟练的供应商代理"Charles"将(他)诊断局限于"外部上拉电阻器"-他也知道、"不是从哪里开始!"   (如您违反 KISS 的行为所示、"未知因素太多"、无法形成逻辑、系统的诊断!)

    供应商(如此奇怪/错误)拒绝"推销亲吻"是直接造成的、"如此多-就像您一样"-每天都来这里-(不必要的)"无法解决的问题"-是由于缺乏(适当的)海报指导而引起的!   (即"kiss"-练习@ MIT、Cal Tech、UW-Madison、UA-Huntsville (最后2个 NASA 认证 学校)-但(显然)"在这里被禁止"-没有解释...)

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

    但是、恐怕我之前已经尝试过上拉电阻器。

    是否存在任何代码错误?

    再次感谢您、Ryu
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ryu、
    当您之前说过您曾尝试过上拉电阻器时、您"现在"还是已经移除了这些电阻器? 您必须具有上拉电阻器。 请在 I2CMasterControl()后面添加以下行,如下所示。 您的运行速度也是400kps。 我建议您从100kps 之类的较低速度开始。 一旦一切正常、您可以提高 I2C 速度。 使用范围查看总线活动。 您是否从外部从器件获得了预期的 ACK?

    I2CMasterDataPut (I2C0_BASE、0x2D);// ADX345的电源控制寄存器
    I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (I2C0_BASE));
    I2CMasterDataPut (I2C0_BASE、0x08);//将 Ctrl reg 写入测量模式
    I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
    while (I2CMasterBusy (I2C0_BASE));
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们是否可以注意到以下几点:

    • 海报的代码消耗了371行和62行
    • 未经说明的是具有 I2C 的"经验水平"
    • 何时必须建议用户"使用范围进行探测"-这是否能确保"探测者"了解(并利用)捕获的结果?
    • 目标器件非常复杂、需要更复杂的"启动和重新启动 I2C 序列"

    只有条建议是"简化-从更基本的器件开始-以便"以更轻松、更舒适和更可控的方式理解构建!"

    高级大学课程-最常-要求在"进入更具挑战性的课程"之前圆满完成"先决条件"课程!   这是"被踢到路边"的-这是有道理的-以及(如何)它是"最好的服务"这张海报的?

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

    尊敬的 Charles:

    是的、我是说我已经设置了上拉电阻器。 根据您的建议、我尝试设置100kps、并且每个都有4.7K 欧姆电阻器。

    Q1……但我不确定我是否设置了速度。 我该怎么做?

    我通过设置100kbps

    I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、flase);



    我按照您的建议修改了我的代码。

    但是、我无法成功使用 I2CMasterDataPut API 函数。

    如果您有时间、请查看我的上一个回复。


    非常感谢您、

    仅在我的国家研究中、我确实很难。

    我不知道如何感谢您。



    Ryu

    *随附*  

    我调试了许多断点、

    我发现 I2CMasterDataPut API 函数未显示任何脉冲。

    我只能看到 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);线路脉冲。

    详细信息为上部回复。 谢谢你