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:I2C 从模式

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/570784/tm4c123gh6pz-i2c-slave-mode

器件型号:TM4C123GH6PZ

您好!

          我需要在 TM4C123GH6PZ 控制器中配置 I2C 从模式。

最初、当我将数据从从属电路板传输到主电路板时、它工作正常、没有任何问题。 假设我仅重置主板电源、它会造成问题。 在主器件侧复位电源后、在主器件侧接收的数据会互换。 I mean (LSB 和 MSB 数据互换)

我使用从板中的调试器进行了检查、它仅显示正确的数据格式。 当我在主板中连接调试器时、它会显示互换 的数据。

您能帮您解决这个问题吗?

我给出了代码。 我可能没有包含一些变量声明。 由此给您带来的不便、我们深表歉意

#include "FSI_SMB.h"
#include "common_header.h"
#include "GPIO.h"

#define MAX_TX_Bytes2 //待发送的最大字节数
#define MAX_I2C_Tx_SIZE2 //待发送的最大字节数

unsigned char Data_Tx_Buffer[6][MAX_TX_Bytes]={'0'}_RX_Bytes'
};'max_bytes ={0'}

//SMB 相关常量
#define SMB_buffer32//最大 SMB 消息大小
#define SMB_TIMEOUT_LENGTH30// ms -事务超时(任何 SMB 事务不能比此更长)
// SMB 字
#define SMB_WORD2 //字节
#define SMB_BYTE 的大小 1
// SMB 通道标志
#define SMB_FLAG_PEC(1 <<0)


define SLAVE_ADDRESS0x0B

//从板配置

#define Bay1_CELA_I2C1
#define Bay1_CellB_I2C2
#define Bay2_CELA_I2C3
#define Bay2_CellB_BI2C4

// I2C0从配置

#define I2C0_SYSCTK_GPIOx #define GPIO2C_IPB_I2CL_I2CL_GPIO0_GPIO0_GPIO2C_C0_GPIO2C_CL_GPIO2C_CAST_GPIO2_GPIO_GPIO_I2C_CL_GPIO0_GPIO2_C0_GPIO_GPIOR_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO2_GPIO0_GPIO0_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO2_


Pin_map.h Pin_map.h


GPIO_PIN_3
#define BASE_I2C0I2C0_BASE
#define INT0_I2CINT_I2C0

// I2C3从配置

#define I2C3_SYSCTL_PERIPH_GPIOx SYSCTL_PERIP_GPIOxSYSCC3_GPIO0
#define I2C3_GPIO_GPIO1_GPIO1_GPIO_GPIO_GPIO2C3_CA_GPIO1_GPIO_GPIO2_GPIO1_GPIO_GPIO_GPIO_GPIO_GPIO2_GPIO1_GPIO_GPIO1_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO2_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO2_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO_GPIO

Pin_map.h Pin_map.h








define I2C4_SYSCTL_PERIPH_GPIOxSYSCTL_PERIPH_GPIOG
#define I2C4_SYSCTL_I2CxSYSCTL_PERIPH_I2C4
#define I2C4_GPIO_P2C_SYSCT2_I2C_GPIO_GPIO_GPIO2C_CA_GPIO2C_CA_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_C4_3Pin_map.h





GPIO2_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_CI_C4_ Pin_map.h





- Pin_map.h
#define I2C5_GPIO_PGx_I2CxSDAGPIO_PG7_I2C5SDA//GPIO_PG7_I2C5SDA - Pin_map.h
#define I2C5_GPIO_Portx_BASEGPIO_PORTG_BASE
#define I2C5_SCLGPIO_PIN_6
#define I2C5_GPIO_PIN_PIN_PHIN




2数据包


;#define I2C5_USC5_OUT5_BIST_2数据包0;#define I2CU_INT_INTS5_INTS5数据包2


Bay1_Calib、Bay2_Full、Bay2_Calib;

