主题中讨论的其他器件:TM4C1294NCPDT、 ADS7142、
您好!
我已随附 TM4C1294NCPDT 数据表以参考以下问题以及 ADS7142数据表。 以下代码应仅将 ADS7142置于手动模式扫描 CH0。 然而、单步执行 Code Composer Studio 中的代码显示、主 MCU 由于任何原因而丢失 i2c 总线仲裁。 此错误在单主系统中似乎没有意义、但它是错误、因为我在代码中的错误检查例程是调试器被卡住的地方。
第1291-1293页上是我用来开发 main 中调用的三个函数的主 Tx/Rx 软件流程图。 代码卡在 ADS7142SingleRegisterWrite()的第一次调用中。
感谢您对这个问题的任何见解
e2e.ti.com/.../4214.tm4c1294ncpdt.pdf
e2e.ti.com/.../5736.ads7142.pdf
// // //// ADS7142_ManualMode_CH0Scan.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/pin_map.h" #include "driverlib/i2c.h" #include "driverlib/i2c.c" #include "driverlib/pin_map.h" #include "driverlib/uarticl" // //! \addtogroup i2c_examples_list //! //! //! 此示例展示了如何配置 I2C8模块以进行连接/通信 //! 与 ADS7142 BoosterPack 配合使用。 //! 这包括设置主模块和从模块。 回送模式 //! 在内部将主从数据线和时钟线连接在一起。 此示例 //! 不使用环回模式是指正在与外部器件进行通信 //! 连接到 TM4C1294NCPDT 微控制器。 //! 设置从机模块的地址、以便从 //! 主器件。 然后检查数据以确保接收到的数据与 //! 传输的数据。 此示例使用//的轮询方法 ! 发送和接收数据。 //! //! 此示例使用以下外设和 I/O 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - I2C8外设 //! - GPIO 端口 A 外设(用于 I2C8引脚) //! - I2C8SCL - PA2 //! - I2C8SDA - PA3 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! -无。 //// ***************** // // //设置从机模块的地址。 这是以 //以下格式发送的7位地址: //[A6:A5:A4:A3:A2:A1:A0:RS] // 第一个字节的"RS"位置为零意味着主 设备//将数据发送到所选的从设备,而在该位置的一 个//意味着主设备将接收来自从设备的数据。 本示例中 ADS7142的从地址//由 ADS7142boostxl // //////上的硬件设置 #define SLAVE_ADDRESS 0x18 void ADS7142SingleRegisterWrite (uint8_t RegisterAddress、uint8_t RegisterData) { //ADS7142单寄存器写入 // ////告知主模块在 //与从器件通信时将在总线上放置什么地址。 将地址设置为 SLAVE_ADDRESS //(在从机模块中设置)。 接收参数设置为 false //表示 I2C 主机正在向从机发起写入操作。 如果 // true、则表示 I2C 主设备正在从 //从设备开始读取。 // I2CMasterSlaveAddrSet (I2C8_BASE、SLAVE_ADDRESS、false); //将要发送的第一个字节放置到 TM4C1294的 I2CMDR 寄存器 中//从地址之后要发送的第一个字节是单寄存器写入操作码 I2CMasterDataPut (I2C8_BASE、SINGLE_WRITE); //检查 I2C 总线以确保它 在(I2CMasterBusy (I2C8_BASE)时不忙 ){ //读取 I2CMCS } // I2C 主命令开始突发发送3个字节 I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_START); //实现延迟 (SysCtl100); //在移动到下一个字节 之前等待 I2CMaster 完成传输,同时(I2CMasterBusy (I2C8_BASE) ){ //读取 I2CMCS } //检查 I2C8模块中的错误 ,同时(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_NOE) //错误分支指令 (I2CMaster_ERROR = I2CMaster_ERROR = I2CMaster_ERROR)/I2CMaster_ERROR = I2CMaster_ERROR (I2CMaster_BASE) { //错误服务 } //为接收错误停止写入 I2C 主命令 (如果(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_ARB_Lost) { I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_RIVE_ERROR_STOP); //实施延迟 SysCtlDelay (I2C8_BASE) ;}将所需的数据写入 I2CSR_CMDBASE (I2DRESS)/ I2C8地址/ I2PR_PRISTER;//将数据写入所需的下一个数据写入 I2C8地址/ I2C8寄存器 针对下一个字节 I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_CONT)持续突发发送的/I2C 主命令; //实现延迟 SysCtlDelay (100); //在移动到下一个字节 之前等待 I2CMaster 完成传输,while (I2CMasterBusy (I2C8_BASE)) { //读取 I2CMCS } //检查 I2C8模块中的错误 while (I2CMasterErr (I2C8_BASE)) //错误分支 { //检查丢失的错误条件 if (I2CMaster_Err (I2C8_BASE)= I2CMERR_I2CMaster_I2ARC) { //错误服务 } //为接收错误停止写入 I2C 主命令 (如果(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_ARB_Lost) { I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_RIVE_ERROR_STOP); //实施延迟 SysCtlDelay (I2CMasterControl)(将 数据放在所需的寄存器中)/ I2CI2CI_100字节 (PRB);将数据放在所需的最后一个数据寄存器中;// I2OBJESD20_CMD_RE_I2C8数据寄存器中 // I2C 主机命令用于完成数据的突发发送 I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_FIND); //实现延迟 SysDelay (100); //等待 I2C 主机完成发送 while (I2CMasterBusy (I2C8_BASE))) }{ //读取 I2CMCS_I2ACT_RegisterError ( while)/I2CM2CM4u.08/I2CM4u.0152CM4u.072R (while) { //ADS7142单寄存 器读取////告知主模块在//与从器件通信时它将在总线上放置什么地址。 将地址设置为 SLAVE_ADDRESS //(在从机模块中设置)。 接收参数设置为 false //表示 I2C 主机正在向从机发起写入操作。 //要执行寄存器读取、主器件必须首先发送所需的从器件地址进行通信。 //在从机地址之后,将发送单个寄存器读取操作码。 //如果为 true,则表示 I2C 主设备正在启动对 //从设备的读取。 // // I2CMasterSlaveAddrSet (I2C8_BASE、SLAVE_ADDRESS、FALSE); //将单个寄存器读取操作码放入 I2CMMDR 寄存器 I2CMasterDataPut (I2C8_BASE、SINGLE_READ); //检查 I2C 总线以确保其 在(I2CMMCS Busy)(I2CMaster82Q8_BASE 、SIDRY)时不忙;//启动 I2C8_I2C 总线;// I2C8_PRIM_PRIM_START (I2CI_START) //等待 I2C 主设备完成传输 while (I2CMasterBusy (I2C8_BASE)) { //读取 I2C8模 块中的错误 while (I2CMC8 Err (I2C8_BASE)) //错误分支 { //检查任意丢失错误条件 if (I2CMC8_Err_I2C_MASTER)= I2CMaster_I2C_Lost { //错误服务 } //为接收错误停止写入 I2C 主命令 (如果(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_ARB_Lost) { I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_RIVE_ERROR_STOP); //实现延迟 SysCtlDelay (I2CMasterControl); } /将 I2C8_BASE (I2PR_CMD_READ)发送到寄存器中;// I2C8地址寄存器/ I2PR_CMD_REGISTER0 (以发送到寄存器中);// I2C8 针对寄存器读取 I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_SEND_FIND)所需的两个字节的完成突发发送的/I2C 主命令; //实现延迟 SysCtlDelay (100); //等待 I2C 主机完成数据传输 while (I2CMasterBusy (I2C8_BASE) ){ //读取 I2C8 模块中的错误标志 while (I2CMC8 Err (I2C8_BASE)) }// 将接收参数设置为 true 以便从 I2CMasterSet (I2C8_BASE)接收数据;//从 I2CMaster2SlaveSet (I2C8_IsrasterPack)地址) //检查 I2C 总线以确保它 在(I2CMasterBusy (I2C8_BASE)时不忙 ){ //读取 I2CMCS } //从寄存器地址 I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_SINGLE_Receive)接收的单个字节的 I2C 主命令; //实现 SysCtlDelay Delay (100); //等待 I2C 主机完成数据传输 while (I2CMasterBusy (I2C8_BASE) ){ //读取 I2CMCS } //检查 I2C8模块 while (I2CMC8 Err (I2C8_BASE))中的错误标志 { //错误服务 } //从 ADS2CMDR_I2CIR 寄存 器中获取数据 void StartSampling () { //提供器件地址和读取位以开始转换 I2CMasterSlaveAddrSet (I2C8_BASE、SLAVE_ADDRESS、TRUE); //检查 I2C 总线以确保其 在(I2CMasterBusy (I2C8_BASE))期间不处于繁忙状态; { //读取 I2CMCS SysCls } //将 I2C 总线写入 I2CMasterStart (I2CM2CM_I2C 控制主机 / I2C 主机);I2CM2CMaster_I2C 控制(I2CM100_I2C 主机/主机突发) { //读取 I2CMCS } //允许主机完成接收第一个字节 while (I2CMasterBusy (I2C8_BASE)) { //读取 I2CARB } //检查 I2C8模块中的错误 while (I2CMasterErr (I2C8_BASE)) //错误分支 { //检查主机中断条件 = I2CMERR (I2CMasterr)= I2CMasterr_ERROR (I2CM_base) { //错误服务 } //为接收错误停止写入 I2C 主命令 (如果(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_ARB_Lost) { I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_RST_ERROR_STOP); //实施延迟 SysCtlDelay (I2C8_BASE ) ; }/ I2CMD20_CMD/ I2C8_PR_PRIM_PRIM_PRIM_PRIMART/STER_STER_PRIMARY (CONT_PRIMARY);//接收数据时、2 (I2CI_PRIM_PRIM_PRIM_PRIM_PRIM_PRIM_PRIM_PRIMART/ I2CI_PRIM_PRIMART/ I2CI_COMMAND);// { //读取 I2CMCS } //允许主设备完成接收每个字节 while (I2CMasterBusy (I2C8_BASE)) { //读取 I2CMCS } //检查 I2C8模块中的错误 while (I2CMARTE Err (I2C8_BASE)!= I2C_MASTER_ERR_NOE) //错误检查 I2CMART_ERROR (I2CMART_MASTER)= I2CMRITE_ERROR (I2C8_ERROR = I2CI_ERROR = I2CMSTRAST_ERROR) { //错误服务 } //为接收错误停止写入 I2C 主命令 (如果(I2CMasterErr (I2C8_BASE)!= I2C_MASTER_ERR_ARB_Lost) { I2CMasterControl (I2C8_BASE、I2C_MASTER_CMD_BURST_RIVE_ERROR_STOP); //实施延迟 SysCtlDelay (100)); } 错误服务 * // //配置 I2C8主站和从站并将它们连接到 ADS7142 BoosterPack // ********* int main (void) { #if defined (target_is_TM4C129_RA0)||\ defined (target_is_TM4C129_RA1)||\ defined (target_is_TM4C129_RA2) uint32_t ui32SysClock; #endif // //将计时设置为直接从外部振荡器/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_值以匹配 电路板上//晶体的值。 // #if defined (target_IS_TM4C129_RA0)||\ defined (target_IS_TM4C129_RA1)||\ defined (target_IS_TM4C129_RA2) ui32SysClock = SysCtlCockFreqSet ((SYSCTL_XTAL_25MHz)| SYSC_SYSC_UST_SYSC_UST_SYSC_UST_SYSC_UST_SYSC_USTR_USTRL | #SYSC_UST_SYSC_UST_SYSC_UST_SYSC_UST_SYSC_UST_SYSC_USTR_USTRIP_USTRIP_USTRIP_USTRIP_USTRIP_USTR_USTRIP_USTRIP_USTRIP_USTRIP_SYSC_USTRIP_SYSC_SYSC/#SYSC/ // SysCtlPeripheralEnable (SYSCTL_Periph_I2C8); // 对于此示例,I2C8与 PORta[3:2]一起使用。 实际使用的端口和//引脚在您的器件上可能不同、有关 //更多信息、请参阅数据表。 需要启用 GPIO 端口 A、以便可以 //使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // 为端口 A2和 A3上的 I2C8功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PA2_I2C8SCL); GPIOPinConfigure (GPIO_PA3_I2C8SDA); // 为这些引脚选择 I2C 功能。 此函数还将 //为 I2C 操作配置 GPIO 引脚、将它们设置为 //使用弱上拉操作进行开漏操作。 请参阅数据表 //以查看每个引脚分配了哪些功能。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinTypeI2CSCL (GPIO_Porta_base、GPIO_PIN_2); GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_3); // 启用主中断。 此函数将启用 所有可用于 I2C 主设备的中断//。 // I2CMasterIntEnable (I2C8_BASE); // I2CSlaveIntEnable (I2C8_BASE); #if defined (TARGET_IS_TM4C129_RA0)||\ defined (TARGET_IS_TM4C129_RA1)||\ defined (TARGET_TM4C129_RA2)| SysClaterClock (I2C8_RA2)、SysClitC12_RA2 ) false); #endif //让我们将器件置于具有单通道单端配置的手动模式 //用于数据转换 //选择通道输入配置 ADS7142SingleSingerWrite (ADS7142_REG_CHANNE_CFG、ADS7142_VAL_CHANNEL_CFG_INPUT_CFG_1_CHANNEL_CONST_END_BENDENT);ADS7142_OPANE_RE_MOREG_OPALE_CONFILE_MORE_MORE_142_MORE_MORE_MODE_MODE_MODE_OPALE_OPALE_OPANE_MORE_MORE_MORE_MORE_MORE_MOREGLE_MOREGLE_MODE_MODE_MODE_MODE_MODE_MODE_OPANE_OPALE_OPANE_MOREG/ ADS7142_OPALE_OPALE_OPALE_OPALE_OPALE_OPANE_MORE_MORE_MOREG/ ADS7142_MOREG //开始手动模式操作 //开始扫描 Ch0 StartSampling(); return (0); }
