通信与电子系统综合设计实验报告--6系(共25页).docx
-
资源ID:14416851
资源大小:2.39MB
全文页数:25页
- 资源格式: DOCX
下载积分:20金币
快捷下载
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
通信与电子系统综合设计实验报告--6系(共25页).docx
精选优质文档-倾情为你奉上 通信与电子系统综合设计院系: 信息学院6系 姓名: 学号: 邮箱: cxxie 手机: 2013年12月27日设计一 实现FPGA对CPLD外设的全部利用实验要求 编写CPLD程序控制其外设(LED,数码管,输入开关等),并全部提供给FPGA使用 编写CPLD与FPGA(XC2V2000)的接口电路,实现FPGA与CPLD外设的直接对应关系. 编写FPGA程序测试CPLD的全部外设实验说明1.硬件分析本次实验涉及的硬件包括:4个脉冲触发开关、8个拨码开关、8个7段数码管、32个LED发光二极管以及如图1.1所示的CPLD和FPGA芯片。0/1开关 8位脉冲开关 4位LED 32位数码管 8位Xilinx CPLDXC95114XLXilinx FPGAXC2V2000图1.1 硬件连接图2.实验要求分析要求通过FPGA对CPLD的全部外设进行控制,如果不进行编码则需要4+8+32+16=60根连接线,而实际只有23条,在这种情况下,对于8位拨码开关,可以在CPLD中对进行并串转换,8位需要3位地址线,再用一位表示指定地址的拨码开关的状态,这样就可以用4位将8位拨码开关信号传输到FPGA,在FPGA中将4位表示拨码开关的信号进行串并转换,得到8位信号,然后用这8位信号控制8个7段数码管,用高4位信号表示段码,再用低四位实现功能控制,最多有16种。对于4个脉冲开关,可直接传输,在FPGA中,用这4位信号实现对32位LED发光二极管进行控制;此外,8个7段数码管,需要3根地址线和4根数据线,32个LED发光二极管,需要5根地址线和1位状态位,状态位用来表示指定地址的LED的状态。通过上述分析,总共需要4+4+3+4+5+1=21根连接线,不超过实际的23条连接线,所以上述方案是可实现的。图1.2为FPGA控制CPLD外设的结构示意图。4位脉冲开关信号,4位拨码开关信号(先并串转换在串并转换)外设CPLDFPGALED控制信号(5位地址+1位状态)数码管控制信号(3位位选+4位段码)CPLD和外设连接图1.2 FPGA控制CPLD外设的结构示意图设计方案1. CPLD程序设计CPLD程序分为以下几个功能模块:首先对八位拨码开关信号进行并串转换传输到FPGA中;对脉冲开关信号进行处理,每按一次脉冲开关,经过程序处理得到0或1传输到FPGA;对FPGA传输过来的5位LED地址、数码管3位位选信号和4位段码信号进行译码然后将译码之后的信号传输到外设。CPLD程序主要结构图如如1.3所示。图1.3 CPLD程序结构图a) 并串转换8位拨码开关信号进入CPLD后对其进行并串转换,转换后用4位信号表示,其中高3位表示拨码开关地址,最低位表示开关的状态。在程序模块,用一个3位计数器,每一次时钟上升沿到来时计数器加1,然后根据计数器的值进行选择转换,程序如下:process(clk,dip,counter)beginif(clk'event and clk='1')thenif counter>="111" thencounter<="000"elsecounter<=counter+1;end if;end if;case counter iswhen "000" => dip_sw<="000"&dip(0);when "001" => dip_sw<="001"&dip(1);when "111" => dip_sw<="111"&dip(7);when others =>dip_sw<="111"&dip(7);end case;end process;b) 脉冲开关信号处理每按一次脉冲开关,对其脉冲信号进行处理,得到1位信号0或1然后传输到FPGA。其处理的程序如下(4个脉冲开关处理过程一样):process(key1)variable K1 : std_logic;beginif key1'event and key1='1' then K1:=not(K1);end if;pul_sw1<=K1;end process;c)LED地址译码 5位LED地址信号和1位LED状态信号从FPGA传输到CPLD后要对其进行译码,其代码如下:process(clk)begin if clk'event and clk='1' thencase led_addr is when "00000" => led(0)<=led_val; when "00001" => led(1)<=led_val;when "11110" => led(30)<=led_val;when others => led(31)<=led_val;end case;end if;end process;d) 数码管位选和段码译码 FPGA传输过来的3位位选信号和4位段码信号,需要在CPLD中对其进行译码,然后直接传输到外设。其代码见附录中实验1的CPLD完整代码。2. FPGA程序设计在FPGA程序中,首先要对系统48MHz时钟进行两次分频得到10KHz和1Hz的时钟,其中10KHz时钟用于LED和数码管进程控制,1Hz时钟用于循环功能控制;其次要对CPLD传输过来的拨码开关的4位串行信号进行串并转换得到8位信号;LED驱动模块包括LED功能控制进程、LED循环控制进程以及计数最大为32的计数器(在进程中指定LED的位置);数码管驱动模块包括数码管功能控制进程、数码管循环控制进程和一个32bit计数器。由于FPGA的VHDL代码较长,见附录中实验1的FPGA完整代码。图1.4为FPGA程序结构图。3位脉冲信号LED循环控制进程数码管进程控制模块数码管循环控制进程LED功能控制进程4位串行信号串并转换 1Hz时钟计数器 1Hz时钟10KHz时钟 10KHz时钟 32位计数器 图1.4 FPGA程序结构图a) 时钟分频FPGA硬件系统接的时钟频率是48MHz,在程序中要对其进行分频。通过两次分频得到频率为10KHz和1Hz的时钟。10KHz主要用于LED和数码管的动态扫描;1Hz的时钟用于LED和数码管的循环功能。b)LED功能控制模块 标号为pul_s1、pul_s2、pul_s3和pul_s4的用于对LED的控制。pul_s2和pul_s1组成2位二进制数用于表示LED实现何种功能;pul_s3用于计数值最大为32的计数器的触发控制,pul_s3每按下一次计数器计数值(LED_cnt)加1,用于指定LED的地址;pul_s4用于功能实现中子功能的选择。四个脉冲开发和LED功能的关系如表1.1。表1.1 四个脉冲开关与LED功能对应关系c)数码管功能控制模块拨码开关4位串行信号在FPGA中转换成8位并行信号dip(7 downto 0)后用于控制数码管功能实现。高四位dip(7 downto 4)用作功能状态位,可以实现16种功能,但在本程序中只设计了7种功能;低四位dip(3 downto 0)用于数码管段码控制;此外,数码管的其中两个功能是关于计数器counter的,8个数码管显示32位计数器加减计数,计数器每隔1秒加1或减1。dip(7 downto 0)与数码管的功能如表1.2所示。表1.2 dip与数码管功能的关系设计结果因为这个实验分为CPLD设计和FPGA设计,故实验程序仿真也分为两部分。1. CPLD仿真图1.5黄颜色部分是8位拨码开关信号并串转换的波形,每个时钟上升沿是转换其中一位,每完成一次转换需要8个时钟周期;蓝颜色和淡粉色的部分分别是4位段码信号和3位位选信号的译码。图1.5 CPLD仿真波形1图1.6是LED地址译码过程,每个时钟上升沿到来时将led_value的值赋给指定地址的LED,每完成一次需要32个时钟周期。图1.6 CPLD仿真波形22. FPGA仿真图1.7是LED功能的仿真波形,包括全亮、全灭和循环移动的仿真波形。图1.7 LED功能仿真波形图1.8至图1.11是数码管各个功能的仿真波形,具体功能见图下方的标注。图1.8 数码管循环移动功能图1.9 数码管显示7(可设置)并循环移动图 1.10 数码管显示32位16进制计数器图1.11 数码管静态显示FDB75310设计总结本次实验由于涉及到CPLD和FPGA的综合设计,所以花费的时间比较长。其中CPLD的设计较为简单,基本是并串转换和译码之类的;而FPGA的设计相对来说复杂很多,主要是其包含了LED和数码管各种功能的设计。在设计过程中,代码的设计看似逻辑正确,但在硬件上实现的时候结果却不是原本所期望的,比较深的感受是,一开始把LED和数码管循环控制的代码都放在LED、数码管功能控制进程中,但却不能实现循环功能,后来分别设计了一个LED和数码管的循环控制子进程,时钟选用1Hz,然后让其和主功能模块连接起来就达到预期的目标了。设计二 AD/DA控制及ChipScope使用实验要求 FPGA控制AD/DA双通道最高速度下工作 学习ChipScope分析工具,并利用其观看AD或DA数字接口的数据实验说明本实验中用到的AD芯片AD9021和DA芯片AD9761都有两个通道(I通道和Q通道),用信号发生器产生两路不同(幅度、频率或波形不同)的信号分别接至AD9021的I通道和Q通道,AD9021的输出信号进入FPGA中经过相应处理传送到AD9761的输入端,经过AD9761数模转换处理之后得到两路模拟信号分别从I通道和Q通道输出,然后接至示波器的两个观测通道,观察波形。整个系统的硬件结构图如图2.1所示。I低通滤波器信号发生器1V直流偏置AD: AD9021Xilinx FPGAXC2V2000 -4 FG676Q低通滤波器1V直流偏置I示波器差分转单端DA: AD9761Q差分转单端图2.1 系统硬件结构图设计方案在设计之前,首先要了解模数转换芯片AD9021和数模转换芯片AD9761的参数和工作原理,之后才能做进一步的设计。1.AD9021与AD9761的简单介绍a)模数转换芯片AD9021AD9201 是一个双通道、10-bit CMOS 模数转换器(ADC),采样速度为20MSPS。 图2.2给出了AD9021的功能框图,包括 2个10-bit、20MSPS 的 ADC,2个输入缓存放大器,一个内部参考电压和复用的数字输出缓存器。图2.2 AD9021的功能框图AD9201 内部集成了 2个ADC、2个模拟输入缓冲器、一个内部基准和基准缓冲器,以及一个输出复用器(multiplexer)。2个 ADC 分别用 I 通道和 Q 通道来表示,它们在输入时钟的上升沿同时对各自的输入信号进行采样。每个 ADC 都有自己的输出寄存器,寄存器的内容在输入时钟的上升沿更新。两个 ADC 寄存器中的结果是通过 SELECT 信号来进行选择的,从图 2.2 中可以看出,SELECT 为低电平时,选择 Q 通道输出;SELECT 为高电平时,选择 I通道输出。图2.3 AD9021时序图b)数模转换芯片AD9761AD9761 是一种双通道、高速、10-bit 的CMOS 数模转换器(DAC),特别适用于包括 I 路和 Q 路数字信息处理的宽带通信应用场合(例如扩频通信)。AD9761 集成了两个 10-bit、40MSPS 的 DAC,两个2倍插值滤波器,一个参考电源和数字输入接口电路,如图2.4所示。该器件支持两个输入通道,每个通道的数据率为 20MSPS,经过两倍的插值,使得两个DAC同时输出最高达40 MSPS 的数据。图2.4 AD9761功能框图图2.5给出了AD9761 的工作时序图。在 DAC 的输入数据线 DB9DB0上,I 路和 Q 路数据交替输入。SELECT 为 I 路和 Q 路的选择信号,当 SELECT为高电平时,输入数据送 I 路的 DAC,当 SELECT 为低电平时,输入数据送 Q路的 DAC。WRITE 信号是写输入信号。DAC 的输入寄存器在 WRITE 的上升沿锁存数据。CLOCK 是时钟信号。两个 DAC 的输出都在 CLOCK 的上升沿更新,同时数字滤波器分别读取各自的输入寄存器。图 2.5 中,CLOCK的上升沿比WRITE 的上升沿延迟tCINV,但 CLOCK 和 WRITE 也可以连接在一起。图2.5 AD9761功能框图2.FPGA设计简单介绍完AD9021和AD9671的功能和时序后,就可以进一步进行FPGA设计。首先要考虑AD9021和AD9761的时钟问题,因为AD9201 是一个双通道、10-bit CMOS 模数转换器(ADC),采样速度为20MSPS,所以可以采用频率为20Mhz的时钟, AD9021的SELECT的频率也为20MHz,每个ADC都有自己的输出寄存器,寄存器的内容在输入时钟的上升沿更新,两个ADC寄存器中的结果是通过 SELECT 信号来进行选择的,从图 2.3 中可以看出,SELECT为低电平时,选择 Q 通道输出;SELECT为高电平时,选择I通道输出。对于AD9761,时钟的频率可以选择为40MHz,因为AD9761集成了两个10bit、40MSPS的DAC,该器件支持两个输入通道,这样每个通道的数据率为20MSPS,经过两倍的插值,使得两个DAC同时输出最高达40MSPS的数据,同时AD9761的SELECT的输入也选择为20MHz的时钟。由上述可知,在FPGA设计中需要用到频率分别为40MHz和20MHz的时钟,而FPGA选择的时钟频率为48MHz,需要对其分频或倍频。在FPGA中添加一个IP核用于生成40MHz的时钟,IP核的参数设置如图2.6所示。图2.6 时钟IP核的参数设置然后对生成的40MHz的时钟进行二分频便得到20MHz的时钟,其二分频代码如下。process(clk40Mhz)beginif clk40Mhz'event and clk40Mhz='1' then clk20Mhz<=not(clk20Mhz);end if;end process;FPGA中对于各种输入信号设置如下。ADC_CS <= '0'ADC_SLEEP <= '0'DAC_RST <= '0'ADC_CLOCK<=clk20Mhz;ADC_SELECT<=clk20Mhz;DAC_CLOCK<=clk40Mhz;DAC_WRITE<=clk40Mhz;DAC<=ADC;DAC_SELECT<=clk20Mhz;在硬件上验证设计的代码时,需要通过ChipScope来观测AD9021输出的信号,选择40MHz的时钟信号作为触发信号,要观测的信号如图2.7所示。图2.7 ChipScope观测的内部信号设计结果实验二的仿真波形如图2.8所示。图2.8 仿真波形使用ChipScope观测到AD9021输出信号如图2.9所示。图2.9 ChipScope观测到的波形实际中,用示波器观测到的波形如图2.10所示。图2.10 示波器观测到的波形设计总结这次实验中在使用48MHz时钟生成40MHz时钟时用到了IP核的设计,在利用IP核进行时钟分频或倍频时,得到的时钟较为稳定,不会出现时钟抖动的问题,同时还用到了元件例化的功能。此外,AD9021和AD9671时钟频率的选择需要多注意,不然可能不会得到预期的结果。设计三 FPGA与DSP间的通信实验要求 DSP通过其EMIF接口与FPGA通信,因此一般情况下DSP为主,FPGA为从设备。这样就要在FPGA内部(通过IPCore)构造一个存储设备或者逻辑接收电路,从而完成与DSP的通信实验说明FPGA作为存储器可以直接将其接口与DSP的EMIF连接,逻辑接收电路要通过EMIF相应的接口信号来完成数据的接收与发送,另外EMIF寄存器的设置直接影响通信各方的时序。DM642 DSP通过EMIF与FPGA相连,将FPGA作为DSP的外设。设计平台中,所使用的EMIF接口信号包括:外部地址线EA3:22、数据线ED0:31和控制线,硬件电路的连接原理图如图3.1所示。图3.1 DSP与FPGA的连接原理框图因为DSP与FPGA之间并没有时钟的连接,所以它们的操作是异步的,即FPGA作为DSP的异步外设。DSP的EMIF使用其内部的时钟来协调接口信号的时序,但FPGA只根据DSP传输过来的信号进行响应,不考虑任何时钟。从图3.1 可知,DM642 的EMIF 接口的地址线、数据线和控制线1 首先通过74LVT16245(U36U39)进行第一级缓冲,得到对应的地址线DC_A3:22、数据线DC_D0:31和控制线2,再经过74LVCH(U71U74)进行第二级缓冲,得到连接FPGA的地址线XDC_A3:22、数据线XDC_D0:31和控制线3。由于数据线是双向传输,地址线和控制线是单向传输,所以缓冲器的控制信号也是不同的。用于地址总线和控制总线的缓冲器(U37、U39、U72、74)的OE#管脚和DIR管脚接固定电位,保证单一的传输方向。而用于数据总线的缓冲器(U36、U38、U71、73)的OE#管脚和DIR管脚由CPLD EPM7032AETC44(U42)给出的信号控制。设计方案因为实验设计的是DSP与FPGA之间的通信,故本次实验分为FPGA设计和DSP设计,具体设计如下。1. FPGA设计FPGA设计主要是在FPGA中设计一个作为DSP访问的外部存储器。首先要弄清楚需要哪几种输入输出信号,这里在FPGA中设计一个具有16个存储单元而且数据宽度为16bit的存储器,16个存储单元需要4根地址线(0000.1111),16位数据宽度需要16根数据线,此外还需要片选信号、读信号和写信号各1位,这样总共占用23根连线。此外需要注意的是,在FPGA中设计的存储器的“读”信号一定要来自DSP的读控制信号对应的管脚上。为了在DSP中判断FPGA中的存储器是否能正确写入,在FPGA写代码模块中将每个读出的数据与16位二进制数据00000相加,然后再观察DSP读出的数据是否作了上述的改变。FPGA中数据读写的进程代码如下:process(addr,cs, rd, wr)beginif cs='0' thenif wr='0' thencase addr iswhen "0000"=> d0<=data;when "0001"=> d1<=data;when "0010"=> d2<=data;when "0011"=> d3<=data;when "0100"=> d4<=data;when "0101"=> d5<=data;when "0110"=> d6<=data;when "0111"=> d7<=data;when "1000"=> d8<=data;when "1001"=> d9<=data;when "1010"=> da<=data;when "1011"=> db<=data;when "1100"=> dc<=data;when "1101"=> dd<=data;when "1110"=> de<=data;when "1111"=> df<=data;when others=> null;end case;elsif rd='0' thencase addr iswhen "0000"=> data<=d0+"00000"when "0001"=> data<=d1+"00000"when "0010"=> data<=d2+"00000"when "0011"=> data<=d3+"00000"when "0100"=> data<=d4+"00000"when "0101"=> data<=d5+"00000"when "0110"=> data<=d6+"00000"when "0111"=> data<=d7+"00000"when "1000"=> data<=d8+"00000"when "1001"=> data<=d9+"00000"when "1010"=> data<=da+"00000"when "1011"=> data<=db+"00000"when "1100"=> data<=dc+"00000"when "1101"=> data<=dd+"00000"when "1110"=> data<=de+"00000"when "1111"=> data<=df+"00000"when others=> null;end case;elsedata<="ZZZZZZZZZZZZZZZZ"end if;else data<="ZZZZZZZZZZZZZZZZ"end if; end process;2. DSP设计DSP通过EMIF接口对FPGA中的存储器进行访问。从硬件电路的连接关系可知,FPGA处于DSP的CE2空间,其首地址为0xA.通过向改地址写入20位数据(低4位为地址,高16位为数据),可实现DSP向FPGA中存储器写入的操作。读数据时,先给出地址(低4位),然后再读出。首先要设置DSP相关寄存器,根据DSP中控制寄存器的地址分配,对相应的控制寄存器作如下定义:#define EMIFA_GBLCTL 0X /EMIFA 全局控制#define EMIFA_CE2CTL 0X /EMIFA CE2空间控制寄存器#define EMIFA_CE2SCE 0X /EMIFA CE2辅助控制寄存器#define ADDRESS 0XA /选择CE2:0xA 根据DSP EMIFA手册,在程序中可以对以上控制寄存器进行如下配置:*(volatile u32*)EMIFA_GBLCTL=(u32)0x;/把clk2打开*(volatile u32*)EMIFA_CE2CTL=(u32)0XFFFFFF13;/16位异步对应通信2*(volatile u32*)EMIFA_CE2SCE=(u32)0x;写函数代码如下,每次向存储器中写入一个16bit数据,总共写16次,第一次写入0x00ff,然后每次写入的数据是前一个数据减去0x0010,这样写入存储器中的数据依次为:0x00ff、0x00ef、0x00df、0x00cf、0x00bf、0x00af、0x009f、0x008f、0x007f、0x006f、0x005f、0x004f、0x003f、0x002f、0x001f和0x000f,每写一次数据要加一个适当的延时,以便进行下一次写数据。void WRITE()int i;unsigned short data=0x00ff;for(i=0;i<16;i+)printf("%x ",data);*(volatile unsigned int short *)ADDRESS+i)=data;data=data-0x0010;delay();printf("n");读函数代码如下,从首地址开始读数据,总共读16次。void READ()int i,temp;for(i=0;i<16;i+)temp=*(volatile unsigned int short *)ADDRESS+i);delay();printf("%x ",temp);printf("n");main函数代码如下,主函数主要包括三个模块:DSP相关寄存器设置、写数据函数和读数据函数。void main()EMIFA();/相关寄存器设置printf("The 16 numbers written in fpga are :n ");WRITE();/写数据printf("The 16 numbers read from fpga are :n ");READ();/读数据设计结果设计结果主要包括FPGA仿真波形和DSP运行结果。FPGA仿真波形如图3.2和图3.3所示:图3.2 写数据仿真波形图3.3 读数据仿真波形DSP写入的数据依次为0x00ff、0x00ef、0x00df、0x00cf、0x00bf、0x00af、0x009f、0x008f、0x007f、0x006f、0x005f、0x004f、0x003f、0x002f、0x001f和0x000f;DSP读出的数据应该依次为0xffff、0xffef、0xffdf、0xffcf、0xffbf、0xffaf、0xff9f、0xff8f、0xff7f、0xff6f、0xff5f、0xff4f、0xff3f、0xff2f、0xff1f和0xff0f。DSP运行的结果如图3.4所示:图3.4 DSP运行结果设计总结这次实验要设计DSP与FPGA的通信,在设计中通过DSP来访问在FPGA中设计的存储器,进行写数据和读数据操作。在DSP设计中,每次写完数据或读完数据都要加一定时间的延时,以保证DSP读写的正确进行。设计四 DSP访问SDRAM实验要求 设置DSP的相关控制寄存器,完成DSP访问SDRAM的时序要求 编写DSP(C语言),实现对SDRAM的读写,并把写入的数据与读出的数据进行比较,来判断读写数据的正确与否 测试SDRAM访问的速度实验说明DM642 DSP可以通过EMIF接口与SDRAM进行无缝连接,硬件系统中用到的SDRAM是MT48LC4M32B2,它是一种高速CMOS、PC100功能的动态随机存储器,容量为128Mbit。该SDRAM的内部有四块DRAM,每块容量为32Mbit,它们公用一个同步接口(所有信号都在时钟信号CLK的上升沿寄存)。设计平台中,所使用的 EMIF 接口信号包括:外部地址线EA3:16、数据线ED0:63和控制线,硬件电路的连接原理图如图4.1所示。从图中可以看到,从DSP 发出的地址线、数据线和控制线直接连接到SDRAM的对应管脚上,中间没有缓冲器。SDRAM放置在DSP EMIF的CE0空间。 TEA3.16 控制线 TBE0#TBE3#DSP DM642 EMIF接口 TBE4#TBE7# TED0.63A0.11 DQ0.31BA0,BA1U34DQM0.4A0.11 BA0,BA1 DQ0.31U35DQM0.4图4.1 DSP与SDRAM的连接框图设计方案在DSP中,针对SDRAM的程序设计主要是完成对SDRAM的读写操作。这样可以先向SDRAM中写入数据,然后再读出这些数据,通过对比写入和写出的数据来判断DSP能否正确地访问SDRAM。此外,可以测试DSP对SDRAM的访问速度。在编写C语音程序之前,需要先编写cmd文件,cmd文件的内容如下:-c-x-stack 0x0600-heap 0x0600MEMORY IRAM : o = 0x l = 0xSECTIONS .text > IRAM .stack > IRAM .bss > IRAM .cinit > IRAM .cio > IRAM .const > IRAM .data > IRAM .switch > IRAM .system > IRAM .far > IRAM进行程序设计时,首先要对SDRAM访问的几个相关寄存器进行配置,这些寄存器包括EMIFA全局控制器、CE0控制寄存器、CE0第二控制寄存器、SDRAM控制寄存器、SD刷新控制寄存器和SD扩展寄存器。根据DSP中控制寄存器的地址分配,对相应的控制寄存器作如下定义:#define EMIFA_GBLCTL 0X /EMIFA全局控制器#define EMIFA_CE0CTL 0X /CE0控制寄存器#define EMIFA_SDCTL 0X /SDRAM控制寄存器#define EMIFA_SDTIM 0XC /SDRAM刷新控制寄存器#define EMIFA_SDEXT 0X /SDRAM扩展寄存器#define address 0x /选择CE0的首地址根据DSP EMIFA手册,在程序中可以对以上控制寄存器进行如下配置:*(volatile u32*)EMIFA_GBLCTL=(u32)0x;*(volatile u32*)EMIFA_CE0CTL=(u32)0xFFFFFF33;*(volatile u32*)EMIFA_SDCTL =(u32)0x;*(volatile u32*)EMIFA_SDTIM =(u32)0x;*(volatile u32*)EMIFA_SDEXT =(u32)0xB;因为已经对以上控制寄存器进行了命名,所以配置了这些控制寄存器之后,SDRAM 就可以像 DSP 内部存储器一样进行读写了。读写 SDRAM 时,可以采用指针,对某个具体地址进行赋值,然后再从相同的地址读出数据进行对比。SDRAM写函数每次把int型的变量i(32位)写入到地址(volatile u32 *)address + i中,总共写入32768个32位的数据,即1Mbit,这样的设计方便在读数据时对数据读写是否正确进行判断。SDRAM写函数代码如下:SDRAM读函数执行时,每读一个数据都会对其进行判断,如果读写不正确,就让counter加1,程序结束后counter的值就是读写错误数据的总量。但在测试读速度时需要去掉读写判断代码,以保证测得的速度准确。SDRAM读函数代码如下:void Write_sdram() int i; for(i =0;i<32768;i+) *(volatile u32 *)address + i) = i;void Read_sdram() int j,k; for(j =0;j<32768;j+) k=*(volatile u32 *)address + j); /if(k!=j) /counter+; 因为要测试SDRAM的访问速度,所以要测试读写花费的时间。具体设计如下:对SDRAM进行32位数据读写,程序中有SDRAM写函数和SDRAM读函数,每执行一次SDRAM写函数共写入1Mbit数据,每次写入32位,这样总共要写32768次;每执行一次SDRAM读函数就把这1Mbit数据读出来。main函数代码如下:void main() clock_t start,middle,stop; double wrt_time,rd_time; double wrt_rate_bit,rd_rate_bit; double wrt_rate_M,rd_rate_M; set_EMIFA(); start = clock(); Write_sdram(); middle = clock(); Read_sdram(); stop = clock(); wrt_time=(double)(middle-start)/CLOCKS_PER_SEC; rd_time=(double)(stop-middle)/CLOCKS_PER_SEC; wrt_rate_bit=/wrt_time; rd_rate_bit=/rd_time; wrt_rate_M = 1/wrt_time; rd_rate_M = 1/rd_time; printf("write time is %f s