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.

[参考译文] 编译器/TM4C123GH6PZ:两个 Tiva 板之间的 I2C 突发数据来回通信出现问题

Guru**** 2614265 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/774126/compiler-tm4c123gh6pz-issue-with-i2c-burst-data-back-and-forth-communication-between-two-tiva-board

器件型号:TM4C123GH6PZ

工具/软件:TI C/C++编译器

您好、先生、

 我在使用 I2C 在两个 Tiva 板之间进行通信时遇到了一些问题。 我要做的是、来回发送一些从一个 Tiva 板(主器件)到另一个 Tiva 板(从器件)的突发数据。 主器件将发送一些突发数据、而从器件将读取数据并将其发送回主器件、并使用 UART 进行显示。

我要在下面附加主设备和从设备代码。

主代码

#include "stdio.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/pin_map.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/SysTick .h"
#include "driverlib/timer.h"
#include "inc/hw_NVIC.h"
#include "driverlib/timer.c"
#include "driverlib/SysTick .c"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "inc/hw_ints.h"
#include "driverlib/ssi.h"
#include "driverlib/i2c.h"
空延迟(int a);
volatile uint32_t count=0;//计数器来计算已调用的中断数量

#define SLAVE_ADDRESS 0x20

//void InitConsole (void);
unsigned long k=0;
int I2C_SEND_char (void);
void I2C_RECV_char (void);
void InitConsole (void);
uint32_t data_read;
uint32_t n=3、i;
  int main()
  {
  
 // char char_tx[]="abcd"、data;
  
  SysCtlClockSet (SYSCTL_SYSDIV_1_SYSCTL_USE_OSC |SYSCTAL_XTAL_8MHZ|SYSCTL_OSC_MAIN);//将系统时钟设置为8MHz
  //void InitConsole (void);
  //启用 I2C0外设
  //
  SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);
  while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C0));
  SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
  while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB));
  //配置多路复用和 GPIO 设置、将 SSI 功能输出到引脚
  GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
  GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
  GPIOPinConfigure (GPIO_PB2_I2C0SCL);
  GPIOPinConfigure (GPIO_PB3_I2C0SDA);
  I2CMasterEnable (I2C0_BASE);
  //
  //此函数通过配置的总线速度来初始化 I2C 主机模块的操作
  //主设备并启用 I2C 主设备块。false -100kbps/true-400kbps
  //
  I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false);
  InitConsole();
  while (1)
  {
  
  I2C_SEND_CHAR ();
  I2C_RECV_char ();  
  //将要发送的数据放入 FIFO 中
 
  
  }
 }   
   
   
int I2C_SEND_char (void)
 I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_ADDRESS、false);//向从器件发送数据
        
 I2CMasterDataPut (I2C0_BASE、'A');
 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
// while (!I2CMasterBusy (I2C0_BASE));
 while (I2CMasterBusy (I2C0_BASE));
 //
   //检查错误。
   //
   if (I2CMasterErr (I2C0_BASE)!= I2C_MASTER_ERR_NONE)
   {
       返回0;
   }
 I2CMasterDataPut (I2C0_BASE、'Q');
 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
// while (!I2CMasterBusy (I2C0_BASE));
 while (I2CMasterBusy (I2C0_BASE));
  //
   //检查错误。
   //
   if (I2CMasterErr (I2C0_BASE)!= I2C_MASTER_ERR_NONE)
   {
       返回0;
   }
 I2CMasterDataPut (I2C0_BASE、D');
 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
// while (!I2CMasterBusy (I2C0_BASE));
 while (I2CMasterBusy (I2C0_BASE));
  

void I2C_RECV_char (void)

 DATA_READ = I2CMasterDataGet (I2C0_BASE);
 I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_ADDRESS、TRUE);
 for (i=0;i<=n;i++)
 {
 DATA_READ = I2CMasterDataGet (I2C0_BASE);    // DATA_READ 在前面声明为未定义的 int 32位
 I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
 UARTCharPut (UART0_BASE、DATA_READ);
 while (I2CMasterBusy (I2C0_BASE));
 }
  空 InitConsole (空)
 {
  //
//启用 UART0模块。
//
 SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
  //
//等待 UART0模块准备就绪。
//
 while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0));
 SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
 while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA));
 GPIOPinConfigure (GPIO_PA0_U0RX);
 GPIOPinConfigure (GPIO_PA1_U0TX);
 //UARTClockSourceSet (SYSCTL_Periph_UART0、UART_CLOCK_SYSTEM);
 // UARTClockSourceSet (UART0_BASE、UART_CLOCK _PIOSC);
 GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
 UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、115200、(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));
 //UARTCharPut (UART0_BASE、"J");
 
 }

从器件代码

