实用文档
} // end of write section
///////////////////////////////////
// Read data from EEPROM section //该过程包括两次发送START位,第一次发送地址 ///////////////////////////////////
// Check outgoing message status. Bypass read section if status is // not inactive.
if (I2cMsgOut1.MsgStatus == I2C_MSGSTAT_INACTIVE) {
// Check incoming message status.
if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP) { Read_load_num1++;
// EEPROM address setup portion
while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS) {
// Maybe setup an attempt counter to break an infinite while //这里可以设置一个计数器用于终止可能存在的无限循环。 // loop. The EEPROM will send back a NACK while it is performing//当EEPROM忙于处理写数据操作时,将返回一个NACK。 // a write operation. Even though the write communique is //对DSP来说,此刻写操作已经完成。但是,EEPROM仍需要 // complete at this point, the EEPROM could still be busy //一定时间完成数据的烧写1.8ms左右。在EEPROM完成烧写之前,都会
// programming the data. Therefore, multiple attempts are //返回NACK,告诉DSP它还在忙。因此,DSP需要多次尝试,直到
// necessary. //EEPROM空闲了,并返回ACK确认为止。 }
// Update current message pointer and message status CurrentMsgPtr = &I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
//第一次发送START成功,即地址数据已发送成功,给发无停止位数据忙状态,作为第二次发送START位标志 }
// Once message has progressed past setting up the internal address//一旦成功写入EEPROM地址,便可以再次发送START起始位
// of the EEPROM, send a restart to read the data bytes from the //然后从EEPROM存储器中读取数据。 // EEPROM. Complete the communique with a stop bit. MsgStatus is //DSP采可用一个停止位来结束数据接收。 // updated in the interrupt service routine. //msg状态在中断程序中被更新了。 else if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_RESTART) //该状态是在中断服务程序中态被赋予 { Read_load_num2++; // Read data portion
while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS) {
// Maybe setup an attempt counter to break an infinite while // loop. }
文案大全
实用文档
// Update current message pointer and message status CurrentMsgPtr = &I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;
//第二次发送START,且数据接收成功,给下一个状态-读忙,作为中断中读取接收缓存中数据的标志 }
} // end of read section
} // end of for(;;) } // end of main
void I2CA_Init(void) {
// Initialize I2C
I2caRegs.I2CSAR = 0x0050;
#if (CPU_FRQ_100MHZ) I2caRegs.I2CPSC.all = 9; #endif
#if (CPU_FRQ_60MHZ) I2caRegs.I2CPSC.all = 6; #endif
I2caRegs.I2CCLKL = 95; I2caRegs.I2CCLKH = 95;
// NOTE: must be non zero // NOTE: must be non zero // Enable SCD & ARDY interrupts
// Prescaler - need 7-12 Mhz on module clk
// Prescaler - need 7-12 Mhz on module clk
// Slave address - EEPROM control code
I2caRegs.I2CIER.all = 0x24;
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
//0b0000 0000 0010 0000,NACKMOD=0,FREE=0中断产生时IIC停止运行,STT=0不产生开始位,
//STP=0不产生停止位,MST=0从模式,TRX=0接收模式,XA=0 七位地址模式,RM=0不重复,DLB=0无回来 //IRS=1使能I2C模块,STB=0模块未处在开始字节模式,FDF=0自由数据格式被禁止 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=1读数据 I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return; }
Uint16 I2CA_WriteData(struct I2CMSG *msg) {
Uint16 i;
// 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; }
// 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++; } }
文案大全