DSPIC接口应用.docx

上传人:b****2 文档编号:24396688 上传时间:2023-05-27 格式:DOCX 页数:23 大小:28.19KB
下载 相关 举报
DSPIC接口应用.docx_第1页
第1页 / 共23页
DSPIC接口应用.docx_第2页
第2页 / 共23页
DSPIC接口应用.docx_第3页
第3页 / 共23页
DSPIC接口应用.docx_第4页
第4页 / 共23页
DSPIC接口应用.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

DSPIC接口应用.docx

《DSPIC接口应用.docx》由会员分享,可在线阅读,更多相关《DSPIC接口应用.docx(23页珍藏版)》请在冰豆网上搜索。

DSPIC接口应用.docx

DSPIC接口应用

DSPI2C应用说明

1.示例程序中几种状态

第一次看i2c_eeprom示例程序,对程序中的MsgStatus信息状态切换非常懵懂,为什么要有这几个状态?

状态切换顺序如何安排?

一大堆的状态,让人有些摸不着头脑。

先把程序中的头文件

涉及的7种状态分析一下。

//I2CMessageCommandsforI2CMSGstruct

#defineI2C_MSGSTAT_INACTIVE0x0000//未激活状态:

一般成功发送数据或者//接受数据后可以设置信息状态为此状态,告诉用户可进行下一次的写数据或读数据。

#defineI2C_MSGSTAT_SEND_WITHSTOP0x0010//发送带停止位数据:

这是为写数据而设///的状态,写入地址和数据之后发个停止位告诉存储器数据写入完毕。

#defineI2C_MSGSTAT_WRITE_BUSY0x0011//写数据忙状态:

在将待写的数据放入//缓存后,就可以使能IIC传输数据了,然后把信息状态设为该状态,意在告诉用户:

数据//已经在传送过程中。

当然是否传送完毕,还需要通过查询SCD位来判断。

#defineI2C_MSGSTAT_SEND_NOSTOP0x0020//发送无停止位数据:

这个状态是为了读//取数据而设的,有查阅过AT24C1024EEPROM存储器使用手册的读者知道,在读数据之前//要发送数据的地址,发完地址不能产生停止位,这是存储器硬件设计决定的。

设为这个状//态意在告诉读者,可以发送要读取的数据的地址了。

#defineI2C_MSGSTAT_SEND_NOSTOP_BUSY0x0021//发送无停止位数据忙状态:

这个状态是//为了读取数据而设的,似于I2C_MSGSTAT_WRITE_BUSY,说明地址数据已经在传送过程中。

//传送是否成功,还要看ARDY的状态。

#defineI2C_MSGSTAT_RESTART0x0022//重发开始位状态:

这个状态也是为读取

////数据而设。

我们知道,读取存储器数据主要分两个步骤:

第一,发送START位+设备地址

//+数据地址+无停止位。

第二,再发START位+设备地址,紧接着存储器发送数据到IIC接收

//缓存器(I2CDRR),接收到设定好的数据数量(I2CCNT值)时输出停止位STOP.

//值得注意的是:

理论上写完数据就能马上读取数据,但事实上EEPROM存储器仍需要一

////定延时来存储数据,约有2ms左右。

通过示波器可以观察到,写完数据后,并不能马上

//成功读取数据,也就是说读数据的第一步骤要重复好几次(总线为50K时,大约要重复

//8次)才能成功。

#defineI2C_MSGSTAT_READ_BUSY0x0023//读取数据忙状态:

这个状态是为读取数

//据而设。

在读数据的第二步骤中,发完START位+设备地址后,就设为这一状态。

意在说//明IIC开始等待接收固定数量(I2CCNT值)的数据。

可以通过查询ARDY位判断。

//头文件中的其他定义应该没什么大问题了!

2.AT24C1024EEPROM读写数据格式

(1)AT24C1024设备地址:

1

0

1

0

0

A1

P0

R/W

(2)单字节写入:

START->发送从设备地址(写控制码R/W=0)->处理Ack->发送字节地址->处理Ack[->发送1字节数据->处理Ack]->STOP。

如下图:

(3)按页写入:

START->发送从设备地址(写控制码R/W=0)->处理Ack->发送字节地址->处理Ack[->发送1字节数据->处理Ack->发送第2字节数据->处理Ack->发送第3字节数据->处理Ack……直到发完X字节]->STOP。

如下图。

