Thread 中讨论的其他器件: controlSUITE
工具/软件:Code Composer Studio
使用 TMS320F28335、我尝试写入 和读取类型为 TM24M01的 EEPROM。
我刚刚修改 了\ti\controlSUITE\device_support\F2833x\v133\DSP2833x_examples_ccsv4中的一个示例。 写作和阅读效果良好。 我的问题是 尝试写入下一个地址并覆盖当前地址。 对两个地址的读取是相同的。
我正在尝试仅写入器件的第一页(256个 baytes/页)。 原因可能是什么? 此处随附了我修改后的读数源和屏幕截图。
#include "DSP28x_Project.h" //器件头文件和示例 include 文件
#define I2C_SLAVE_ADDR 0x50
#define I2C_NUMBYTES 14.
#define I2C_EEPROM_HIGH_ADDR 0x00
#define I2C_EEPROM_LOW_ADDR 0x0F
void I2CA_Init (void);
uint16 I2CA_WriteData (struct I2CMSG *msg);
uint16 I2CA_ReadData (struct I2CMSG *msg);
uint16 I2CA_WriteDataConfig (struct I2CMSG *msg);
uint16 I2CA_ReadDataConfig (struct I2CMSG *msg);
中断空 CPU_timer0_ISR (空);
UINT16 EEPROM_Buffer_Init();
uint16 EEPROM_ParaMetersUpdate();
uint16错误;
tempMemoryHighAddr、tempMemoryLowAddr;
uint32内存 HighLastAddr;
uint32内存 LowLastAddr;
uint16 PassCount、WriteCounter、L、I、k;
uint16mtime;
struct I2CMSG * CurrentMsgPtr;
void main (void)
{
// uint16错误;
// uint16 i;
// I2cMsgOut1.MsgBuffer[0]= 0x00;
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 DSP2833x_SYSCTRL.c 文件中。
InitSysCtrl();
//步骤2. 初始化 GPIO:
//此示例函数位于 DSP2833x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
// InitGpio();
//仅针对 I2C 功能设置 GP I/O
InitI2CGpio();
//禁用 CPU 中断
Dint;
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 DSP2833x_PIECTRL.c 文件中。
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 DSP2833x_PieVect.c 中找到
InitPieVectTable();
//此文件中的 ISR 函数。
EALLOW; //这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.I2CINT1A =&i2c_int1a_ISR;
PieVectTable.TINT0 = &CPU_timer0_ISR;
EDIS; //这是禁止写入 EALLOW 受保护寄存器所必需的
//此函数位于 DSP2833x_InitPeripherals.c 中
// InitPeripherals ();//此示例不需要
InitCpuTimer();
ConfigCpuTimer (&CpuTimer0、100、1000);
PieCtrlRegs.PIEIER1.bit.INTx7=1; //计时器0配置
StartCpuTimer0();
{
//////////////////////////////////////////////////////////////////////
// EEPROM_DataMgt();
中断空 CPU_timer0_ISR (空)
{
{
mtime = 0;
EEPROM_DataMgt();
PieCtrlRegs.PIEACX.ALL |= PIEACK_Group1;
空 I2CA_Init (空)
{
//初始化 I2C
I2caRegs.I2CSAR = 0x0050; //从器件地址- EEPROM 控制代码
I2caRegs.I2CPSC.all = 14; //预分频器-模块时需要7-12MHz (150/15=10MHz)
#endif
对于 100MHz SYSCLKOUT、#IF (CPU_FRQ_100MHz)//
I2caRegs.I2CPSC.all = 9; //预分频器-模块时需要7-12MHz (100/10 = 10MHz)
#endif
I2caRegs.I2CCLKH = 5; //注意:必须为非零
I2caRegs.I2CIER.ALL = 0x24; //启用 SCD 和 ARDY 中断
//挂起时停止 I2C
I2caRegs.I2CFFRX.ALL = 0x2040; //启用 RXFIFO、清除 RXFFINT、
}
PassCount = 0;
WriteCounter = 0;
L= 0;
K = 0;
//清除传入消息缓冲区
对于(I = 0;I < I2C_MAX_BUFFER_SIZE;I++)
{
I2cMsgIn1.MsgBuffer[i]= 0x0000;
I2cMsgOut1.MsgBuffer[i]= 0x0000;
}
tempsMsgStatus_OUT = I2C_MSGSTAT_SEND_WITHSTOP;
tempsMsgStatus_IN = I2C_MSGSTAT_SEND_NOSTOP;
tempSlaveAddress = I2C_SLAVE_ADDR;
tempNumOfBytes = I2C_NUMBYTES ;
tempMemoryHighAddr = I2C_EEPROM_HIGH_ADDR;
tempMemoryLowAddr = I2C_EEPROM_LOW_ADDR;
I2CA_ReadDataConfig (&I2cMsgIn1);
I2CA_WriteDataConfig (&I2cMsgOut1);
返回0;
}
UINT16 EEPROM_DataMgt()
{
{
{
{
MemoryHighLastAddr = tempMemoryHighAddr;//存储当前地址
MemoryLowLastAddr = tempMemoryLowAddr;
tempMemoryLowAddr = (tempMemoryLowAddr += 0x10); //计算 要写入的下一个低位地址
I2CA_WriteDataConfig (&I2cMsgOut1);// 发送要写入的地址和数据
否则、if (WriteCounter ==1)//改写当前地址
{
tempMemoryLowAddr = 内存 LowLastAddr;
I2CA_PointerOverWrite (&I2cMsgOut1);
否则 {/*I2CA_WriteDataConfig (&I2cMsgOut1);*/}
{
L++;
WriteCounter++;
CurrentMsgPtr =&I2cMsgOut1;
I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY;
{
WriteCounter = 0;// 在写入下一个地址并覆盖当前地址后复位
tempMemoryLowAddr = (tempMemoryLowAddr += 0x10);//存储写入的地址
} //写入段结束
{
//检查传入消息状态。
if (I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP)// I2cMsgIn1.MsgStatus 在程序启动时初始化为 I2C_MSGSTAT_SEND_NOSTOP
{
// EEPROM 地址设置部分
// I2CA_ReadDataConfig (&I2cMsgIn1);
{
//可以设置一个尝试计数器来打破无限 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;
}
} //读取段结束
返回0;
uint16 I2CA_WriteDataConfig (struct I2CMSG *msg)
{
MSG->SlaveAddress = tempSlaveAddress;
MSG->NumOfBytes = tempNumOfBytes;
MSG->MemoryHighAddr = tempMemoryHighAddr;
MSG->MemoryLowAddr = tempMemoryLowAddr;
MSG->MsgBuffer[0] = 0x05;
MSG->MsgBuffer[1] = 0x06;
MSG->MsgBuffer[2] = 0x00;
MSG->MsgBuffer[3] = 0xE1;
MSG->MsgBuffer[4] = 0x00;
MSG->MsgBuffer[5] = 0xE1;
MSG->MsgBuffer[6] = 0x00;
MSG->MsgBuffer[7] = 0x00;
MSG->MsgBuffer[8] = 0x00;
MSG->MsgBuffer[9] = 0x00;
MSG->MsgBuffer[10] = 0x64;
MSG->MsgBuffer[11] = 0x96;
MSG->MsgBuffer[12]=0x64 ;
MSG->MsgBuffer[13] = 0x0A;
MSG->MsgBuffer[14]=0x00 ;
MSG->MsgBuffer[15]=0x00 ;
}
UINT16 I2CA_PointerOverWrite (struct I2CMSG *msg)
{
MSG->SlaveAddress = tempSlaveAddress;
MSG->NumOfBytes = tempNumOfBytes;
MSG->MemoryHighAddr = tempMemoryHighAddr;
MSG->MemoryLowAddr = tempMemoryLowAddr ;
MSG->MsgBuffer[0] = 0x00;
MSG->MsgBuffer[1] = 0x06;
MSG->MsgBuffer[2] = 0x01;
MSG->MsgBuffer[3] = 0xF4;
MSG->MsgBuffer[4] = 0x01;
MSG->MsgBuffer[5] = 0xF4;
MSG->MsgBuffer[6] = 0x00;
MSG->MsgBuffer[7] = 0x00;
MSG->MsgBuffer[8] = 0x00;
MSG->MsgBuffer[9] = 0x00;
MSG->MsgBuffer[10] = 0x64;
MSG->MsgBuffer[11] = 0x96;
MSG->MsgBuffer[12]=0x64 ;
MSG->MsgBuffer[13] = 0x00;
MSG->MsgBuffer[14]=0x00 ;
MSG->MsgBuffer[15]=0x00 ;
返回0;
}
uint16 I2CA_ReadDataConfig (struct I2CMSG *msg)
{
MSG->SlaveAddress = tempSlaveAddress;
MSG->NumOfBytes = tempNumOfBytes;
MSG->MemoryHighAddr = tempMemoryHighAddr;
MSG->MemoryLowAddr = tempMemoryLowAddr ;
返回0;
}
{
uint16 i;
//模块清除该位的操作被延迟到 SCD 位之后
//设置。 如果在启动新消息之前未选中此位
// I2C 可能会被混淆。
IF (I2caRegs.I2CMDR.bit.STP==1)
{
返回 I2C_STP_NOT _READY_ERROR;
}
I2caRegs.I2CSAR = msg->SlaveAddress;
IF (I2cRegs.I2CSTR.bit.BB = 1)
{
返回 I2C_BUS_BUS_BUSY_ERROR;
}
// MsgBuffer +地址
I2caRegs.I2CCNT = msg->NumOfBytes+2;
//设置要发送的数据
I2caRegs.I2CDXR = msg->MemoryHighAddr;
I2caRegs.I2CDXR = msg->MemoryLowAddr;
//对于(i=0;i NumOfBytes-2;i++)
对于(i=0;i NumOfBytes;i++)
I2caRegs.I2CDXR =*(msg->MsgBuffer+I);
}
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;
}
{
//检查总线是否占线
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; //作为主接收器发送重启
}
}
{
uint16 IntSource、I;
IntSource = I2caRegs.I2CISRC.ALL;
//中断源=检测到停止条件
if (IntSource = I2C_SCD_ISRC)
{
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_WRITE_BUSY)
{
其他
{
//如果在的地址设置部分收到 NACK 消息
// EEPROM 读取、下面的代码进一步包含在寄存器访问就绪中
//中断源代码将生成停止条件。 停止后
//条件已接收(此处),将消息状态设置为重试。
//用户可能希望在生成错误之前限制重试次数。
if (CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr -> MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
// PassCount++;
//如果已完成消息正在读取 EEPROM 数据,则将 msg 重置为非活动状态
//并从 FIFO 读取数据。
否则(CurrentMsgPTR->MsgStatus =I2C_MSGSTAT_READ_BUSY)
{
for (i=0;i < I2C_NUMBYTES;i++)
{
I2cMsgIn1.MsgBuffer[i]= I2cRegs.I2CDRR;
}
if (PassCount< 15)// 在15次读数后停止将数据写入 Temparray。
{
tempMemoryHighAddr = tempMemoryHighAddr;
tempMemoryLowAddr = (tempMemoryLowAddr += 0x10);
Temparray[(14*PassCount)+k]= CurrentMsgPtR->MsgBuffer[k] ;
PassCount++;
I2CA_ReadDataConfig (&I2cMsgIn1);
}
}
否则{}
}
} //检测到停止条件结束
//此中断用于确定的 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");
}
PieCtrlRegs.PIEACX.ALL = PIEACK_group8;
}
//不再需要。
//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================