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:I2C 环回示例不起作用

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/572630/tm4c123gh6pm-i2c-loopback-example-is-not-working

器件型号:TM4C123GH6PM

我已经尝试过 TivaWare 提供的 I2C 回写示例。 但它不起作用。 它在 调试字符串的串行传输过程中停止。 我已连接输出屏幕。  

我在 Windows 10上使用的是具有 CCS 7.0的 TivaWare 2.1.156  

//
//
//// master_slave_loopback.c -演示简单 I2C 消息的示例
// 传输和接收。
//
//版权所有(c) 2010-2016 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
以源代码和二进制形式重新分发和使用,无论是否
进行//修改,只要
满足以下条件//:
//
重新分发源代码必须保留上述版权
//声明、此条件列表和以下免责声明。
//
//二进制形式的再发行必须复制上述版权
//声明、此条件列表和//

分发随附的//文档和/或其他材料中的以下免责声明。
////
未经

事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
////
本软件由版权所有者和贡献者提供
//“按原样”,不

承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
//所有者或贡献者都不对任何直接、间接、偶然、
//特殊、模范、 或相应的损害(包括但不
限于采购替代产品或服务;丧失使用、
//数据或利润; 或业务中断)、无论

出于何种原因使用
本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
//
//这是 Tiva 固件开发包版本2.1.3.156的一部分。
////
*****************

#include 
#include 
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctio.uarth"
#include "UART"



//
//! \addtogroup i2c_examples_list
//! 

I2C 主设备环回(i2c_master_slave_loopback)

