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.
大家好、我正在使用 I2C 协议将 EEPROM 与 tms320f28069连接、我无法发送超过4字节的数据。
我必须写入 EEPROM 的整个页面。
那么、我可以做什么来使用 FIFO 将超过4字节的数据发送到 EEPROM。
谢谢你
您的忠实客户
Mihir Dave
您好!
该器件上的 I2C FIFO 最多只能支持4字节的数据传输和中断生成设置。
我们确实有具有16字节 FIFO 的器件。
我相信您已经查看了示例: C2000Ware\device_support\f28066\examples\c28\i2c_eeprom
多个数据的传输可以通过 FIFO 来实现。
代码中的默认选项为0。 由于这些位为零、如果接收 FIFO 操作被启用并且 I2C 被解除复位、接收 FIFO 中断标志将被置位。
I2caRegs.I2CFFTX.ALL
I2caRegs.I2CFFRX.ALL
我们可以提高寄存器中的触发级别并发送数据块。
此致。
您好!
目前、相应寄存 器的值为 I2caRegs.I2CFFTX.All=0x6020和 I2caRegs.I2CFFRX.All=0x2040。
因此、对于多数据字节 传输、我必须为 以下寄存器分配 I2caRegs.I2CFFTX.All=0x0000和 I2caRegs.I2CFFRX.All=0x0000值?
对吧?
谢谢你
您的忠实客户
Mihir Dave
器件型号:TMS320F28069
您好!
我可以使用该程序将4字节数据发送到 EEPROM、该程序包含"高地址"、"低地址"、"第一个数据"、"第二个数据"。
但现在我必须执行页写操作(向 EEPROM 发送多个字节)。
因此、请向我建议我在下面所附的计划中需要进行的修改。 向 EEPROM 发送多个字节。
谢谢你。
/* i2clibral.c* *创建时间:2019年7月14日 * 作者:Mihir */ #include "DSP28x_Project.h" //器件头文件和示例包含文件 //注:此示例中使用的 I2C 宏可在 // F2806x_I2C_defines.h 文件 //此文件中找到的函数的原型语句中找到。 void I2CA_Init (void); uint16 I2CA_WriteData (struct I2CMSG *msg); uint16 I2CA_ReadData (struct I2CMSG *msg); interrupt void i2c_int1a_ISR (void); void PASS (void); void FAIL (void); #define I2C_SLAVE_ADDR 0x50 #define I2C_NUMBYTES 4 #define I2C_EEPROM_HIGH_ADDR 0x00 #define I2C_EEPROM_LOW_ADDR 0x81 //全局变量 //传出地址将使用两个字节, //因此仅设置最大 14字节的结构 I2CI2cMsgOut1={I2C_MSG_SEND_WITHSTOP, I2C_SLAVE_ADDR、 I2C_NUMBYTES、 I2C_EEPROM_HIGH_ADDR、 I2C_EEPROM_LOW_ADDR、 0x05、 //消息字节1 0x09}; //消息字节2 结构 I2CMSG I2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP、 I2C_SLAVE_ADDR、 I2C_NUMBYTES、 I2C_EEPROM_HIGH_ADDR、 I2C_EEPROM_LOW_ADDR}; struct I2CMSG * CurrentMsgPtr;//用于中断 UINT16传递计数; void gpioConfig (void); UINT16失败计数; int count=0; int msg[10]={0x00、0x7F、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、 void main (void) { uint16 Error; uint16 I; CurrentMsgPtr =&I2cMsgOut1; //步骤1。 初始化系统控制: // PLL、看门狗、启用外设时钟 //此示例函数位于 F2806x_sysctrl.c 文件中。 gpioConfig(); //步骤2. 初始化 GPIO: //此示例函数位于 F2806x_GPIO.c 文件中, //说明了如何将 GPIO 设置为其默认状态。 // InitGpio(); //仅设置 GP I/O 以实现 I2C 功能 //步骤3。 清除所有中断并初始化 PIE 矢量表: //禁用 CPU 中断 DINT; //将 PIE 控制寄存器初始化为默认状态。 //默认状态是禁用所有 PIE 中断并 清除标志//。 //此函数位于 F2806x_PIECTRL.c 文件中。 InitPieCtrl(); //禁用 CPU 中断并清除所有 CPU 中断标志: IER = 0x0000; IFR = 0x0000; //使用指向 shell 中断 //服务例程(service routinese, ISR)的指针初始化 PIE 矢量表。 //这将填充整个表,即使在 本示例中未使用中断//也是如此。 这对于调试很有用。 //可以在 F2806x_DefaultIsr.c 中找到 shell ISR 例程 //此函数可在 F2806x_PieVect.c 中找到 InitPieVectTable(); //此示例中使用的中断被重新映射到 这个文件中的// ISR 函数。 EALLOW;//这是写入 EALLOW 受保护寄存 器 PieVectTable.I2CINT1A =&i2c_int1a_ISR; EDIS;//这是禁用写入 EALLOW 受保护寄存 器所必需的//步骤4。 初始化所有器件外设: //此函数可在 F2806X_InitPeripherals.c 中找到// InitPeripherals ();//此示例 I2CA_Init()不需要; //步骤5。 用户特定代码 //清除计数器 PassCount = 0; failcount = 0; //清除 (i = 0;i < I2C_MAX_buffer_size;i++) {的传入消息缓冲器 I2cMsgIn1.MsgBuffer[i]= 0x0000; } //启用此示例所需的中断 //在 PIE 中启用 I2C 中断1:组8中断1 PieCtrlRegs.PIEIER8.bit.INTx1 = 1; //启用连接到 PIE 组8 的 CPU INT8 |= M_I2CR.I2CI_INT.INT8; //启用连接到 PI_I2I2_ICOR;I2C_INT.INT8; I2caRegs.I2CCNT = 4; I2caRegs.I2CDXR = 0x00;// CAL_CFG1寄存器 I2caRegs.I2CDXR = 0x80;//位 OUT=1、位 FT=1 I2caRegs.I2CDXR = 0x01; I2caRegs.I2CDXR = 0x01; I2caRegs.I2CMDR.all=0x6EA0;*/ // (;) {的应用循环 ////////////////////////////////////////////////////////////////////// //将数据写入 EEPROM 部分// ////////////////////////////////////////////////////////////////////// //检查外发消息是否应发送。 //在本例中,初始化后发送一个停止位。 if (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_SEND_WITHSTOP) { 错误= I2CA_WriteData (&I2cMsgOut1); //如果通信已正确启动,请将 msg 状态设置为忙 //并更新中断服务例程的 CurrentMsgPtr。 //否则,不执行任何操作,然后重试下一个循环。 发送一条消息 //启动后、I2C 中断将处理其余中断。 搜索 //此文件中的 i2c_int1a_isr。 如果(错误= I2C_Success) { CurrentMsgPtr =&I2cMsgOut1; I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY; } }//写入段结束 //////////////////////////////////////////////////////////////////////// //从 EEPROM 部分读取数据// //////////////////////////////////////////////////////////////////////// //检查外发消息状态。 如果状态为、则绕过读取段 //未处于非活动状态。 IF (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_INACTIVE) { //检查传入消息状态。 if (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP) { // EEPROM 地址设置部分 while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success) { //可以设置一个尝试计数器来打破无限 while //循环。 EEPROM 将在执行时发回一个 NACK //写入操作。 即使是写公报 //完成此时,EEPROM 仍可能处于忙状态 //对数据进行编程。 因此、会多次尝试 //必需。 } //更新当前消息指针和消息状态 CurrentMsgPtr =&I2cMsgIn1; I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY; } //一旦消息经过设置内部地址的过程 //在 EEPROM 中、发送重新启动以从读取数据字节 // EEPROM。 完成公报并停留一会。 MsgStatus 为 //在中断服务例程中更新。 否则、IF (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_RESTART) { //读取数据部分 while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success) { //可以设置一个尝试计数器来打破无限 while //循环 。} //更新当前消息指针和消息状态 CurrentMsgPtr =&I2cMsgIn1; I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY; } }//读取段结束 }//结束 for (;) }//结束 main void I2CA_Init (void) { //初始化 I2C I2caRegs.I2CSAR = 0x0050;//从机地址- EEPROM 控制代码 I2caRegs.I2CPSC.all = 6;//预分频器-需要 注意 I2clk = I2mHz;I2clk = I2mK 模块上的 I2mHz;Iclk = 12MHz 必须为非零 I2caRegs.I2CCLKH = 5;//注:必须为非零 I2caRegs.I2CIER。ALL = 0x24;//启用 SCD 和 ARDY 中断 I2caRegs.I2CMDR.ALL = 0x0020;//使 I2C 退出复位 //暂停 I2caRegs.I2CFFTX.ALL = 0x6000时停止 I2C;//启用 FIFO 模式和 TXFIFO I2caRegs.I2CFFRX.ALL = 0x2040;//启用 RXFIFO、清除 RXFFINT、 返回; } uint16 I2CA_WriteData (struct I2CMSG *16) { 等待从任一 STP/ INT16主设备清除通信。 //模块清除该位的操作被延迟,直到 SCD 位被 //置位。 如果在发送新消息之前未选中此位、 // I2C 可能会被混淆。 if (I2caRegs.I2CMDR.bit.STP==1) { 返回 I2C_STP_NOT READY_ERROR; } //设置从地址 I2cRegs.I2CSAR = msg->SlaveAddress; //如果 (I2cRegs.I2CSTR.bit.BB = 1) {,则检查总线是否繁忙 返回 I2C_BUS_BUSY_ERROR; } //设置要发送的字节数 // MsgBuffer +地址 I2caRegs.I2CCNT = msg->NumOfBytes; //设置发送 I2caRegs.I2CDLow= msg->MemoryHighAddr; I2caRegs.I2CDXr = 0=MemoryAdr; (对于 MemoryAdr.I=0) NumOfBytes-2;i++) // for (i=0;i NumOfBytes;i++) { I2caRegs.I2CDXR =*(msg->MsgBuffer+I); } //作为主发送器发送 START I2caRegs.I2CMDR.ALL = 0x6E20; 返回 I2C_Success; } uint16 I2CA_ReadData (struct I2CMSG *MSG) { //等待从任何主控方清除 STP 位。 //模块清除该位的操作被延迟,直到 SCD 位被 //置位。 如果在发送新消息之前未选中此位、 // I2C 可能会被混淆。 if (I2caRegs.I2CMDR.bit.STP==1) { 返回 I2C_STP_NOT_READY_ERROR; } I2caRegs.I2CSAR = msg->SlaveAddress; if (msg->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP) { //检查总线是否占线 IF (I2cRegs.I2CSTR.bit.BB = 1) { 返回 I2C_BUS_BUS_BUSY_ERROR; } I2caRegs.I2CCNT = 2; I2caRegs.I2CDXR = msg->MemoryHighAddr; I2caRegs.I2CDXR = msg->MemoryLowAddr; I2caRegs.I2CMDR.ALL = 0x2620;//发送数据到设置 EEPROM 地址 } 否则 if (msg->MsgStatus = I2C_MSGSTAT_RESTART) { I2caRegs.I2CCNT = msg->NumOfBytes;//设置预期的字节数 I2caRegs.I2CMDR.ALL = 0x2C20;//作为主接收器发送重启 } 返回 I2C_SUCCESS; } 中断 void i2c_int1a_isr (void) // I2C-A { uint16 IntSource、I; //读取中断源 IntSource = I2caRegs.I2CISRC.ALL; //中断源=检测到的停止条件 if (IntSource = I2C_SCD_ISRC) { //如果已完成的消息正在写入数据,则将 msg 重置为非活动状态 if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_WRITE_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_INACTIVE; } 其他 { //如果在的地址设置部分收到 NACK 消息 // EEPROM 读取、下面的代码进一步包含在寄存器访问就绪中 //中断源代码将生成停止条件。 停止后 //条件已接收(此处),将消息状态设置为重试。 //用户可能希望在生成错误之前限制重试次数。 if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP; } //如果已完成消息正在读取 EEPROM 数据,则将 msg 重置为非活动状态 //并从 FIFO 读取数据。 否则(CurrentMsgPTR->MsgStatus =I2C_MSGSTAT_READ_BUSY) { CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE; for (i=0;i < I2C_NUMBYTES;i++) { CurrentMsgPtr->MsgBuffer[i]= I2caRegs.I2CDRR; } { //检查接收到的数据 } } }//检测到停止条件结束 //中断源=寄存器访问就绪 //此中断用于确定 //读取数据通信的 EEPROM 地址设置部分何时完成。 由于没有指令要求停止位、这个标志 //告诉我们何时发送消息而不是 SCD 标志。 如果 接收到 NACK //、清除 NACK 位并命令停止。 否则、请转至 通信的读取//数据部分。 否则、if (IntSource = I2C_ARDY_ISRC) { if (I2caRegs.I2CSTR.bit.nack = 1) { I2caRegs.I2CMDR.bit.STP= 1; I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit; } 否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_RESTART; } }//寄存器访问结束, 否则 { //由于中断源无效而产生一些错误 asm (" ESTOP0"); } //启用未来的 I2C (PIE 组8)中断 PieCtrlRegs.PIEACK.all = PIEACK_group8; } void gpioConfig (void){ EALLOW; //GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;//启用 GPIO32的上拉电阻(SDAA) //GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;//启用 GPIO33的上拉电阻器(SCLA) GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;//异步输入 GPIO32 (SDAA) GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;//异步输入 GPIO33 (SCLA) GpioCtrlRegs.GPBMUX1.bit.GPIO32=1;//为 SDAA 配置 GPIO32 GpioCtrlRegs.GPBMUX1.bit.GPIO33=1;//为 SCLA 配置 GPIO33 SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;// I2C EDIS; } //============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ //不再需要。 //========================================
您好,Mihir ,
如果您希望不使用 FIFO、 则 I2CFFTX/I2CFFRx 可保持为0。
复位时、I2CFFTX / I2CFFRx 寄存器为 0。
如果您希望增加 FIFO 容量,则需要将这些寄存器的位4修改为0。
此致。
您好!
我已将 I2CFFTX/I2CFFRX 保持 为"0"。
但在接收期间收到 MSG 状态代码"32 &33"之后。
我已附上以下相同的计划。
谢谢你
您的忠实客户
Mihir Dave
/* i2clibral.c* *创建时间:2019年7月14日 * 作者:Mihir */ #include "DSP28x_Project.h" //器件头文件和示例包含文件 //注:此示例中使用的 I2C 宏可在 // F2806x_I2C_defines.h 文件 //此文件中找到的函数的原型语句中找到。 void I2CA_Init (void); uint16 I2CA_WriteData (struct I2CMSG *msg); uint16 I2CA_ReadData (struct I2CMSG *msg); interrupt void i2c_int1a_ISR (void); void PASS (void); void FAIL (void); #define I2C_SLAVE_ADDR 0x50 #define I2C_NUMBYTES 4 #define I2C_EEPROM_HIGH_ADDR 0x00 #define I2C_EEPROM_LOW_ADDR 0x81 //全局变量 //传出地址将使用两个字节, //因此仅设置最大 14字节的结构 I2CI2cMsgOut1={I2C_MSG_SEND_WITHSTOP, I2C_SLAVE_ADDR、 I2C_NUMBYTES、 I2C_EEPROM_HIGH_ADDR、 I2C_EEPROM_LOW_ADDR、 0x05、 //消息字节1 0x09}; //消息字节2 结构 I2CMSG I2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP、 I2C_SLAVE_ADDR、 I2C_NUMBYTES、 I2C_EEPROM_HIGH_ADDR、 I2C_EEPROM_LOW_ADDR}; struct I2CMSG * CurrentMsgPtr;//用于中断 UINT16传递计数; void gpioConfig (void); UINT16失败计数; int count=0; int msg[10]={0x00、0x7F、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00、 void main (void) { uint16 Error; uint16 I; CurrentMsgPtr =&I2cMsgOut1; //步骤1。 初始化系统控制: // PLL、看门狗、启用外设时钟 //此示例函数位于 F2806x_sysctrl.c 文件中。 gpioConfig(); //步骤2. 初始化 GPIO: //此示例函数位于 F2806x_GPIO.c 文件中, //说明了如何将 GPIO 设置为其默认状态。 // InitGpio(); //仅设置 GP I/O 以实现 I2C 功能 //步骤3。 清除所有中断并初始化 PIE 矢量表: //禁用 CPU 中断 DINT; //将 PIE 控制寄存器初始化为默认状态。 //默认状态是禁用所有 PIE 中断并 清除标志//。 //此函数位于 F2806x_PIECTRL.c 文件中。 InitPieCtrl(); //禁用 CPU 中断并清除所有 CPU 中断标志: IER = 0x0000; IFR = 0x0000; //使用指向 shell 中断 //服务例程(service routinese, ISR)的指针初始化 PIE 矢量表。 //这将填充整个表,即使在 本示例中未使用中断//也是如此。 这对于调试很有用。 //可以在 F2806x_DefaultIsr.c 中找到 shell ISR 例程 //此函数可在 F2806x_PieVect.c 中找到 InitPieVectTable(); //此示例中使用的中断被重新映射到 这个文件中的// ISR 函数。 EALLOW;//这是写入 EALLOW 受保护寄存 器 PieVectTable.I2CINT1A =&i2c_int1a_ISR; EDIS;//这是禁用写入 EALLOW 受保护寄存 器所必需的//步骤4。 初始化所有器件外设: //此函数可在 F2806X_InitPeripherals.c 中找到// InitPeripherals ();//此示例 I2CA_Init()不需要; //步骤5。 用户特定代码 //清除计数器 PassCount = 0; failcount = 0; //清除 (i = 0;i < I2C_MAX_buffer_size;i++) {的传入消息缓冲器 I2cMsgIn1.MsgBuffer[i]= 0x0000; } //启用此示例所需的中断 //在 PIE 中启用 I2C 中断1:组8中断1 PieCtrlRegs.PIEIER8.bit.INTx1 = 1; //启用连接到 PIE 组8 的 CPU INT8 |= M_I2CR.I2CI_INT.INT8 ;= I2CI_ICOR;I2CADDR_INT.INT8; I2caRegs.I2CCNT = 4; I2caRegs.I2CDXR = 0x00;// CAL_CFG1寄存器 I2caRegs.I2CDXR = 0x80;//位 OUT=1、位 FT=1 I2caRegs.I2CDXR = 0x01; I2caRegs.I2CDXR = 0x01; I2caRegs.I2CMDR.all=0x6EA0; // (;) {的应用循环 ////////////////////////////////////////////////////////////////////// //将数据写入 EEPROM 部分// ////////////////////////////////////////////////////////////////////// //检查外发消息是否应发送。 //在本例中,初始化后发送一个停止位。 if (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_SEND_WITHSTOP) { 错误= I2CA_WriteData (&I2cMsgOut1); //如果通信已正确启动,请将 msg 状态设置为忙 //并更新中断服务例程的 CurrentMsgPtr。 //否则,不执行任何操作,然后重试下一个循环。 发送一条消息 //启动后、I2C 中断将处理其余中断。 搜索 //此文件中的 i2c_int1a_isr。 如果(错误= I2C_Success) { CurrentMsgPtr =&I2cMsgOut1; I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY; } }//写入段结束 //////////////////////////////////////////////////////////////////////// //从 EEPROM 部分读取数据// //////////////////////////////////////////////////////////////////////// //检查外发消息状态。 如果状态为、则绕过读取段 //未处于非活动状态。 IF (I2cMsgOut1.MsgStatus = I2C_MSGSTAT_INACTIVE) { //检查传入消息状态。 if (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP) { // EEPROM 地址设置部分 while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success) { //可以设置一个尝试计数器来打破无限 while //循环。 EEPROM 将在执行时发回一个 NACK //写入操作。 即使是写公报 //完成此时,EEPROM 仍可能处于忙状态 //对数据进行编程。 因此、会多次尝试 //必需。 } //更新当前消息指针和消息状态 CurrentMsgPtr =&I2cMsgIn1; I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY; } //一旦消息经过设置内部地址的过程 //在 EEPROM 中、发送重新启动以从读取数据字节 // EEPROM。 完成公报并停留一会。 MsgStatus 为 //在中断服务例程中更新。 否则、IF (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_RESTART) { //读取数据部分 while (I2CA_ReadData (&I2cMsgIn1)!= I2C_Success) { //可以设置一个尝试计数器来打破无限 while //循环 。} //更新当前消息指针和消息状态 CurrentMsgPtr =&I2cMsgIn1; I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY; } }//读取段结束 }//结束 for (;) }//结束 main void I2CA_Init (void) { //初始化 I2C I2caRegs.I2CSAR = 0x0050;//从机地址- EEPROM 控制代码 I2caRegs.I2CPSC.all = 6;//预分频器-需要 注意 I2clk = I2mHz;I2clk = I2mK 模块上的 I2mHz;Iclk = 12MHz 必须为非零 I2caRegs.I2CCLKH = 5;//注:必须为非零 I2caRegs.I2CIER。ALL = 0x24;//启用 SCD 和 ARDY 中断 I2caRegs.I2CMDR.ALL = 0x0020;//使 I2C 退出复位 //暂停 I2caRegs.I2CFFTX.ALL = 0x6000时停止 I2C;//启用 FIFO 模式和 TXFIFO I2caRegs.I2CFFRX.ALL = 0x2040;//启用 RXFIFO、清除 RXFFINT、 返回; } uint16 I2CA_WriteData (struct I2CMSG *16) { 等待从任一 STP/ INT16主设备清除通信。 //模块清除该位的操作被延迟,直到 SCD 位被 //置位。 如果在发送新消息之前未选中此位、 // I2C 可能会被混淆。 if (I2caRegs.I2CMDR.bit.STP==1) { 返回 I2C_STP_NOT READY_ERROR; } //设置从地址 I2cRegs.I2CSAR = msg->SlaveAddress; //如果 (I2cRegs.I2CSTR.bit.BB = 1) {,则检查总线是否繁忙 返回 I2C_BUS_BUSY_ERROR; } //设置要发送的字节数 // MsgBuffer +地址 I2caRegs.I2CCNT = msg->NumOfBytes; //设置发送 I2caRegs.I2CDLow= msg->MemoryHighAddr; I2caRegs.I2CDXr = 0=MemoryAdr; (对于 MemoryAdr.I=0) NumOfBytes-2;i++) // for (i=0;i NumOfBytes;i++) { I2caRegs.I2CDXR =*(msg->MsgBuffer+I); } //作为主发送器发送 START I2caRegs.I2CMDR.ALL = 0x6E20; 返回 I2C_Success; } uint16 I2CA_ReadData (struct I2CMSG *MSG) { //等待从任何主控方清除 STP 位。 //模块清除该位的操作被延迟,直到 SCD 位被 //置位。 如果在发送新消息之前未选中此位、 // I2C 可能会被混淆。 if (I2caRegs.I2CMDR.bit.STP==1) { 返回 I2C_STP_NOT_READY_ERROR; } I2caRegs.I2CSAR = msg->SlaveAddress; if (msg->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP) { //检查总线是否占线 IF (I2cRegs.I2CSTR.bit.BB = 1) { 返回 I2C_BUS_BUS_BUSY_ERROR; } I2caRegs.I2CCNT = 2; I2caRegs.I2CDXR = msg->MemoryHighAddr; I2caRegs.I2CDXR = msg->MemoryLowAddr; I2caRegs.I2CMDR.ALL = 0x2620;//发送数据到设置 EEPROM 地址 } 否则 if (msg->MsgStatus = I2C_MSGSTAT_RESTART) { I2caRegs.I2CCNT = msg->NumOfBytes;//设置预期的字节数 I2caRegs.I2CMDR.ALL = 0x2C20;//作为主接收器发送重启 } 返回 I2C_SUCCESS; } 中断 void i2c_int1a_isr (void) // I2C-A { uint16 IntSource、I; //读取中断源 IntSource = I2caRegs.I2CISRC.ALL; //中断源=检测到的停止条件 if (IntSource = I2C_SCD_ISRC) { //如果已完成的消息正在写入数据,则将 msg 重置为非活动状态 if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_WRITE_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_INACTIVE; } 其他 { //如果在的地址设置部分收到 NACK 消息 // EEPROM 读取、下面的代码进一步包含在寄存器访问就绪中 //中断源代码将生成停止条件。 停止后 //条件已接收(此处),将消息状态设置为重试。 //用户可能希望在生成错误之前限制重试次数。 if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP; } //如果已完成消息正在读取 EEPROM 数据,则将 msg 重置为非活动状态 //并从 FIFO 读取数据。 否则(CurrentMsgPTR->MsgStatus =I2C_MSGSTAT_READ_BUSY) { CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_INACTIVE; for (i=0;i < I2C_NUMBYTES;i++) { CurrentMsgPtr->MsgBuffer[i]= I2caRegs.I2CDRR; } { //检查接收到的数据 } } }//检测到停止条件结束 //中断源=寄存器访问就绪 //此中断用于确定 //读取数据通信的 EEPROM 地址设置部分何时完成。 由于没有指令要求停止位、这个标志 //告诉我们何时发送消息而不是 SCD 标志。 如果 接收到 NACK //、清除 NACK 位并命令停止。 否则、请转至 通信的读取//数据部分。 否则、if (IntSource = I2C_ARDY_ISRC) { if (I2caRegs.I2CSTR.bit.nack = 1) { I2caRegs.I2CMDR.bit.STP= 1; I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit; } 否则(CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY) { CurrentMsgPtr ->MsgStatus = I2C_MSGSTAT_RESTART; } }//寄存器访问结束, 否则 { //由于中断源无效而产生一些错误 asm (" ESTOP0"); } //启用未来的 I2C (PIE 组8)中断 PieCtrlRegs.PIEACK.all = PIEACK_group8; } void gpioConfig (void){ EALLOW; //GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;//启用 GPIO32的上拉电阻(SDAA) //GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;//启用 GPIO33的上拉电阻器(SCLA) GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;//异步输入 GPIO32 (SDAA) GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;//异步输入 GPIO33 (SCLA) GpioCtrlRegs.GPBMUX1.bit.GPIO32=1;//为 SDAA 配置 GPIO32 GpioCtrlRegs.GPBMUX1.bit.GPIO33=1;//为 SCLA 配置 GPIO33 SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;// I2C EDIS; } //============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ //不再需要。 //========================================
我已将您的另一个线程与这个线程合并、因为它看起来是重复的。
当您尝试发送整个页面时、您是否更新了 I2CCNT 中的字节数? 我看到您在写入函数中将 msg->NumOfBytes 写入 I2C 计数的位置,但我看不到您在消息结构中更新此字段的位置。
此外、如果您使用 FIFO、您只需观察 I2CFFTX.TXFFST 域、以确保在写入 I2CDXR 之前它不会太满而无法获取更多数据。 如果不使用 FIFO、则必须在写入 I2CDXR 之前在每个字节后检查 I2CSTR.XRDY 位。
惠特尼
您好!
我正在更新要在第18行发送的字节数。
在第18行分配了4个以上的计数(字节)之后,也只有4个字节的数据被发送到该位置,并且下一个超过4个字节的数据丢失。
谢谢你
Mihir Dave
我看到、您正在更新该行并重建应用程序? 没关系。 不过、您仍然需要解决我所说的更新代码以检查 TXFFST 的问题、以确保 FIFO 未满、然后再尝试添加更多数据。
惠特尼
您好!
好的、我也会实施它、并在它之后更新您。
谢谢你
Mihir Dave
您好!
我监控了 TXFFST 的状态、它显示了6280。
请告诉我应该检查 TXFFST 状态并更新新数据的代码行、以便我可以发送超过4个字节的数据。
我处于死区状态
谢谢你
您的忠实客户
Mihir Dave
您好,
您是否能够取得进展?
此致。