注意,连续写入的数据字节数不能超过每页所能容下的总量。

如果写入的数据超过一页的长度,将发生回卷,即从EEPROM的0地址处进行数据覆盖。

比如,AT24C1024有512页,每页最大容纳256字节。

超过这个长度,地址指针将从每页首地址重新开始。

(4)随机单字节读取:

第一步:

发START->发送从设备地址(写控制码R/W=0)->处理Ack->发送字节地址高位->处理Ack->发送字节地址低位->处理Ack->第二步:

发START->发送器件地址(读控制码R/W=1)->处理Ack->接收1字节数据->STOP。

(5)随机连续读取:

在随机单字节读取操作的STOP信号发送之前,加入若干个[->发送Ack->接收1字节数据]即可实现。

(6)当前位置单字节读取:

START->发送从设备地址(读控制码)->处理Ack->发送字节地址->处理Ack->接收1字节数据->STOP。

当前指的是之前进行过读取操作但是没有发送STOP信号,EEPROM芯片内部指针所在的位置即为当前位置。

(7)当前位置连续读取:

在当前位置单节读取操作的STOP信号发送之前,加入若干个[->发送Ack->接收1字节数据]即可实现。

备注:

部分内容引用XX文库中的《I2C读写流程》文档

3.主程序说明及流程图

详细的注释可以参见程序附录,,这里主要解释一下设备地址取0x50的缘由。

从AT24C1024的数据手册可知,设备地址为

而在程序中设置的地址是0x50,即0B01010000。

看似不妥,其实,这个例子中设备地址采用7位地址模式,这样只取0x50的低7位作为设备地址的高七位,设备地址的最低位R/W则由寄存器I2CMDR中的TRX位决定。

这样读数据时设备地址为0B10100001,写数据时设备地址改为0B10100000。

通过示波器可以验证这些数据。

问题1:

每次检测到SCD中断时,也就是顺利发完指定数量的数据或者接收指定数量的数据了,理论上I2caRegs.I2CCNT==0,但是本人设了几个中断点去观察该寄存器的值,发现总是不为零。

通过观察I2caRegs.I2CFFTX.bit.TXFFST和I2caRegs.I2CFFRX.bit.RXFFST,可以发现这两个寄存器为零时,I2caRegs.I2CCNT也不为零。

由此可知,I2CCNT不能实时反映发送/接收存储器中数据的数量,不过可以用TXFFST/RXFFST来代替。

图1主程序流程图,图2为写数据程序流程图,图3为读数据程序流程图,图4为中断函数流程图。

图1主程序流程图

图2写数据程序流程图图3读数据程序流程图

图4中断函数流程图

4.程序附录

//可以用以下代码替换示例程序Example_280xI2c_eeprom.c中的代码,再进行调试。

//

//该程序跟原始程序没多大区别,主要改变为:

引入几个统计变量,改变发送数据长度为2字节//

//TIFile$Revision:

/main/5$

//Checkin$Date:

April4,200717:

18:

36$

//###########################################################################

//

//FILE:

Example_280xI2c_eeprom.c

//

//TITLE:

DSP280xI2CEEPROMExample

//

//ASSUMPTIONS:

//

//ThisprogramrequirestheDSP280xheaderfiles.

//

//ThisprogramrequiresanexternalI2CEEPROMconnectedto

//theI2Cbusataddress0x50.

//

//Assupplied,thisprojectisconfiguredfor"boottoSARAM"

//operation.The280xBootModetableisshownbelow.

//ForinformationonconfiguringthebootmodeofaneZdsp,

//pleaserefertothedocumentationincludedwiththeeZdsp,

//

//BootGPIO18GPIO29GPIO34

//ModeSPICLKASCITXDA

//SCITXB

//-------------------------------------

//Flash111

//SCI-A110

//SPI-A101

//I2C-A100

//ECAN-A011

//SARAM010<-"boottoSARAM"

//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"//DSP280xHeaderfileIncludeFile

#include"DSP280x_Examples.h"//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//为方便示波器观察,设置发送2字节的数据

#defineI2C_EEPROM_HIGH_ADDR0x11//数据的写入地址高位

#defineI2C_EEPROM_LOW_ADDR0x0F//数据的写入地址低位

//Globalvariables//全局变量

//Twobyteswillbeusedfortheoutgoingaddress,//有2个字节是地址

//thusonlysetup14bytesmaximum//最多只能设置14字节数据

