当前位置:首页 > DSP中i2c存储eeprom实例分析
return I2C_STP_NOT_READY_ERROR; }
// Setup slave address
I2caRegs.I2CSAR = msg->SlaveAddress;
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1) {
return I2C_BUS_BUSY_ERROR; }
////////判断总线空闲后进行数据发送//////// // Setup number of bytes to send // MsgBuffer + Address
I2caRegs.I2CCNT = msg->NumOfBytes+2; //递减
// Setup data to send
I2caRegs.I2CDXR = msg->MemoryHighAddr; I2caRegs.I2CDXR = msg->MemoryLowAddr; // for (i=0; i
I2caRegs.I2CDXR = *(msg->MsgBuffer+i); }
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20; // 按以下参数配置IIC并使能IIC
//【0b0110 1110 0010 0000,NACKMOD=0,FREE=1中断产生时IIC能继续运行,STT=1产生开始位】
//【STP=1产生停止位,MST=1主模式,TRX=1发送,XA=0 七位地址模式,RM=0不重复,DLB=0无回路,IRS=1使能I2C模块,STB=0,FDF=0】 //开始发送数据,I2CCNT 递减模式统计数据到达0时产生中断,且产生停止位 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=0写数据模式 return I2C_SUCCESS; }
Uint16 I2CA_ReadData(struct I2CMSG *msg)
{ //要完成一次读数据任务:要产生两个START位,产生第1个START位之后发送设备地址和数据地址; //产生第2个START位之后写入设备地址,并开始接收存储器提供的数据。 // Wait until the STP bit is cleared from any previous master communication. // Clearing of this bit by the module is delayed until after the SCD bit is // set. If this bit is not checked prior to initiating a new message, the // I2C could get confused. if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR; }
I2caRegs.I2CSAR = msg->SlaveAddress;
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP) //产生第一个START位之后发送设备地址和数据地址//// {
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1) {
return I2C_BUS_BUSY_ERROR; }
I2caRegs.I2CCNT = 2; // 设置发送数据字节数-递减模式-等0时可以允许产生stop位(若使能STP) I2caRegs.I2CDXR = msg->MemoryHighAddr;//发送要读取数据的开始地址 I2caRegs.I2CDXR = (msg->MemoryLowAddr); I2caRegs.I2CMDR.all = 0x2620;
// 按以下参数配置IIC并使能IIC
//【STT =1发送起始位,STP=0不产生停止位,MST=1主模式,TRX=1发送,IRS=1使能I2C模块】
} // 开始发送数据I2CCNT 递减模式统计数据到达0时产生中断,但是没有产生停止位 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=0写数据
else if(msg->MsgStatus == I2C_MSGSTAT_RESTART)//产生第2个START位之后发送设备地址,然后开始接收存储器提供的数据// {
I2caRegs.I2CCNT = msg->NumOfBytes; I2caRegs.I2CMDR.all = 0x2C20;
// 设置数据接收字节数量
// 按以下参数配置IIC并使能IIC
// 【STT =1发送起始位,STP=1产生停止位,MST=1主模式,TRX=0接收,IRS=1使能I2C模块】
} //开始接收数据,I2CCNT递减模式统计数据到达0时产生中断,有产生停止位 //注意-TRX决定AT24C1024设备地址中的R/W,这里R/W=1读数据
return I2C_SUCCESS; //到此说明发送地址/读取数据成功 }
interrupt void i2c_int1a_isr(void) // I2C-A {
Uint16 IntSource, i;
all_ISRC_number++;//统计所有中断次数 // Read interrupt source IntSource = I2caRegs.I2CISRC.all;
// Interrupt source = stop condition detected if(IntSource == I2C_SCD_ISRC) {
SCD_ISRC_number++;
// If completed message was writing data, reset msg to inactive state
if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY) {
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;//发送完成,便换为未启动状态;说明可以进行下一次写数据 } else {
// If a message receives a NACK during the address setup portion of the // EEPROM read, the code further below included in the register access ready // interrupt source code will generate a stop condition. After the stop // condition is received (here), set the message status to try again. // User may want to limit the number of retries before generating an error.
if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)//发送无停止位地址忙 {
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;//更新为发送停止位状态,可允许下一发送地址 }
// If completed message was reading EEPROM data, reset msg to inactive state // and read data from FIFO.
else if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY) //读数据忙状态,说明可对接收缓存器I2CDRR进行接收数据读取了 {
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE; //设为未启状态动,再读数据,这样允许下一次写数据到EEPROM for(i=0; i < I2C_NUMBYTES; i++) {
CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR; }
// Check recieved data //读完接收到的数据,接下来进行判断数据是否准确 for(i=0; i < I2C_NUMBYTES; i++) {
if(I2cMsgIn1.MsgBuffer[i] == I2cMsgOut1.MsgBuffer[i]) {
PassCount++; } else {
FailCount++; } }
if(PassCount == I2C_NUMBYTES) { pass(); } else { fail();
}
//检查完毕
} }
} // end of stop condition detected // Interrupt source = Register Access Ready
// This interrupt is used to determine when the EEPROM address setup portion of the //该中断用于判断读数据通讯中何时完成EEPROM数据地址的设置;
// read data communication is complete. Since no stop bit is commanded, this flag //由于不产生停止位,这个标志(ARDY)告诉我们地址数据是否发送完成。 // tells us when the message has been sent instead of the SCD flag. If a NACK is //如果收到NACK,清除NACK位,并设置产生一个停止位。
// received, clear the NACK bit and command a stop. Otherwise, move on to the read //否则,继续读取通讯数据。
// data portion of the communication. else if(IntSource == I2C_ARDY_ISRC) //IIC模块准备好中断:包括【复位,发完一个数据单元(1~8bits的数据)
{ //却没收到ACK/STOP或者出现counter=0】都可引发该中断 ARDY_ISRC_number++;
if(I2caRegs.I2CSTR.bit.NACK == 1) //因为EEPROM处理数据忙而回复的NACK {
I2caRegs.I2CMDR.bit.STP = 1; //产生一个STOP停止位,从而引发一次SCD中断。 I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT; //清除NACK位
ARDY_ISRC_NACK_number++;
}
else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY) {
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_RESTART;//更新为重发START位状态,为接收数据准备 }
} // end of register access ready else {
// Generate some error due to invalid interrupt source asm(\ ESTOP0\ }
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8; //重启中断允许 }
void pass()
{
asm(\ ESTOP0\ for(;;); } void fail() {
asm(\ ESTOP0\ for(;;); }
//=========================================================================== // No more.
//===========================================================================
共分享92篇相关文档