DSP中i2c存储eeprom实例分析

上传人:daj****de 文档编号:120776399 上传时间:2022-07-18 格式:DOCX 页数:17 大小:224.86KB
返回 下载 相关 举报
DSP中i2c存储eeprom实例分析_第1页
第1页 / 共17页
DSP中i2c存储eeprom实例分析_第2页
第2页 / 共17页
DSP中i2c存储eeprom实例分析_第3页
第3页 / 共17页
点击查看更多>>
资源描述
1示例程序中几种状态说明第一次看i2c_eeprom示例程序,对程序中的MsgStatus信息状态切换非常懵懂,为什 么要有这几个状态?状态切换顺序如何安排? 一大堆的状态,让人有些摸不着头脑。先把程 序中的头文件-涉及的7种状态分析一下。/ I2C Message Commands for I2CMSG struct#define I2C_MSGSTAT_INACTIVE0x0000未激活状态:一般成功发送数据或者/接受数据后可以设置信息状态为此状态,告诉用户可进行下一次的写数据或读数据。#define I2C_MSGSTAT_SEND_WITHSTOP0x0010 /发送带停止位数据:这是为写数据而设/的状态,写入地址和数据之后发个停止位告诉存储器数据写入完毕。#define I2C_MSGSTAT_WRITE_BUSY0x0011 写数据忙状态:在将待写的数据放入/缓存后,就可以使能IIC传输数据了,然后把信息状态设为该状态,意在告诉用户:数据 /已经在传送过程中。当然是否传送完毕,还需要通过查询SCD位来判断。#define I2C_MSGSTAT_SEND_NOSTOP0x0020/发送无停止位数据:这个状态是为了读/取数据而设的,有查阅过AT24C1024EEPROM存储器使用手册的读者知道,在读数据之前 /要发送数据的地址,发完地址不能产生停止位,这是存储器硬件设计决定的。设为这个状 /态意在告诉读者,可以发送要读取的数据的地址了。#define I2C_MSGSTAT_SEND_NOSTOP_BUSY 0x0021/发送无停止位数据忙状态:这个状态是 /为了读取数据而设的,似于I2C_MSGSTAT_WRITE_BUSY,说明地址数据已经在传送过程中。 传送是否成功,还要看ARDY的状态。#define I2C_MSGSTAT_RESTART0x0022/重发开始位状态:这个状态也是为读取/数据而设。我们知道,读取存储器数据主要分两个步骤:第一,发送START位+设备地址 /+数据地址+无停止位。第二,再发START位+设备地址,紧接着存储器发送数据到IIC接收 缓存器(I2CDRR),接收到设定好的数据数量(I2CCNT值)时输出停止位STOP./值得注意的是:理论上写完数据就能马上读取数据,但事实上EEPROM存储器仍需要一 /定延时来存储数据,约有2ms左右。通过示波器可以观察到,写完数据后,并不能马上 /成功读取数据,也就是说读数据的第一步骤要重复好几次(总线为50K时,大约要重复 /8次)才能成功。#define I2C_MSGSTAT_READ_BUSY0x00237读取数据忙状态:这个状态是为读取数据而设。在读数据的第二步骤中,发完START位+设备地址后,就设为这一状态。意在说 /明IIC开始等待接收固定数量(I2CCNT值)的数据。可以通过查询ARDY位判断。/头文件中的其他定义应该没什么大问题了!2. AT24C1024 EEPROM读写数据格式(1)AT24C1024 设备地址:10100A1P0R/W(2)单字节写入:START -发送从设备地址(写控制码R/W=0)-处理Ack - 发送字节地址- 处理Ack -发送1字节数据- 处理Ack - STOP。如下 图:_ _STOPSDA LINEVJHIDEVICE TADDRESS FMOST SIGNIFICANT WORD ADDRESSLEASTSIGNIFICANT WORD ADDRESSMSBACKR/_wRoACKLSBACKLBACK(3)按页写入:START-发送从设备地址(写控制码R/W=0)-处理Ack -发 送字节地址- 处理Ack -发送1字节数据- 处理Ack-发送第2字节数 据- 处理Ack-发送第3字节数据- 处理Ack直到发完X字节- STOPo 如下图。注意,连续写入的数据字节数不能超过每页所能容下的总量。如果写入 的数据超过一页的长度,将发生回卷,即从EEPR0M的0地址处进行数据覆盖。 比如,AT24C1024有512页,每页最大容纳256字节。超过这个长度,地址指针 将从每页首地址重新开始。STARTDEVICEADDRESSTEWORD ADDRESS.WOHO ADDRESS (n)1 1 1 1 1 1 1 1 1 1 1 1111 IlliMOSTLEAST罰 GN IFICANTSliMPCANTDATA (n)STOP -MSBACKR/_w cPACKLSBACKL s BACKACK(4)随机单字节读取:第一步:发START -发送从设备地址(写控制码R/W=0) -处理Ack -发送字节地址高位- 处理Ack -发送字节地址低位- 处理 Ack-第二步:发START -发送器件地址(读控制码R/W=1)-处理Ack -接 收1字节数据- STOP。SDA L NEA MSBDEVICEADOAESSwriteHtgh ByteL咖ADDRESSAQDFtESSfl,STARTEVIGEADDHESSREADSTOPACKR/w- QPAck.LSBDATA n N口WHITE(5)随机连续读取:在随机单字节读取操作的STOP信号发送之前,加入若干个 -发送Ack -接收1字节数据即可实现。$0* LlKtRQEUICETT ADDFB9ELow 日ADDRESS:DEVICE R ADDRESShead)1PJWY WRITEackACKN-c ACK(6)当前位置单字节读取:START -发送从设备地址(读控制码)- 处理Ack -发送字节地址- 处理Ack -接收1字节数据- STOP。当前指的是之前 进行过读取操作但是没有发送STOP信号,EEPROM芯片内部指针所在的位置即为 当前位置。READ3口LINEDATA(7)当前位置连续读取:在当前位置单节读取操作的STOP信号发送之前,加入 若干个- 发送Ack -接收1字节数据即可实现。STARTREAD|q11 V r J 厂 1111|1IJJ|jdJ11li11111J1) J|I1JLl11cDATA nAC备注:部分内容引用百度文库中的I2C读写流程文档3.主程序说明及流程图详细的注释可以参见程序附录,这里主要解释一下设备地址取0x50的缘由。从AT24C1024的数据手册可知,设备地址为10100州Pa。而在程序中设置的地址是0x50,即0B0101 0000。看似不妥,其实,这个例子中设备地址采用7位地址 模式,这样只取0x5 0的低7位作为设备地址的高七位,设备地址的最低位R/W则由寄存器 I2CMDR中的TRX位决定。这样读数据时设备地址为0B1010 0001,写数据时设备地址改为 0B1010 0000。通过示波器可以验证这些数据。问题1:每次检测到SCD中断时,也就是顺利发完指定数量的数据或者接收指定数量的数据了, 理论上l2caRegs.l2CCNT=0,但是本人设了几个中断点去观察该寄存器的值,发现总是不为 零。通过观察 l2caRegs . I2CFFTX .bit. TXFFST 和 l2caRegs . l2CFFRX.bit .RXFFST, 可 以发现这两个寄存器为零时,l2caRegs . I2CCNT也不为零。由此可知,I2CCNT不能实时反映 发送/接收存储器中数据的数量,不过可以用TXFFST/RXFFST来代替。图1主程序流程图,图2为写数据程序流程图,图3为读数据程序流程图,图4为中断 函数流程图。a.更改当前指针为:I2cMsgInlb.令I2cMsgInl 状态=I2C MSGSTAT READ BUSYI2CA WriteData 函数返回:I2C STP NOT READY ERROR配置从设备地址返回 I2C BUS BUSY ERROR配置 I2CCNT;地址数据放入缓存;信息数据放入缓存:配置I2CMDR返回I2CSUCCESS图 1 主程序流程图图 2 写数据程序流程图图3 读数据程序流程图中断i2c_in/1a_isr获取中断源:IntS-Y令I2cMsgOu tl当前状态 =I2C MSGSTAT INACTIVE当前状态MSGSTAT WRITE中断源C SCDI2cMsgIn1当前状态MSGSTAT SEND NOSTOPNY令I2cMsgIn 1当前状态 =I2C MSGSTAT SEND NOSTOPI2cMsgIn1当前状态=I2C MSGSTAT READ BU令I2cMsgIn 1当前状态=i2c msgStat inactive从接收缓存器I2CDRR读取数据N -r彳进入fail死循环彳进入 Pass 死循环数据处理:计正确次数和错误次数中断返冋中断源停止仿真CK=1?设置IIC产生STOP位;清除NACK;N当前状态MSGSTAT SEND NOSTOP令当前状态-I2C MISGSTAT RE START图 4 中断函数流程图4.程序附录可以用以下代码替换示例程序Example_280xl2c_eeprom.c中的代码,再进行调试。/该程序跟原始程序没多大区别,主要改变为:引入几个统计变量,改变发送数据长度为2字节/ TI File $Revision: /main/5 $/ Checkin $Date: April 4, 2007 17:18:36 $/#/ FILE: Example_280xI2c_eeprom.c/ TITLE: DSP280x I2C EEPROM Example/ ASSUMPTIONS:/ This program requires the DSP280x header files./ This program requires an external I2C EEPROM connected to/ the I2C bus at address 0x50./As supplied, this project is configured for boot to SARAM/ operation. The 280x Boot Mode table is shown below./ For information on configuring the boot mode of an eZdsp,/please refer to the documentation included with the eZdsp,/ Boot GPIO18 GPIO29 GPIO34/Mode SPICLKA SCITXDA/Flash11/SCI-A11/SPI-A10/I2C-A10/ECAN-A01/SARAM01/OTP00/I/0000/SCITXB101010 - boot to SARAM1/ DESCRIPTION:/ This program will write 1-14 words to EEPROM and read them back. / The data written and the EEPROM address written to are contained / in the message structure, I2cMsgOut1. The data read back will be / contained in the message structure I2cMsgIn1./CODE MODIFICATIONS ARE REQUIRED FOR 60 MHZ DEVICES (In/ DSP280x_Examples.h in the common/include/ directory, set/#define CPU_FRQ_60MHZ to 1, and #define CPU_FRQ_100MHZ to 0)./ /This program will work with the on-board I2C EEPROM supplied on/ the F280x eZdsp./# / Original Author: D.F./ $TI Release: DSP280x Header Files V1.60 $/ $Release Date: December 3, 2007 $/#include DSP280x_Device.h / DSP280x Headerfile Include File#include DSP280x_Examples.h / DSP280x Examples Include File/ Note: I2C Macros used in this example can be found in the/ DSP280x_I2C_defines.h file/ Prototype statements for functions found within this file.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_ADDR0x50 /EEPROM 地址#define I2C_NUMBYTES2/ 为方便示波器观察,设置发送 2 字节的数据#define I2C_EEPROM_HIGH_ADDR0x11 /数据的写入地址高位#define I2C_EEPROM_LOW_ADDR0x0F /数据的写入地址低位/ Global variables/全局变量/ Two bytes will be used for the outgoing address,/有 2 个字节是地址/ thus only setup 14 bytes maximum/最多只能设置 14 字节数据struct I2CMSG l2cMsgOut1二I2C_MSGSTAT_SEND_WITHSTOP 初始状态为:发送带停止位数据I2C_SLAVE_ADDR,I2C_NUMBYTES,I2C_EEPROM_HIGH_ADDR,I2C_EEPROM_LOW_ADDR,0xff,/ Msg Byte 010x3F,/ Msg Byte 020x56,/ Msg Byte 030x78,/ Msg Byte 040x9A,/ Msg Byte 050xBC,/ Msg Byte 060xDE,/ Msg Byte 070xF0,/ Msg Byte 080x11,/ Msg Byte 090x10,/ Msg Byte 100x11,/ Msg Byte 110x12,/ Msg Byte 120x13,/ Msg Byte 130x12,/ Msg Byte 14;struct I2CMSG I2cMsgIn1= I2C_MSGSTAT_SEND_NOSTOP,I2C_SLAVE_ADDR,I2C_NUMBYTES,I2C_EEPROM_HIGH_ADDR,I2C_EEPROM_LOW_ADDR;struct I2CMSG *CurrentMsgPtr;/ Used in interruptsUint16 PassCount;Uint16 FailCount;Uint16 ARDY_ISRC_NACK_number=0; /统计 ARDY 中断源引起的中断中 NACK 次数Uint16 SCD_ISRC_number=0;统计SCD中断源引起的中断次数Uint16 ARDY_ISRC_number=0;/统计 ARDY 中断源引起的中断次数Uint16 all_ISRC_number=0;/统计所有中断源引起的中断次数Uint16 Write_load_num=0;/统计写数据函数调用次数Uint16 Read_load_num1=0;/统计读数据函数调用次数 1 第一步骤Uint16 Read_load_num2=0;/统计读数据函数调用次数 2 第二步骤void main(void)Uint16 Error;Uint16 i;CurrentMsgPtr = &I2cMsgOut1;/ Step 1. Initialize System Control:/ PLL, WatchDog, enable Peripheral Clocks / This example function is found in the DSP280x_SysCtrl.c file.InitSysCtrl();/ Step 2. Initalize GPIO:/ This example function is found in the DSP280x_Gpio.c file and/ illustrates how to set the GPIO to its default state./ InitGpio();/ Setup only the GP I/O only for I2C functionalityInitI2CGpio();/ Step 3. Clear all interrupts and initialize PIE vector table:/ Disable CPU interruptsDINT;/ Initialize PIE control registers to their default state./ The default state is all PIE interrupts disabled and flags/ are cleared./ This function is found in the DSP280x_PieCtrl.c file.InitPieCtrl();/ Disable CPU interrupts and clear all CPU interrupt flags:IER = 0x0000;IFR = 0x0000;/ Initialize the PIE vector table with pointers to the shell Interrupt/ Service Routines (ISR)./ This will populate the entire table, even if the interrupt/ is not used in this example. This is useful for debug purposes./ The shell ISR routines are found in DSP280x_DefaultIsr.c./ This function is found in DSP280x_PieVect.c.InitPieVectTable();/ Interrupts that are used in this example are re-mapped to/ ISR functions found within this file.EALLOW;/ This is needed to write to EALLOW protected registersPieVectTable.I2CINT1A = &i2c_int1a_isr;EDIS;/ This is needed to disable write to EALLOW protected registers/ Step 4. Initialize all the Device Peripherals:/ This function is found in DSP280x_InitPeripherals.c/ InitPeripherals(); / Not required for this exampleI2CA_Init();/ Step 5. User specific code/ Clear CountersPassCount = 0;FailCount = 0;/ Clear incoming message bufferfor (i = 0; i SlaveAddress;/ Check if bus busyif (I2caRegs.I2CSTR.bit.BB = 1)return I2C_BUS_BUSY_ERROR;/判断总线空闲后进行数据发送/ Setup number of bytes to send/ MsgBuffer + AddressI2caRegs.I2CCNT = msg-NumOfBytes+2; /递减/ Setup data to sendI2caRegs.I2CDXR = msg-MemoryHighAddr;I2caRegs.I2CDXR = msg-MemoryLowAddr;/ for (i=0; iNumOfBytes-2; i+)for (i=0; iNumOfBytes; i+)I2caRegs.I2CDXR = *(msg-MsgBuffer+i);/ Send start as master transmitterI2caRegs.I2CMDR.all = 0x6E20; / 按以下参数配置 IIC 并使能 IIC/【ObOIIO 1110 0010 OOOO, 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 busyif (I2caRegs.I2CSTR.bit.BB = 1)return I2C_BUS_BUSY_ERROR;l2caRegs.l2CCNT = 2;/设置发送数据字节数-递减模式-等0时可以允许产生stop位(若使能STP)l2caRegs.l2CDXR = msg-MemoryHighAddr; 发送要读取数据的开始地址l2caRegs.l2CDXR = (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)/y产生第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-AUint16 IntSource, i;all_ISRC_number+; 统计所有中断次数/ Read interrupt sourceIntSource = 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 stateif (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_N0ST0P_BUSY)发送无停止位地址忙CurrentMsgPtr-MsgStatus = I2C_MSGSTAT_SEND_N0ST0P;更新为发送停止位状态,可允许下一发送地址/ 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;/设为未启状态动,再读数据,这样允许下一次写数据到 EEPROMfor(i=0; i MsgBufferi = I2caRegs.I2CDRR;/ Check recieved data /读完接收到的数据,接下来进行判断数据是否准确for(i=0; i MsgStatus = l2C_MSGSTAT_SEND_NOSTOP_BUSY)CurrentMsgPtr-MsgStatus = I2C_MSGSTAT_RESTART;/更新为重发 START位状态,为接收数据准备 / end of register access readyelse/ Generate some error due to invalid interrupt source asm( ESTOP0);/ Enable future I2C (PIE Group 8) interruptsPieCtrlRegs.PIEACK.all = PIEACK_GROUP8; /重启中断允许void pass()asm( ESTOP0);for(;);void fail()asm( ESTOP0);for(;);/=
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!