structI2CMSGI2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP,//初始状态为:

发送带停止位数据

I2C_SLAVE_ADDR,

I2C_NUMBYTES,

I2C_EEPROM_HIGH_ADDR,

I2C_EEPROM_LOW_ADDR,

0xff,//MsgByte01

0x3F,//MsgByte02

0x56,//MsgByte03

0x78,//MsgByte04

0x9A,//MsgByte05

0xBC,//MsgByte06

0xDE,//MsgByte07

0xF0,//MsgByte08

0x11,//MsgByte09

0x10,//MsgByte10

0x11,//MsgByte11

0x12,//MsgByte12

0x13,//MsgByte13

0x12,//MsgByte14

};

structI2CMSGI2cMsgIn1={I2C_MSGSTAT_SEND_NOSTOP,

I2C_SLAVE_ADDR,

I2C_NUMBYTES,

I2C_EEPROM_HIGH_ADDR,

I2C_EEPROM_LOW_ADDR};

structI2CMSG*CurrentMsgPtr;//Usedininterrupts

Uint16PassCount;

Uint16FailCount;

Uint16ARDY_ISRC_NACK_number=0;//统计ARDY中断源引起的中断中NACK次数

Uint16SCD_ISRC_number=0;//统计SCD中断源引起的中断次数

Uint16ARDY_ISRC_number=0;//统计ARDY中断源引起的中断次数

Uint16all_ISRC_number=0;//统计所有中断源引起的中断次数

Uint16Write_load_num=0;//统计写数据函数调用次数

Uint16Read_load_num1=0;//统计读数据函数调用次数1第一步骤

Uint16Read_load_num2=0;//统计读数据函数调用次数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/OonlyforI2Cfunctionality

InitI2CGpio();

//Step3.ClearallinterruptsandinitializePIEvectortable:

//DisableCPUinterrupts

DINT;

//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;//ThisisneededtowritetoEALLOWprotectedregisters

PieVectTable.I2CINT1A=&i2c_int1a_isr;

EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters

//Step4.InitializealltheDevicePeripherals:

//ThisfunctionisfoundinDSP280x_InitPeripherals.c

//InitPeripherals();//Notrequiredforthisexample

I2CA_Init();

//Step5.Userspecificcode

//ClearCounters

PassCount=0;

FailCount=0;

//Clearincomingmessagebuffer

for(i=0;i

{

I2cMsgIn1.MsgBuffer[i]=0x0000;

}

//Enableinterruptsrequiredforthisexample

//EnableI2Cinterrupt1inthePIE:

Group8interrupt1

//EnableCPUINT8whichisconnectedtoPIEgroup8

IER|=M_INT8;

EINT;

//Applicationloop

for(;;)

{

//////////////////////////////////

//WritedatatoEEPROMsection//

//////////////////////////////////

//Checktheoutgoingmessagetoseeifitshouldbesent.

//Inthisexampleitisinitializedtosendwithastopbit.

if(I2cMsgOut1.MsgStatus==I2C_MSGSTAT_SEND_WITHSTOP)

{Write_load_num++;

Error=I2CA_WriteData(&I2cMsgOut1);

//Ifcommunicationiscorrectlyinitiated,setmsgstatustobusy//如果通信已经正确初始化,设置msg状态为’忙‘,并

//andupdateCurrentMsgPtrfortheinterruptserviceroutine.//更新作为中断服务路径的指针CurrentMsgPtr。

//Otherwise,donothingandtryagainnextloop.Oncemessageis//否则,不做任何操作,等待下一次重新写数据。

一旦信息正确

//initiated,theI2Cinterruptswillhandletherest.Searchfor//初始化,I2C中断将处理接下来的事情。

可以在

//ICINTR1A_ISRinthei2c_eeprom_isr.cfile.//i2c_eeprom_isr.c文件中找到ICINTR1A_ISR。

if(Error==I2C_SUCCESS)//数据已成功放入缓存寄存器

{

CurrentMsgPtr=&I2cMsgOut1;//改变指针路径

I2cMsgOut1.MsgStatus=I2C_MSGSTAT_WRITE_BUSY;//设为发送数据忙状态

}

}//endofwritesection

///////////////////////////////////

//ReaddatafromEEPROMsection//该过程包括两次发送START位,第一次发送地址

///////////////////////////////////

//Checkoutgoingmessagestatus.Bypassreadsect

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 临床医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1