/
* I2C 硬件初始化
*索引- I2C 通道索引(I2C0 | OUTI2C)
* ownAddress -自 SMB 地址
/
void initI2C (uint8索引、uint8 ownAddress)
{
if (index = Bay1_Cella _I2C)// I2C 零通道// Bay1 Cella
{
//从 I2C0初始化

SysCtlPeripheralEnable (I2C0_SYSCTL_Periph_I2Cx);//启用外设。
SysCtlPeripheralEnable (I2C0_SYSCTL_Periph_GPIOx);//启用外设。
GPIOPinConfigure (I2C0_GPIO_PBX_I2CxSCL);
GPIOPinConfigure (I2C0_GPIO_PBX_I2CxSDA);
GPIOPinTypeI2CSCL (I2C0_GPIO_Portx_BASE、I2C0_SCL);// SCL
GPIOPinTypeI2C (I2C0_GPIO_Portx_BASE、I2C0_DTA);
I2CSlaveInit (base_I2C0、ownAddress);//初始化 I2C 从设备块
I2CSlaveEnable (BASE_I2C0);//启用 I2C 从设备块
I2CSlaveIntEnable (BASE_I2C0);//启用 I2C 从机中断
IntEnable (INT0_I2C);
}
否则、如果(INDEX = Bay1_CellB_I2C)// I2C 第三通道// Bay1 CellB
{
//从 I2C3初始化

SysCtlPeripheralEnable (I2C3_SYSCTL_Periph_I2Cx);//启用外设。
SysCtlPeripheralEnable (I2C3_SYSCTL_Periph_GPIOx);//启用外设。
GPIOPinConfigure (I2C3_GPIO_PGx_I2CxSCL);
GPIOPinConfigure (I2C3_GPIO_PGx_I2CxSDA);
GPIOPinTypeI2CSCL (I2C3_GPIO_Portx_BASE、I2C3_SCL);// SCL
GPIOPinTypeI2C (I2C3_GPIO_Portx_BASE、I2C3_DTA);
I2CSlaveInit (base_I2C3、ownAddress);//初始化 I2C 从设备块
I2CSlaveEnable (BASE_I2C3);//启用 I2C 从设备块
I2CSlaveIntEnable (BASE_I2C3);//启用 I2C 从机中断
IntEnable (INT3_I2C);
}
否则、IF (INDEX = Bay2_Cella _I2C)// I2C 第四通道// Bay2 Cella
{
//从 I2C4初始化

SysCtlPeripheralEnable (I2C4_SYSCTL_Periph_I2Cx);//启用外设。
SysCtlPeripheralEnable (I2C4_SYSCTL_Periph_GPIOx);//启用外设。
GPIOPinConfigure (I2C4_GPIO_PGx_I2CxSCL);
GPIOPinConfigure (I2C4_GPIO_PGx_I2CxSDA);
GPIOPinTypeI2CSCL (I2C4_GPIO_Portx_BASE、I2C4_SCL);// SCL
GPIOPinTypeI2C (I2C4_GPIO_Portx_BASE、I2C4_DTA);
I2CSlaveInit (base_I2C4、ownAddress);//初始化 I2C 从设备块
I2CSlaveEnable (BASE_I2C4);//启用 I2C 从设备块
I2CSlaveIntEnable (BASE_I2C4);//启用 I2C 从机中断
IntEnable (int4_I2C);
}
否则、如果(INDEX = Bay2_CellB_I2C)// I2C 第五通道// Bay2 CellB
{
//从 I2C5初始化

SysCtlPeripheralEnable (I2C5_sysctl_Periph_I2Cx);//启用外设。
SysCtlPeripheralEnable (I2C5_sysctl_Periph_GPIOx);//启用外设。
GPIOPinConfigure (I2C5_GPIO_PGx_I2CxSCL);
GPIOPinConfigure (I2C5_GPIO_PGx_I2CxSDA);
GPIOPinTypeI2CSCL (I2C5_GPIO_Portx_BASE、I2C5_SCL);// SCL
GPIOPinTypeI2C (I2C5_GPIO_Portx_BASE、I2C5_DTA);
I2CSlaveInit (base_I2C5、ownAddress);//初始化 I2C 从设备块
I2CSlaveEnable (BASE_I2C5);//启用 I2C 从设备块
I2CSlaveIntEnable (BASE_I2C5);//启用 I2C 从机中断
IntEnable (INT5_I2C);
}

#endif
}

