主题中讨论的其他器件: C2000WARE
大家好、我正在使用 I2C 协议将 EEPROM 与 tms320f28069连接、我无法发送超过4字节的数据。
我必须写入 EEPROM 的整个页面。
那么、我可以做什么来使用 FIFO 将超过4字节的数据发送到 EEPROM。
谢谢你
您的忠实客户
Mihir Dave
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;
}
//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
//不再需要。
//========================================
您好!
我已将 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 位。
惠特尼