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 位。
惠特尼
您好,
您是否能够取得进展?
此致。