#include "stdio.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/pin_map.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/SysTick .h"
#include "driverlib/timer.h"
#include "inc/hw_NVIC.h"
#include "driverlib/timer.c"
#include "driverlib/SysTick .c"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "inc/hw_ints.h"
#include "driverlib/ssi.h"
#include "driverlib/i2c.h"
空延迟(int a);
volatile uint32_t count=0;//计数器来计算已调用的中断数量
void TimerBegin (void);
uint32_t ui32ADC0Value[1];
float ui32ADCvalue;
#define SLAVE_ADDRESS 0x20

#define debug true
//void InitConsole (void);
unsigned long k=0;
void I2C_SEND_char (void);
void I2C_RECV_char (void);
void InitConsole (void);
uint32_t char_rx;
uint32_t n=3、i;
  int main()
  {
  
  //char char_tx[]="abcd"、data;
  
  SysCtlClockSet (SYSCTL_SYSDIV_1_SYSCTL_USE_OSC |SYSCTAL_XTAL_8MHZ|SYSCTL_OSC_MAIN);//将系统时钟设置为8MHz
  //void InitConsole (void);
  //启用 I2C0外设
  //
  SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);
  while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C0));
  SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
  while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOB));
  //配置多路复用和 GPIO 设置、将 SSI 功能输出到引脚
  GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
  GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
  GPIOPinConfigure (GPIO_PB2_I2C0SCL);
  GPIOPinConfigure (GPIO_PB3_I2C0SDA);
  I2CMasterEnable (I2C0_BASE);
  //
  //此函数通过配置的总线速度来初始化 I2C 主机模块的操作
  //主设备并启用 I2C 主设备块。false -100kbps/true-400kbps
  //
  I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false);
  InitConsole();
  
  while (1)
  {
  
  I2C_RECV_char ();  
  I2C_SEND_CHAR ();
   
  }
 }   
   
   
void I2C_SEND_char (void)

for (i=0;i<=n;i++)
 {
while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_TREQ));
  I2CSlaveDataPut (I2C0_BASE、char_Rx);
  

 }
void I2C_RECV_char (void)
  SysCtlDelay (1000);

 for (i=0;i<=n;i++)
 {
 while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_RREQ));
  char_rx=I2CSlaveDataGet (I2C0_BASE);
  UARTCharPut (UART0_BASE、char_Rx);

 }
#if debug
无效
InitConsole (空)

 //
 //启用用于 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);
 //
 //使用内部8MHz 振荡器作为 UART 时钟源。
 //
 //UARTClockSourceSet (UART0_BASE、UART_CLOCK _PIOSC);
 //
 //为这些引脚选择替代(UART)功能。
 // TODO:更改此选项以选择您正在使用的端口/引脚。
 //
 GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
 //
 //初始化控制台 I/O 的 UART
 //
 UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、115200、(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));

#endif

怀疑

当我保存在调试部分时、程序会停止在主代码中突出显示的部分。 请告诉我发生这种情况的原因。

2.我对突发数据感到困惑的是,我所写的程序是正确的还是不正确的,用于突发数据发送。 如果突发数据的代码不正确、请说明我如何操作。  

我 是一名学生 、 正在学习 I2C 通信。 因此、请帮助我解决问题。

谢谢、

Mariya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    很抱歉、我在前面的代码中出错了。 而不是 while (I2CMasterBusy (I2C0_BASE));我放置 while (I2CMasterBusy (I2C0_BASE));因此它在那里停止。 现在我更改了代码并保持调试模式、并进行了检查、现在它仅在返回 main 执行接收功能后发送第一个字符"A"。在 UART 终端中、我接收的是空字符(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ)。
    从代码也被置于调试模式并且程序在 while (!(I2CSlaveStatus (I2C0_BASE)& I2C_SLAVE_ACT_RREQ)堆栈;这个部分。

    请告诉我将会出现什么问题以及如何解决。
    谢谢、
    Mariya
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Mariya、

    不久前、我在与其他客户合作时看到了类似的问题、并使用我在这篇文章 中提供的代码 e2e.ti.com/.../2817634解决了该问题

    您能否查看我提供的内容并在您的示例上实施这些内容、并查看是否解决了您的问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、先生、

    我使用您提供的用于发送单字节数据的链接检查了我的代码。 我能够发送单字节数据、但问题在于我尝试发送突发量的数据。 我对突发数据发送有一点困惑、我不确定 我遵循的方式是否正确、也不确定是否适用于突发数据发送。 请告诉我先生、我如何来回发送突发数据。

    谢谢、  

    Mariya

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

    我们提供了一份非常有用的应用手册、介绍如何进行 I2C 事务处理、包括突发事务处理、我认为如果您阅读该应用手册、您将获得所需的所有信息! 应用手册链接为 :www.ti.com/.../spma073.pdf