//! //! 此示例说明了如何将 I2C0模块配置为环回模式。 //! 这包括设置主模块和从模块。 回送模式 //! 在内部将主从数据线和时钟线连接在一起。 //! 设置从机模块的地址、以便从 //! 主器件。 然后检查数据以确保接收到的数据与 //! 传输的数据。 此示例使用//的轮询方法 ! 发送和接收数据。 //! //! 此示例使用以下外设和 I/O 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - I2C0外设 //! - GPIO 端口 B 外设(用于 I2C0引脚) //! - I2C0SCL - PB2 //! - I2C0SDA - PB3 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 I2C 操作不需要这些。 //! - UART0外设 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! -无。 //// ***************** // // //要发送的 I2C 数据包数量。 //// ***************** #define NUM_I2C_DATA 3 //********* // //设置从机模块的地址。 这是以 //以下格式发送的7位地址: // [A6:A5:A4:A3:A2:A1:A0:RS] // 第一个字节的"RS"位置为零表示主 设备//向所选的从设备发送(发送)数据,而在该位置为1 表示主设备从设备接收数据。 //// ***************** #define SLAVE_ADDRESS 0x3C //********* // //此函数将 UART0设置为用于控制台,以便 在示例运行时显示信息//。 //// ***************** void InitConsole (void) { // //启用用于 UART0引脚的 GPIO 端口 A。 // TODO:将其更改为您正在使用的 GPIO 端口。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // //为端口 A0和 A1上的 UART0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); // //启用 UART0以便我们可以配置时钟。 // SysCtlPeripheralEnable (SYSCTL_Periph_UART0); // //使用内部16MHz 振荡器作为 UART 时钟源。 // UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); // //为这些引脚选择替代(UART)功能。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); // //初始化控制台 I/O 的 UART // UARTStdioConfig (0、115200、16000000); } //********* // //配置 I2C0主机和从机,并使用环回模式连接它们。 //// ***************** int main (void) { #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) uint32_t ui32SysClock; #endif uint32_t pui32DataTx[NUM_I2C_DATA]; uint32_t pui32DataRx[NUM_I2C_DATA]; uint32_t ui32Index; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 板上的//晶体。 // #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_OSC)、25000000); #else SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz); #endif // //使用前必须启用 I2C0外设。 // SysCtlPeripheralEnable (SYSCTL_Periph_I2C0); // //对于本示例,I2C0与 PortB[3:2]一起使用。 实际端口和 //使用的引脚可能与您的器件不同、请参阅的数据表 //更多信息。 GPIO 端口 B 需要启用、因此这些引脚可以 //使用。 // TODO:将其更改为您正在使用的 GPIO 端口。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB); // //为端口 B2和 B3上的 I2C0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PB2_I2C0SCL); GPIOPinConfigure (GPIO_PB3_I2C0SDA); // //为这些引脚选择 I2C 功能。 此函数也会 //为 I2C 操作配置 GPIO 引脚,将其设置为 //开漏操作,弱上拉。 请参阅数据表 //查看每个引脚分配了哪些功能。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2); GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3); // //启用环回模式。 环回模式是一个内置的特性 //可用于调试 I2C 操作。 它在内部连接 I2C //主机和从机终端,这可以有效地让您按发送数据 //主设备并作为从设备接收数据。 //注意:对于外部 I2C 操作,您需要使用外部上拉电阻 //比内部上拉电阻器强。 请参阅的数据表 //更多信息。 // I2CLoopbackEnable (I2C0_BASE); // //启用和初始化 I2C0主机模块。 使用的系统时钟 // I2C0模块。 最后一个参数设置 I2C 数据传输速率。 //如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为 //设置为400kbps。 在本示例中、我们将使用100kbps 的数据速率。 // #if defined (target_IS_TM4C129_RA0)|| \ 已定义(TARGET_IS_TM4C129_RA1)|| \ 已定义(TARGET_IS_TM4C129_RA2) I2CMasterInitExpClk (I2C0_BASE、ui32SysClock、false); #else I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false); #endif // //启用 I2C0从机模块。 此模块仅用于测试 //目的。 无需启用它即可正常运行 // I2Cx 主机模块。 // I2CSlaveEnable (I2C0_BASE); // //将从地址设置为 SLAVE_ADDRESS。 在回送模式下、它是一个 //发送到的任意7位数(在上面的宏中设置) // I2CMasterSlaveAddrSet 函数。 // I2CSlaveInit (I2C0_BASE、SLAVE_ADDRESS); // //告诉主模块何时将在总线上放置什么地址 //与从设备通信。 将地址设置为 SLAVE_ADDRESS //(在从机模块中设置)。 接收参数设置为 false //表示 I2C 主设备正在向从设备发起写入操作。 如果 // true、这表示 I2C 主设备正在启动读取 //从器件。 // I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_ADDRESS、FALSE); // //设置用于显示消息的串行控制台。 这是 //仅用于此示例程序,I2C 操作不需要。 // InitConsole(); // //在控制台上显示示例设置。 // UARTprintf ("I2C 环回示例->"); UARTprintf ("\n 模块= I2C0"); UARTprintf ("\n 模式=单次发送/接收"); UARTprintf ("\n 速率= 100kbps\n"); // //初始化要发送的数据。 // pui32DataTx[0]='I'; pui32DataTx[1]='2'; pui32DataTx[2]="C"; // //初始化接收缓冲区。 // for (ui32Index = 0;ui32Index < NUM_I2C_DATA;ui32Index++) { pui32DataRx[ui32Index]= 0; } // //指示数据的方向。 // UARTprintf ("来自主设备的转环->从设备\n"); // //从主设备向从设备发送3个 I2C 数据表。 // for (ui32Index = 0;ui32Index < NUM_I2C_DATA;ui32Index++) { // //显示 I2C0主机正在传输的数据。 // UARTprintf ("正在发送:'%c'。 。 。 "、pui32DataTx[ui32Index]); // //将要发送的数据放在数据寄存器中 // I2CMasterDataPut (I2C0_BASE、pui32DataTx[ui32Index]); // //开始从主器件发送数据。 自回送起 //模式被启用、主控和受控单元被连接 //允许我们接收我们发送的相同数据。 // I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND); // //等待从机接收并确认数据。 // while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_RREQ)) { } // //从从从器件读取数据。 // pui32DataRx[ui32Index]= I2CSlaveDataGet (I2C0_BASE); // //等待主机模块完成传输。 // while (I2CMasterBusy (I2C0_BASE)) { } // //显示从机已接收到的数据。 // UARTprintf ("已接收:'%c'\n"、pui32DataRx[ui32Index]); } // //重置接收缓冲区。 // for (ui32Index = 0;ui32Index < NUM_I2C_DATA;ui32Index++) { pui32DataRx[ui32Index]= 0; } // //指示数据的方向。 // UARTprintf ("\n\n"从从属设备->主设备进行转接来电"); // //将数据方向修改为 true,以便查看地址 //表示 I2C 主设备正在从设备发起读取。 // I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_ADDRESS、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++) { // //显示 I2C0从机模块正在传输的数据。 // UARTprintf ("正在发送:'%c'。 。 。 "、pui32DataTx[ui32Index]); // //将要发送的数据放在数据寄存器中 // 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); // //显示从机已接收到的数据。 // UARTprintf ("已接收:'%c'\n"、pui32DataRx[ui32Index]); } // //告诉用户测试已完成。 // UARTprintf ("\nDone.\n\n"); // //返回无错误 // 返回(0); }

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

    您好!

     我刚才使用您的代码运行了示例、没有问题。 下面是 CCS 内的终端输出。 让我们确保问题与 COM 端口设置无关。 请尝试另一个终端仿真、如 hyperteminal 或只是 CCS 中的仿真。 下面是 CCS 终端的屏幕截图。 请查看右下角。 要显示终端,请转至 View->Other->Terminal->Terminal。 确保您具有正确的 COM 端口设置。 请参阅我的 COM 端口屏幕截图。 您的 COM 端口号将与我的不同。