/*********
*返回相应的 SMBus 基值
/
uint32 I2CBaseS (uint8索引)
{
uint32 Slave_base = 0;
switch (index)
{
Case Bay1_Cella I2C:
Slave_base = base_I2C0;
break;

Case Bay1_CellB_I2C:
slave_base = base_I2C3;
break;

case Bay2_Cella:
slave_base_bend;bay2c4



= base_base_base_base_base_base_I2C;case





= base_base_base_sta.
*将相应的 SMBus 命令数据返回到缓冲区
/
void SMB_SLAVE_TX_DATA (uint8索引、uint8命令)
{
switch (command)
{
case SMB_specification _info:

temp_data[index]= 0x0003;

break;

case SMB_CYCLE:temp_DATA[index]

= 0x0005;

break;

case SMB_MAX_ERROR:

if (Bay1_CALIBRATE=0x0A=0x0A_CLA


= 0x0A
;







= 0xbay2C_BIC_BIC_DATA_CLABLE_CLABLETE_ENABLE[0x0A]= 0x0A[0A]= 0xbay_CLABLE_CLAB_ENABLE_CLAB_ENAB_ENAB_ENAB_ENABLE];{= 0x0A[0x0A]= 0x0002_CY_CLIP_CLIP_CLIP_CLIP_CLAB_CLAB_ENAB_ENAB_CL

temp_data[Bay2_CellB_I2C]= 0x0A;
}
否则
{
temp_data[Bay2_Cella _I2C]= 0x02;
temp_data[Bay2_CellB_I2C]= 0x02;
}

break;

case SMB_BAT_A2= 0x00BA_E2_E2[= 0x00BA_E2_E2_ENABLE_END]




















;temp_Bay2_E2_E2_E2C_ENABLE_PAY_E= 0x00_E2_E2_PAY_PAY_E12_E= 0x0002;= 0xBA_E2_ENABLE_PAY_END[PAY_E_E_PAY_PAY_PAY2_E_E_PAY_E2_PAY_PAY_PAY_PAY_100]= 0x0002 = 0x0002 = 0x0002;= 0x00_EART_E2_
temp_data[Bay2_CellB_I2C]= 0x00A0;
}
否则
{
temp_data[Bay2_Cella _I2C]= 0x0080;
temp_data[Bay2_CellB_I2]= 0x0080;
}

break;

case SMB_CHARING_VOLTAGE:

temp_DATA[index]= 0x41A0;// 16800

break;// temp_data/intry[0x3000mV/ inch[000mV[000_b]















;case = 0x3000mb = 0x3000mb;/b_data_index = 0x000mV/ incharge[000m];/b./000mVb = 0x3000mb = 0x3000mb;/b./000mb = 0x3000mb;//



case smb_at_rate time_TO_full:

temp_data[索引]= 0x0050;

break;

case smb_at_rate time_TO_empty:

temp_data[索引]= 0x0070;

break;

case smb_relat_State_of _charge:

temp_data[索引]= 0x0041;



case SMB_absolute_State_index]





;temp_data_data_index]= 0x0031;temp_data_data_data_index]=

0x0031;case:0x0031;temp_data_data_index_data_index_deg[0x0031;t_data_index];t_data_data_index]= 0x0031 = 0x0031;tb


= 0x000_data_data_deg_



MSB_DATA = MSB_DATA >> 8;

Data_Tx_Buffer[index][0]= MSB_DATA;
Data_Tx_Buffer[index][1]= LSB_DATA;
}

/********
*中断处理程序(索引- SMB 通道索引
/
void I2CHandler (uint8索引)
{
// uint32 Basem = I2CBaseM (索引);//获取主寄存器基础
uint32 bases = I2CBaseS (INDEX);//获取从机寄存器基址
uint8状态;
uint8数据;

//从机模式
if (I2CSlaveIntStatus (Bases、true))// I2CSlaveIntStatus ()返回 true =>如果 I2C 从机中断状态为活动
状态{
//清除从机中断
I2CSlaveIntClear (Bases);//清除 I2C 从机中断源。

//获取 I2C 从
机状态的状态= I2CSlaveStatus (Bases);//获取当前的 I2C 从机中断状态。
数据= I2CSlaveDataGet (Bases);//获取数据(此函数从 I2C 从数据寄存器读取一个字节的数据。)

if (status = I2C_SLAVE_ACT_RREQ_FBR)//主设备已发送第一个字节
{
//仅在总线空闲
时处理 if (smb[index].state = SMB_IDLE)
{
smb[index].state = SMB_SLAVE;
SMB[index].index = 0;
SMB[index].callpeconed= 0;
如果已激活 smb[calebraveindex]、则为 smb[calebraveindex];如果已重新调用 smb[slaveindex].index = smb[slavecount];如果已激活 smb[smb[calebraveback.index
//我们只能从从从 smb[index].cmd
= I2CSlaveDataGet (Bases)接收字;//第一个字节是命令

if (smb[index].flags & SMB_FLAG_PEC)
{
smb[index].count += 1;
CRC8_add ((uint8 *)&smb[index].timerRestart]


;smb[index](timerRestart])
// else
//我们处于某个中间位置,需要先将其丢弃
}

//从接收器
else if (status =I2C_SLAVE_ACT_RREQ)//主机已发送数据
{
data = I2CSlaveDataGet (Bases);//获取数据
SMB [索引].count-;

if (smb[index].count = 0)//接收到的最后一个字节
{
if (SMB [索引].flags & SMB_FLAG_PEC)// if PEC -最后一个字节是校验和
SMB [索引].Received= data;
SMB [索引].state = SMB_DONE;//我们已完成,需要处理数据
}

//如果不是最后一个字节,或者没有启用 PEC
,则需要将字节添加到缓冲区中(((smb[index].count > 0)||(!(smb[index].flags & smb_FLAG_PEC)
){
smb[index].que[sb[index].index+]= data;
if (pbpbpb[index].intpec[e].flag](sb[sb[sb[sb[=
)、sb[culate].index].index].flag])))

}

//从发送器
if (status =I2C_SLAVE_ACT_TREQ)//主设备已请求数据(TREQ 位已设置)
{
smb_slave_tx_data (index、smb[index].cmd);

if (Data_Count_var < Max_I2C_Tx_size)// Max_I2C_Tx_Size 是要发送的最大字节数
{
I2CSlaveDataPut (Bases、Data_Tx_Buffer[index][Data_Count_var]);//传输一个字节
Data_Count_var++;//下一个字节的增量

//检查 Tx 是否已完成
if (Data_Count_var = Max_I2C_Tx_Size)//重置标志和其他变量
{
DATA_Count_var = 0;
smb[索引].state = SMB_IDLE;
}
}

}


/*********
*实数 I2C 中断处理程序
//

从板 I2C 中断

空 I2C0IntHandler (空)// Bay1 Cella 中断
{
I2CHandler (Bay1_Cella _I2C);
}

void I2C3IntHandler (void)// Bay1 CellB 中断
{
I2CHandler (Bay1_CellB_I2C);
}

void I2C4IntHandler (void)// Bay2 Cella Interrupt
{
I2CHandler (Bay2_Cella _I2C);
}

void I2C5IntHandler (void)// Bay2 CellB 中断
{
I2CHandler (Bay2_CellB_I2C);
}

//
* main.c
*
/ int main (void)
{
SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTAL_XTAL_8MHZ);CellC1(Bayella

(I2C_USC_USC_UST_OSC
);I2C_BIC_BIC/

I2C 从器件地址/I2C B;BIC_BIC_BIC_1、I2C_BITERB;BIC_BIC_BITER2、I2C_BITER2、I2C_BIC_BICE_B、I2C_BITER2、I2C_BIN/ BIC_BIN/ BIT_BIC_BYB、BIN/ BIN/ BIN/ BIN/ BIN/ CLB

while (1)
{

}
}




 

。  

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

    您是否检查了示波器或 LA 上的 I2C 总线以查看发生了什么。 此外、当主器件上完成电源复位时、您是否与调试器进行了检查、从器件如何响应更改?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    感谢您的宝贵答复。 我检查了示波器上的 I2C 总线。 因为我看到的只是从电路板读取数据的差异。 下面我附上了一个图像、供您参考、并检查了示波器中的 I2C 总线。

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

    当主器件由于下电上电周期而复位时、从器件侧是否知道它? 我认为,奴隶仍然按照交易的旧状态作出反应。 作为实验、将 GPIO 从主器件连接到从器件。 主器件侧的 GPIO 用于复位从器件。 主器件上电后、它会使从器件复位。 然后、从器件是否使用正确的数据或不正确的数据进行响应。

    我还注意到、低电平状态高于 GND 电平。 这表明使用了非常强的上拉电阻。 我也会要求您纠正相同的情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    很抱歉耽误你的回答。 这 是我的错误。 现在工作正常。

    I 侧(主控和受控)都启用了 PEC、并且我额外计算了一个字节的数据以在受控侧传输 PEC、但我忘记了传输 PEC 数据。 由于这个错误、我的 LSB 和 MSB 数据被互换。 感谢您的宝贵答复。

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

    很高兴您能够解决该问题。