DSP中i2c存儲eeprom實例分析_第1頁
DSP中i2c存儲eeprom實例分析_第2頁
DSP中i2c存儲eeprom實例分析_第3頁
DSP中i2c存儲eeprom實例分析_第4頁
DSP中i2c存儲eeprom實例分析_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1.示例程序中幾種狀態(tài)說明第一次看i2c_eeprom示例程序,對程序中的MsgStatus信息狀態(tài)切換非常懵懂,為什么要有這幾個狀態(tài)?狀態(tài)切換順序如何安排?一大堆的狀態(tài),讓人有些摸不著頭腦。先把程序中的頭文件涉及的7種狀態(tài)分析一下。//I2CMessageCommandsforI2CMSGstruct#defineI2C_MSGSTAT_INACTIVE0x0000//未激活狀態(tài):一般成功發(fā)送數(shù)據(jù)或者//接受數(shù)據(jù)后可以設(shè)置信息狀態(tài)為此狀態(tài),告訴用戶可進行下一次的寫數(shù)據(jù)或讀數(shù)據(jù)。#defineI2C_MSGSTAT_SEND_WITHSTOP0x0010//發(fā)送帶停止位數(shù)據(jù):這是為寫數(shù)據(jù)而設(shè)///的狀態(tài),寫入地址和數(shù)據(jù)之后發(fā)個停止位告訴存儲器數(shù)據(jù)寫入完畢。#defineI2C_MSGSTAT_WRITE_BUSY0x0011//寫數(shù)據(jù)忙狀態(tài):在將待寫的數(shù)據(jù)放入//緩存后,就可以使能IIC傳輸數(shù)據(jù)了,然后把信息狀態(tài)設(shè)為該狀態(tài),意在告訴用戶:數(shù)據(jù)//已經(jīng)在傳送過程中。當(dāng)然是否傳送完畢,還需要通過查詢SCD位來判斷。#defineI2C_MSGSTAT_SEND_NOSTOP0x0020//發(fā)送無停止位數(shù)據(jù):這個狀態(tài)是為了讀//取數(shù)據(jù)而設(shè)的,有查閱過AT24C1024EEPROM存儲器使用手冊的讀者知道,在讀數(shù)據(jù)之前//要發(fā)送數(shù)據(jù)的地址,發(fā)完地址不能產(chǎn)生停止位,這是存儲器硬件設(shè)計決定的。設(shè)為這個狀//態(tài)意在告訴讀者,可以發(fā)送要讀取的數(shù)據(jù)的地址了。#defineI2C_MSGSTAT_SEND_NOSTOP_BUSY0x0021//發(fā)送無停止位數(shù)據(jù)忙狀態(tài):這個狀態(tài)是//為了讀取數(shù)據(jù)而設(shè)的,似于I2C_MSGSTAT_WRITE_BUSY,說明地址數(shù)據(jù)已經(jīng)在傳送過程中。//傳送是否成功,還要看ARDY的狀態(tài)。#defineI2C_MSGSTAT_RESTART0x0022//重發(fā)開始位狀態(tài):這個狀態(tài)也是為讀取////數(shù)據(jù)而設(shè)。我們知道,讀取存儲器數(shù)據(jù)主要分兩個步驟:第一,發(fā)送START位+設(shè)備地址//+數(shù)據(jù)地址+無停止位。第二,再發(fā)START位+設(shè)備地址,緊接著存儲器發(fā)送數(shù)據(jù)到IIC接收//緩存器(I2CDRR),接收到設(shè)定好的數(shù)據(jù)數(shù)量(I2CCNT值)時輸出停止位STOP.//值得注意的是:理論上寫完數(shù)據(jù)就能馬上讀取數(shù)據(jù),但事實上EEPROM存儲器仍需要一////定延時來存儲數(shù)據(jù),約有2ms左右。通過示波器可以觀察到,寫完數(shù)據(jù)后,并不能馬上//成功讀取數(shù)據(jù),也就是說讀數(shù)據(jù)的第一步驟要重復(fù)好幾次(總線為50K時,大約要重復(fù)//8次)才能成功。#defineI2C_MSGSTAT_READ_BUSY0x0023//讀取數(shù)據(jù)忙狀態(tài):這個狀態(tài)是為讀取數(shù)//據(jù)而設(shè)。在讀數(shù)據(jù)的第二步驟中,發(fā)完START位+設(shè)備地址后,就設(shè)為這一狀態(tài)。意在說//明IIC開始等待接收固定數(shù)量(I2CCNT值)的數(shù)據(jù)。可以通過查詢ARDY位判斷。//頭文件中的其他定義應(yīng)該沒什么大問題了!2.AT24C1024EEPROM讀寫數(shù)據(jù)格式(1)AT24C1024設(shè)備地址:10100A1P0R/W(2)單字節(jié)寫入:START->發(fā)送從設(shè)備地址(寫控制碼R/W=0)->處理Ack->發(fā)送字節(jié)地址->處理Ack[->發(fā)送1字節(jié)數(shù)據(jù)->處理Ack]->STOP。如下圖:(3)按頁寫入:START->發(fā)送從設(shè)備地址(寫控制碼R/W=0)->處理Ack->發(fā)送字節(jié)地址->處理Ack[->發(fā)送1字節(jié)數(shù)據(jù)->處理Ack->發(fā)送第2字節(jié)數(shù)據(jù)->處理Ack->發(fā)送第3字節(jié)數(shù)據(jù)->處理Ack……直到發(fā)完X字節(jié)]->STOP。如下圖。注意,連續(xù)寫入的數(shù)據(jù)字節(jié)數(shù)不能超過每頁所能容下的總量。如果寫入的數(shù)據(jù)超過一頁的長度,將發(fā)生回卷,即從EEPROM的0地址處進行數(shù)據(jù)覆蓋。比如,AT24C1024有512頁,每頁最大容納256字節(jié)。超過這個長度,地址指針將從每頁首地址重新開始。(4)隨機單字節(jié)讀?。旱谝徊剑喊l(fā)START->發(fā)送從設(shè)備地址(寫控制碼R/W=0)->處理Ack->發(fā)送字節(jié)地址高位->處理Ack->發(fā)送字節(jié)地址低位->處理Ack->第二步:發(fā)START->發(fā)送器件地址(讀控制碼R/W=1)->處理Ack->接收1字節(jié)數(shù)據(jù)->STOP。(5)隨機連續(xù)讀?。涸陔S機單字節(jié)讀取操作的STOP信號發(fā)送之前,加入若干個[->發(fā)送Ack->接收1字節(jié)數(shù)據(jù)]即可實現(xiàn)。(6)當(dāng)前位置單字節(jié)讀取:START->發(fā)送從設(shè)備地址(讀控制碼)->處理Ack->發(fā)送字節(jié)地址->處理Ack->接收1字節(jié)數(shù)據(jù)->STOP。當(dāng)前指的是之前進行過讀取操作但是沒有發(fā)送STOP信號,EEPROM芯片內(nèi)部指針?biāo)诘奈恢眉礊楫?dāng)前位置。(7)當(dāng)前位置連續(xù)讀?。涸诋?dāng)前位置單節(jié)讀取操作的STOP信號發(fā)送之前,加入若干個[->發(fā)送Ack->接收1字節(jié)數(shù)據(jù)]即可實現(xiàn)。備注:部分內(nèi)容引用百度文庫中的《I2C讀寫流程》文檔3.主程序說明及流程圖詳細的注釋可以參見程序附錄,,這里主要解釋一下設(shè)備地址取0x50的緣由。從AT24C1024的數(shù)據(jù)手冊可知,設(shè)備地址為。而在程序中設(shè)置的地址是0x50,即0B01010000。看似不妥,其實,這個例子中設(shè)備地址采用7位地址模式,這樣只取0x50的低7位作為設(shè)備地址的高七位,設(shè)備地址的最低位R/W則由寄存器I2CMDR中的TRX位決定。這樣讀數(shù)據(jù)時設(shè)備地址為0B10100001,寫數(shù)據(jù)時設(shè)備地址改為0B10100000。通過示波器可以驗證這些數(shù)據(jù)。問題1:每次檢測到SCD中斷時,也就是順利發(fā)完指定數(shù)量的數(shù)據(jù)或者接收指定數(shù)量的數(shù)據(jù)了,理論上I2caRegs.I2CCNT==0,但是本人設(shè)了幾個中斷點去觀察該寄存器的值,發(fā)現(xiàn)總是不為零。通過觀察I2caRegs.I2CFFTX.bit.TXFFST和I2caRegs.I2CFFRX.bit.RXFFST,可以發(fā)現(xiàn)這兩個寄存器為零時,I2caRegs.I2CCNT也不為零。由此可知,I2CCNT不能實時反映發(fā)送/接收存儲器中數(shù)據(jù)的數(shù)量,不過可以用TXFFST/RXFFST來代替。圖1主程序流程圖,圖2為寫數(shù)據(jù)程序流程圖,圖3為讀數(shù)據(jù)程序流程圖,圖4為中斷函數(shù)流程圖。圖1主程序流程圖圖2寫數(shù)據(jù)程序流程圖圖3讀數(shù)據(jù)程序流程圖圖4中斷函數(shù)流程圖4.程序附錄//可以用以下代碼替換示例程序Example_280xI2c_eeprom.c中的代碼,再進行調(diào)試。////該程序跟原始程序沒多大區(qū)別,主要改變?yōu)椋阂霂讉€統(tǒng)計變量,改變發(fā)送數(shù)據(jù)長度為2字節(jié)////TIFile$Revision:/main/5$//Checkin$Date:April4,200717:18:36$//###########################################################################////FILE:Example_280xI2c_eeprom.c////TITLE:DSP280xI2CEEPROMExample////ASSUMPTIONS:////ThisprogramrequirestheDSP280xheaderfiles.////ThisprogramrequiresanexternalI2CEEPROMconnectedto//theI2Cbusataddress0x50.////Assupplied,thisprojectisconfiguredfor"boottoSARAM"http://operation.The280xBootModetableisshownbelow.//ForinformationonconfiguringthebootmodeofaneZdsp,//pleaserefertothedocumentationincludedwiththeeZdsp,////BootGPIO18GPIO29GPIO34//ModeSPICLKASCITXDA//SCITXB//-------------------------------------//Flash111//SCI-A110//SPI-A101//I2C-A100//ECAN-A011//SARAM010<-"boottoSARAM"http://OTP001//I/0000////DESCRIPTION:////Thisprogramwillwrite1-14wordstoEEPROMandreadthemback.//ThedatawrittenandtheEEPROMaddresswrittentoarecontained//inthemessagestructure,I2cMsgOut1.Thedatareadbackwillbe//containedinthemessagestructureI2cMsgIn1.//--------------------------------------------------------------//CODEMODIFICATIONSAREREQUIREDFOR60MHZDEVICES(In//DSP280x_Examples.hinthecommon/include/directory,set//#defineCPU_FRQ_60MHZto1,and#defineCPU_FRQ_100MHZto0).//--------------------------------------------------------------//Thisprogramwillworkwiththeon-boardI2CEEPROMsuppliedon//theF280xeZdsp.//////###########################################################################//OriginalAuthor:D.F.////$TIRelease:DSP280xHeaderFilesV1.60$//$ReleaseDate:December3,2007$//############################################################################include"DSP280x_Device.h"http://DSP280xHeaderfileIncludeFile#include"DSP280x_Examples.h"http://DSP280xExamplesIncludeFile//Note:I2CMacrosusedinthisexamplecanbefoundinthe//DSP280x_I2C_defines.hfile//Prototypestatementsforfunctionsfoundwithinthisfile.voidI2CA_Init(void);Uint16I2CA_WriteData(structI2CMSG*msg);Uint16I2CA_ReadData(structI2CMSG*msg);interruptvoidi2c_int1a_isr(void);voidpass(void);voidfail(void);#defineI2C_SLAVE_ADDR0x50//EEPROM地址#defineI2C_NUMBYTES2//為方便示波器觀察,設(shè)置發(fā)送2字節(jié)的數(shù)據(jù)#defineI2C_EEPROM_HIGH_ADDR0x11//數(shù)據(jù)的寫入地址高位#defineI2C_EEPROM_LOW_ADDR0x0F//數(shù)據(jù)的寫入地址低位//Globalvariables//全局變量//Twobyteswillbeusedfortheoutgoingaddress,//有2個字節(jié)是地址//thusonlysetup14bytesmaximum//最多只能設(shè)置14字節(jié)數(shù)據(jù)structI2CMSGI2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP,//初始狀態(tài)為:發(fā)送帶停止位數(shù)據(jù)I2C_SLAVE_ADDR,I2C_NUMBYTES,I2C_EEPROM_HIGH_ADDR,I2C_EEPROM_LOW_ADDR,0xff,//MsgByte010x3F,//MsgByte020x56,//MsgByte030x78,//MsgByte040x9A,//MsgByte050xBC,//MsgByte060xDE,//MsgByte070xF0,//MsgByte080x11,//MsgByte090x10,//MsgByte100x11,//MsgByte110x12,//MsgByte120x13,//MsgByte130x12, //MsgByte14};structI2CMSGI2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP,I2C_SLAVE_ADDR,I2C_NUMBYTES,I2C_EEPROM_HIGH_ADDR,I2C_EEPROM_LOW_ADDR};structI2CMSG*CurrentMsgPtr; //UsedininterruptsUint16PassCount;Uint16FailCount;Uint16ARDY_ISRC_NACK_number=0;//統(tǒng)計ARDY中斷源引起的中斷中NACK次數(shù)Uint16SCD_ISRC_number=0;//統(tǒng)計SCD中斷源引起的中斷次數(shù)Uint16ARDY_ISRC_number=0;//統(tǒng)計ARDY中斷源引起的中斷次數(shù)Uint16all_ISRC_number=0;//統(tǒng)計所有中斷源引起的中斷次數(shù)Uint16Write_load_num=0;//統(tǒng)計寫數(shù)據(jù)函數(shù)調(diào)用次數(shù)Uint16Read_load_num1=0;//統(tǒng)計讀數(shù)據(jù)函數(shù)調(diào)用次數(shù)1第一步驟Uint16Read_load_num2=0;//統(tǒng)計讀數(shù)據(jù)函數(shù)調(diào)用次數(shù)2第二步驟voidmain(void){Uint16Error;Uint16i;CurrentMsgPtr=&I2cMsgOut1;//Step1.InitializeSystemControl://PLL,WatchDog,enablePeripheralClocks//ThisexamplefunctionisfoundintheDSP280x_SysCtrl.cfile.InitSysCtrl();//Step2.InitalizeGPIO://ThisexamplefunctionisfoundintheDSP280x_Gpio.cfileand//illustrateshowtosettheGPIOtoit'sdefaultstate.//InitGpio();//SetuponlytheGPI/OonlyforI2CfunctionalityInitI2CGpio();//Step3.ClearallinterruptsandinitializePIEvectortable://DisableCPUinterruptsDINT;//InitializePIEcontrolregisterstotheirdefaultstate.//ThedefaultstateisallPIEinterruptsdisabledandflags//arecleared.//ThisfunctionisfoundintheDSP280x_PieCtrl.cfile.InitPieCtrl();//DisableCPUinterruptsandclearallCPUinterruptflags:IER=0x0000;IFR=0x0000;//InitializethePIEvectortablewithpointerstotheshellInterrupt//ServiceRoutines(ISR).//Thiswillpopulatetheentiretable,eveniftheinterrupt//isnotusedinthisexample.Thisisusefulfordebugpurposes.//TheshellISRroutinesarefoundinDSP280x_DefaultIsr.c.//ThisfunctionisfoundinDSP280x_PieVect.c.InitPieVectTable();//Interruptsthatareusedinthisexamplearere-mappedto//ISRfunctionsfoundwithinthisfile.EALLOW; //ThisisneededtowritetoEALLOWprotectedregistersPieVectTable.I2CINT1A=&i2c_int1a_isr;EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters//Step4.InitializealltheDevicePeripherals://ThisfunctionisfoundinDSP280x_InitPeripherals.c//InitPeripherals();//NotrequiredforthisexampleI2CA_Init();//Step5.Userspecificcode//ClearCountersPassCount=0;FailCount=0;//Clearincomingmessagebufferfor(i=0;i<I2C_MAX_BUFFER_SIZE;i++){I2cMsgIn1.MsgBuffer[i]=0x0000;}//Enableinterruptsrequiredforthisexample//EnableI2Cinterrupt1inthePIE:Group8interrupt1PieCtrlRegs.PIEIER8.bit.INTx1=1;//EnableCPUINT8whichisconnectedtoPIEgroup8IER|=M_INT8;EINT;//Applicationloopfor(;;){////////////////////////////////////WritedatatoEEPROMsection//////////////////////////////////////Checktheoutgoingmessagetoseeifitshouldbesent.//Inthisexampleitisinitializedtosendwithastopbit.if(I2cMsgOut1.MsgStatus==I2C_MSGSTAT_SEND_WITHSTOP){Write_load_num++;Error=I2CA_WriteData(&I2cMsgOut1);//Ifcommunicationiscorrectlyinitiated,setmsgstatustobusy//如果通信已經(jīng)正確初始化,設(shè)置msg狀態(tài)為’忙‘,并//andupdateCurrentMsgPtrfortheinterruptserviceroutine.//更新作為中斷服務(wù)路徑的指針CurrentMsgPtr。//Otherwise,donothingandtryagainnextloop.Oncemessageis//否則,不做任何操作,等待下一次重新寫數(shù)據(jù)。一旦信息正確//initiated,theI2Cinterruptswillhandletherest.Searchfor//初始化,I2C中斷將處理接下來的事情??梢栽?/ICINTR1A_ISRinthei2c_eeprom_isr.cfile.//i2c_eeprom_isr.c文件中找到ICINTR1A_ISR。if(Error==I2C_SUCCESS)//數(shù)據(jù)已成功放入緩存寄存器{CurrentMsgPtr=&I2cMsgOut1;//改變指針路徑I2cMsgOut1.MsgStatus=I2C_MSGSTAT_WRITE_BUSY;//設(shè)為發(fā)送數(shù)據(jù)忙狀態(tài)}}//endofwritesection/////////////////////////////////////ReaddatafromEEPROMsection//該過程包括兩次發(fā)送START位,第一次發(fā)送地址/////////////////////////////////////Checkoutgoingmessagestatus.Bypassreadsectionifstatusis//notinactive.if(I2cMsgOut1.MsgStatus==I2C_MSGSTAT_INACTIVE){//Checkincomingmessagestatus.if(I2cMsgIn1.MsgStatus==I2C_MSGSTAT_SEND_NOSTOP){Read_load_num1++;//EEPROMaddresssetupportionwhile(I2CA_ReadData(&I2cMsgIn1)!=I2C_SUCCESS){//Maybesetupanattemptcountertobreakaninfinitewhile//這里可以設(shè)置一個計數(shù)器用于終止可能存在的無限循環(huán)。//loop.TheEEPROMwillsendbackaNACKwhileitisperforming//當(dāng)EEPROM忙于處理寫數(shù)據(jù)操作時,將返回一個NACK。//awriteoperation.Eventhoughthewritecommuniqueis//對DSP來說,此刻寫操作已經(jīng)完成。但是,EEPROM仍需要//completeatthispoint,theEEPROMcouldstillbebusy//一定時間完成數(shù)據(jù)的燒寫1.8ms左右。在EEPROM完成燒寫之前,都會//programmingthedata.Therefore,multipleattemptsare//返回NACK,告訴DSP它還在忙。因此,DSP需要多次嘗試,直到//necessary.//EEPROM空閑了,并返回ACK確認為止。}//UpdatecurrentmessagepointerandmessagestatusCurrentMsgPtr=&I2cMsgIn1;I2cMsgIn1.MsgStatus=I2C_MSGSTAT_SEND_NOSTOP_BUSY;//第一次發(fā)送START成功,即地址數(shù)據(jù)已發(fā)送成功,給發(fā)無停止位數(shù)據(jù)忙狀態(tài),作為第二次發(fā)送START位標(biāo)志}//Oncemessagehasprogressedpastsettinguptheinternaladdress//一旦成功寫入EEPROM地址,便可以再次發(fā)送START起始位//oftheEEPROM,sendarestarttoreadthedatabytesfromthe//然后從EEPROM存儲器中讀取數(shù)據(jù)。//EEPROM.Completethecommuniquewithastopbit.MsgStatusis//DSP采可用一個停止位來結(jié)束數(shù)據(jù)接收。//updatedintheinterruptserviceroutine.//msg狀態(tài)在中斷程序中被更新了。elseif(I2cMsgIn1.MsgStatus==I2C_MSGSTAT_RESTART)//該狀態(tài)是在中斷服務(wù)程序中態(tài)被賦予{Read_load_num2++;//Readdataportionwhile(I2CA_ReadData(&I2cMsgIn1)!=I2C_SUCCESS){//Maybesetupanattemptcountertobreakaninfinitewhile//loop.}//UpdatecurrentmessagepointerandmessagestatusCurrentMsgPtr=&I2cMsgIn1;I2cMsgIn1.MsgStatus=I2C_MSGSTAT_READ_BUSY;//第二次發(fā)送START,且數(shù)據(jù)接收成功,給下一個狀態(tài)-讀忙,作為中斷中讀取接收緩存中數(shù)據(jù)的標(biāo)志}}//endofreadsection}//endoffor(;;)}//endofmainvoidI2CA_Init(void){//InitializeI2CI2caRegs.I2CSAR=0x0050; //Slaveaddress-EEPROMcontrolcode#if(CPU_FRQ_100MHZ)I2caRegs.I2CPSC.all=9; //Prescaler-need7-12Mhzonmoduleclk#endif#if(CPU_FRQ_60MHZ)I2caRegs.I2CPSC.all=6; //Prescaler-need7-12Mhzonmoduleclk#endifI2caRegs.I2CCLKL=95; //NOTE:mustbenonzeroI2caRegs.I2CCLKH=95; //NOTE:mustbenonzeroI2caRegs.I2CIER.all=0x24; //EnableSCD&ARDYinterruptsI2caRegs.I2CMDR.all=0x0020; //TakeI2Coutofreset //StopI2Cwhensuspended //0b0000000000100000,NACKMOD=0,F(xiàn)REE=0中斷產(chǎn)生時IIC停止運行,STT=0不產(chǎn)生開始位,//STP=0不產(chǎn)生停止位,MST=0從模式,TRX=0接收模式,XA=0七位地址模式,RM=0不重復(fù),DLB=0無回來//IRS=1使能I2C模塊,STB=0模塊未處在開始字節(jié)模式,FDF=0自由數(shù)據(jù)格式被禁止//注意:TRX決定AT24C1024設(shè)備地址中的R/W,這里R/W=1讀數(shù)據(jù)I2caRegs.I2CFFTX.all=0x6000; //EnableFIFOmodeandTXFIFOI2caRegs.I2CFFRX.all=0x2040; //EnableRXFIFO,clearRXFFINT,return;}Uint16I2CA_WriteData(structI2CMSG*msg){Uint16i;//WaituntiltheSTPbitisclearedfromanypreviousmastercommunication.//ClearingofthisbitbythemoduleisdelayeduntilaftertheSCDbitis//set.Ifthisbitisnotcheckedpriortoinitiatinganewmessage,the//I2Ccouldgetconfused.if(I2caRegs.I2CMDR.bit.STP==1){returnI2C_STP_NOT_READY_ERROR;}//SetupslaveaddressI2caRegs.I2CSAR=msg->SlaveAddress;//Checkifbusbusyif(I2caRegs.I2CSTR.bit.BB==1){returnI2C_BUS_BUSY_ERROR;}////////判斷總線空閑后進行數(shù)據(jù)發(fā)送//////////Setupnumberofbytestosend//MsgBuffer+AddressI2caRegs.I2CCNT=msg->NumOfBytes+2;//遞減//SetupdatatosendI2caRegs.I2CDXR=msg->MemoryHighAddr;I2caRegs.I2CDXR=msg->MemoryLowAddr;//for(i=0;i<msg->NumOfBytes-2;i++)for(i=0;i<msg->NumOfBytes;i++){I2caRegs.I2CDXR=*(msg->MsgBuffer+i);}//SendstartasmastertransmitterI2caRegs.I2CMDR.all=0x6E20;//按以下參數(shù)配置IIC并使能IIC//【0b0110111000100000,NACKMOD=0,F(xiàn)REE=1中斷產(chǎn)生時IIC能繼續(xù)運行,STT=1產(chǎn)生開始位】//【STP=1產(chǎn)生停止位,MST=1主模式,TRX=1發(fā)送,XA=0七位地址模式,RM=0不重復(fù),DLB=0無回路,IRS=1使能I2C模塊,STB=0,FDF=0】//開始發(fā)送數(shù)據(jù),I2CCNT遞減模式統(tǒng)計數(shù)據(jù)到達0時產(chǎn)生中斷,且產(chǎn)生停止位//注意:TRX決定AT24C1024設(shè)備地址中的R/W,這里R/W=0寫數(shù)據(jù)模式returnI2C_SUCCESS;}Uint16I2CA_ReadData(structI2CMSG*msg){//要完成一次讀數(shù)據(jù)任務(wù):要產(chǎn)生兩個START位,產(chǎn)生第1個START位之后發(fā)送設(shè)備地址和數(shù)據(jù)地址;//產(chǎn)生第2個START位之后寫入設(shè)備地址,并開始接收存儲器提供的數(shù)據(jù)。//WaituntiltheSTPbitisclearedfromanypreviousmastercommunication.//ClearingofthisbitbythemoduleisdelayeduntilaftertheSCDbitis//set.Ifthisbitisnotcheckedpriortoinitiatinganewmessage,the//I2Ccouldgetconfused.if(I2caRegs.I2CMDR.bit.STP==1){returnI2C_STP_NOT_READY_ERROR;}I2caRegs.I2CSAR=msg->SlaveAddress;if(msg->MsgStatus==I2C_MSGSTAT_SEND_NOSTOP)//產(chǎn)生第一個START位之后發(fā)送設(shè)備地址和數(shù)據(jù)地址////{//Checkifbusbusyif(I2caRegs.I2CSTR.bit.BB==1){returnI2C_BUS_BUSY_ERROR;}I2caRegs.I2CCNT=2;//設(shè)置發(fā)送數(shù)據(jù)字節(jié)數(shù)-遞減模式-等0時可以允許產(chǎn)生stop位(若使能STP)I2caRegs.I2CDXR=msg->MemoryHighAddr;//發(fā)送要讀取數(shù)據(jù)的開始地址I2caRegs.I2CDXR=(msg->MemoryLowAddr);I2caRegs.I2CMDR.all=0x2620; //按以下參數(shù)配置IIC并使能IIC //【STT=1發(fā)送起始位,STP=0不產(chǎn)生停止位,MST=1主模式,TRX=1發(fā)送,IRS=1使能I2C模塊】}//開始發(fā)送數(shù)據(jù)I2CCNT遞減模式統(tǒng)計數(shù)據(jù)到達0時產(chǎn)生中斷,但是沒有產(chǎn)生停止位//注意:TRX決定AT24C1024設(shè)備地址中的R/W,這里R/W=0寫數(shù)據(jù)elseif(msg->MsgStatus==I2C_MSGSTAT_RESTART)//產(chǎn)生第2個START位之后發(fā)送設(shè)備地址,然后開始接收存儲器提供的數(shù)據(jù)//{I2caRegs.I2CCNT=msg->NumOfBytes; //設(shè)置數(shù)據(jù)接收字節(jié)數(shù)量I2caRegs.I2CMDR.all=0x2C20; //按以下參數(shù)配置IIC并使能IIC //【STT=1發(fā)送起始位,STP=1產(chǎn)生停止位,MST=1主模式,TRX=0接收,IRS=1使能I2C模塊】}//開始接收數(shù)據(jù),I2CCNT遞減模式統(tǒng)計數(shù)據(jù)到達0時產(chǎn)生中斷,有產(chǎn)生停止位//注意-TRX決定AT24C1024設(shè)備地址中的R/W,這里R/W=1讀數(shù)據(jù)returnI2C_SUCCESS;//到此說明發(fā)送地址/讀取數(shù)據(jù)成功}interruptvoidi2c_int1a_isr(void)//I2C-A{Uint16IntSource,i;all_ISRC_number++;//統(tǒng)計所有中斷次數(shù)//ReadinterruptsourceIntSource=I2caRegs.I2CISRC.all;//Interruptsource=stopconditiondetectedif(IntSource==I2C_SCD_ISRC){SCD_ISRC_number++;//Ifcompletedmessagewaswritingdata,resetmsgtoinactivestateif(CurrentMsgPtr->MsgStatus==I2C_MSGSTAT_WRITE_BUSY){CurrentMsgPtr->MsgStatus=I2C_MSGSTAT_INACTIVE;//發(fā)送完成,便換為未啟動狀態(tài);說明可以進行下一次寫數(shù)據(jù)}else{//IfamessagereceivesaNACKduringtheaddresssetupportionofthe//EEPROMread,thecodefurtherbelowincludedintheregisteraccessready//interruptsourcecodewillgenerateastopcondition.Afterthestop//conditionisreceived(here),setthemessagestatustotryagain.//Usermaywanttolimitthenumberofretriesbeforegeneratinganerror.if(CurrentMsgPtr->MsgStatus==I2C_MSGSTAT_SEND_NOSTOP_BUSY)//發(fā)送無停止位地址忙{CurrentMsgPtr->MsgStatus=I2C_MSGSTAT_SEND_NOSTOP;//更新為發(fā)送停止位狀態(tài),可允許下一發(fā)送地址}//IfcompletedmessagewasreadingEEPROMdata,resetmsgtoinactivestate//andreaddatafromFIFO.elseif(CurrentMsgPtr->MsgStatus==I2C_MSGSTAT_READ_BUSY)//讀數(shù)據(jù)忙狀態(tài),說明可對接收緩存器I2CDRR進行接收數(shù)據(jù)讀取了{CurrentMsgPtr->MsgStatus=I2C_MSGSTAT_INACTIVE;//設(shè)為未啟狀態(tài)動,再讀數(shù)據(jù),這樣允許下一次寫數(shù)據(jù)到EEPROMfor(i=0;i<I2C_NUMBYTES;i++){CurrentMsgPtr->MsgBuffer[i]=I2caRegs.I2CDRR;}//Checkrecieveddata//讀完接收到的數(shù)據(jù),接下來

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論