1.综合资料
1.TMS320C55x的硬件结构
① P22 CPU结构图
C55x有1条32位的程序数据总线(PB),5条16位数据总线(BB、CB、DB、EB、FB)和1条24位的程序地址总线及5条23位的数据地址总线,这些总线分别与CPU相连。总线通过存储器接口单元(M)与外部程序总线和数据总线相连,实现CPU对外部存储器的访问。这种并行的多总线结构,使CPU能在一个CPU周期内完成1次32位程序代码读、3次16位数据读和两次16位数据写。C55x根据功能的不同将CPU分为4个单元,即指令缓冲单元(I)、程序流程单元(P)、地址流程单元(A)和数据计算单元(D)。
②C55x的CPU组成
指令缓冲单元(I单元)
组成: 32×16位指令缓冲队列;指令译码器。
功能: 接收程序代码并放入指令缓冲队列;由指令译码器解释指令,再把指令流传给其它的工作单元
书上P23图2-2:
1.指令缓冲队列:
每个机器周期,PB从程序空间传送32位的程序代码至I单元的指令缓冲队列;最大可以存放64个字节的待译码指令,可以执行块循环指令,具有对于分支、调用和返回指令的随机处理能力。
2.指令解码器:
当CPU准备译码时,6个字节的代码从队列发送到I单元的指令译码器;
能够识别指令边界, 译码8、16、24、32、40和48位的指令,决定2条指令是否并行执行,将译码结果和立即数送至P单元、A单元、D单元
程序流单元(P单元)
组成: 程序地址发生器;程序控制逻辑
功能: 产生所有程序空间地址,并送到PAB总线
1.P单元:
产生程序空间地址,并加载地址到PAB;控制指令流顺序
2.程序地址产生逻辑:
产生24位的程序空间取指的地址;可产生顺序地址;
也可以I单元的立即数或D单元的寄存器值作为地址
3.程序控制逻辑:
接收来自I单元的立即数,并测试来自A单元或D单元的结果从而执行如下动作:测试条件执行指令的条件是否成
立,把测试结果送程序地址发生器;当中断被请求或使能时,
初始化中断服务程序;控制单一指令重复或块指令重复;管理
并行执行的指令
地址-数据流单元(A单元)
组成: 数据地址产生电路(DAGEN);附加16位ALU和1组寄存器
功能: 产生读/写数据空间地址,并送到BAB、CAB、DAB总线
图2-4
A单元算术逻辑电路:
ALU可接收来自I单元的立即数或与存储器、I/O空间、A单元寄存器、D单元寄存器和P单元寄存器进行双向通信。可完成如下动作:加法、减法、比较、布尔逻辑、符号移位、逻辑移位和绝对值计算;测试、设置、清空、求补A单元寄存器位或存储器位域;改变或转移寄存器值,循环移位寄存器值,从移位器向一个A单元寄存器送特定值。
数据地址产生器单元:
DAGEN产生所有读写数据空间的地址。可接收来自I单元的立即数或来自A单元的寄存器值;根据P单元指示,对间接寻址方式时选择使用线性寻址还是循环寻址。
数据运算单元(D单元)
组成: 1个40位的筒形移位寄存器(barrel shifter);
2个乘加单元(MAC);1个40位的ALU;若干寄存器。
功能: CPU中最主要的部分,是主要的数据处理部件
存储器接口单元(M单元)
是CPU和数据空间或I/O空间
图2-5
移位器:
接收来自I单元的立即数,与存储器、I/O空间、D单元寄存器、P单元寄存器、A单元寄存器进行双向通信;把移位结果送至D 单元的ALU或A单元的ALU;
实现40位累加器值最大左移31位或最大右移32位;实现16位寄存器、存储器或I/O空间数据最大左移31位或最大右移32位;实现16位立即数最大左移15位;提取或扩张位域,执行位计数;对寄存器值进行循环移位;在累加器的值存入数据空间之前,对它们进行取整/饱和处理。
D单元ALU:
可从I单元接收立即数,或与存储器、I/O空间、D单元寄存器、P单元寄存器、A单元寄存器进行双向通信,还可接收移位器的结果;加法、减法、比较、取整、饱和、布尔逻辑以及绝对值运算;在执行一条双16位算术指令时,同时进行两个算术操作;测试、设置、清除以及求D单元寄存器的补码;对寄存器的值进行移动。
两个MAC:
可支持乘法和加/减法。在单个机器周期内,每个MAC可以进行一次17×17位小数或整数乘法运算和一次带有可选的32或40位饱和处理的40位加/减法运算。MAC的结果送累加器;MAC接收来自I单元的立即数,或来自存储器、I/O空间、A单元寄存器的数据,和D单元寄存器、P单元寄存器进行双向通信;MAC的操作会影响P单元状态寄存器的某些位。
③指令流水线
见书本P25页
DSP器件的六个特点:哈佛结构,多总线结构,流水线技术,硬件乘法器,多处理单元结构,嵌入式功能。
冯·诺依曼结构:
程序和数据共用同一套总线,对程序和数据需要分时读写,执行速度慢,数据吞吐量低,计算机结构简单,不适于进行高速度的数字信号处理。
哈佛结构:
程序、数据具有独立的存储空间,有独立的程序总线和数据总线,可同时对程序和数据进行寻址和读写访问,执行速度高,数据吞吐量大,计算机结构复杂,非常适于进行高速的数字信号处理。
流水线技术,4级流水线分别为:取指令,译码,取数,执行DSP复位后程序指针指向FF8000H—放置着bootloader
数据空间为128页每页64k
在DSP中有符号,无符号,短整型,整型都是16位。
Ioport类型的指针只有16位
C_int00为c/c++的程序入口地址
中断物理地址模型:IVPD(16位):ISP(5位):000(保留)
IVPD(16位):中断指针地址
ISP(5位):中断序列号(32个中断)
复位后IVPD(16位)=FFFF00H
32个中断分为:不可屏蔽中断如:软件中断(指令),硬件中断(NMI,RESET)
可屏蔽中断{INIM 全局中断位IER局部中断位}
ISR中断服务程序
IFR中断标志程序
C55x硬件结构
总共12条独立总线
程序数据总线(PB) 1 32位
程序地址总线(PAB) 1 24位
数据总线(BB,CB,DB,EB,FB)5条16位
数据地址总线(BAB,CAB,DAB,EAB,FAB)5条32位
Cpu中有96个寄存器
指令缓冲单元(I单元)
组成: 32×16位指令缓冲队列;指令译码器。
功能: 接收程序代码并放入指令缓冲队列;由指令译码器解释指令,再把指令流传给其它的工作单元
书上P23图2-2:
1.指令缓冲队列:
每个机器周期,PB从程序空间传送32位的程序代码至I单元的指令缓冲队列;最大可以存放64个字节的待译码指
令,可以执行块循环指令,具有对于分支、调用和返回指令的
随机处理能力。
2.指令解码器:
当CPU准备译码时,6个字节的代码从队列发送到I 单元的指令译码器;
能够识别指令边界, 译码8、16、24、32、40和48位的指令,决定2条指令是否并行执行,将译码结果和立即数送至
P单元、A单元、D单元
程序流单元(P单元)
组成: 程序地址发生器;程序控制逻辑
功能: 产生所有程序空间地址,并送到PAB总线
P单元:
产生程序空间地址,并加载地址到PAB;控制指令流顺序
程序地址产生逻辑:
产生24位的程序空间取指的地址;可产生顺序地址;
也可以I单元的立即数或D单元的寄存器值作为地址
程序控制逻辑:
接收来自I单元的立即数,并测试来自A单元或D单元的结果从而执行如下动作:测试条件执行指令的条件是否成立,把测试结果送程序地址发生器;当中断被请求或使能时,初始化中断服务程序;控制单一指令重复或块指令重复;管理并行执行的指令
地址-数据流单元(A单元)
组成: 数据地址产生电路(DAGEN);附加16位ALU和1组寄存器
功能: 产生读/写数据空间地址,并送到BAB、CAB、DAB总线
图2-4
A单元算术逻辑电路:
ALU可接收来自I单元的立即数或与存储器、I/O空间、A单元寄存器、D单元寄存器和P单元寄存器进行双向通信。可完成如下动作:加法、减法、比较、布尔逻辑、符号移位、逻辑移位和绝对值计算;测试、设置、清空、求补A单元寄存器位或存储器位域;改变或转移寄存器值,循环移位寄存器值,从移位器向一个A单元寄存器送特定值。
数据地址产生器单元:
DAGEN产生所有读写数据空间的地址。可接收来自I 单元的立即数或来自A单元的寄存器值;根据P单元指示,对间接寻址方式时选择使用线性寻址还是循环寻址。
数据运算单元(D单元)
组成: 1个40位的筒形移位寄存器(barrel shifter);
2个乘加单元(MAC);1个40位的ALU;若干寄存器。
功能: CPU中最主要的部分,是主要的数据处理部件
存储器接口单元(M单元)
是CPU和数据空间或I/O空间
图2-5
移位器:
接收来自I单元的立即数,与存储器、I/O空间、D 单元寄存器、P单元寄存器、A单元寄存器进行双向通信;把移位结果送至D单元的ALU或A单元的ALU;
实现40位累加器值最大左移31位或最大右移32位;实现16位寄存器、存储器或I/O空间数据最大左移31位或最大右移32位;实现16位立即数最大左移15位;提取或扩张位域,执行位计数;对寄存器值进行循环移位;在累加器的值存入数据空间之前,对它们进行取整/饱和处理。
D单元ALU:
可从I单元接收立即数,或与存储器、I/O空间、D 单元寄存器、P单元寄存器、A单元寄存器进行双向通信,还可接收移位器的结果;加法、减法、比较、取整、饱和、布尔逻辑以及绝对值运算;在执行一条双16位算术指令时,同时进行两个算术操作;测试、设置、清除以及求D单元寄存器的补码;对寄存器的值进行移动。
两个MAC:
可支持乘法和加/减法。在单个机器周期内,每个MAC 可以进行一次17×17位小数或整数乘法运算和一次带有可选的32或40位饱和处理的40位加/减法运算。MAC的结果送累加器;MAC接收来自I单元的立即数,或来自存储器、I/O空间、A单元寄存器的数据,和D单元寄存器、P单元寄存器进行双向通信;MAC的操作会影响P单元状态寄存器的某些位。
C55x的存储(数据/程序)空间统一编址
CPU读取程序代码时,使用24位地址访问相关字节
CPU读写数据时,使用23位地址访问相关字
两种情况下地址总线上均为24位,只是数据寻址时地址总线上的最低位强制填充0
C55x存储空间(总共为16M字节或8M字)的划分:
128个主页面(0~127),每个主页面为64K字
主页面0的前192个字节或96个字(00 0000h~00 00BFh)被MMR所占用
CPU使用字地址访问数据空间
字地址为23位的,寻址16位的数据
地址线为24位的,当CPU读/写数据空间时,23位的字地址最低位补一个0成为总地址
例:
字地址:000 0000 0000 0001 0000
0010
地址总线:0000 0000 0000 0010
0000 0100
I/O空间和程序/数据空间是分开的,只能用来访问DSP 外设上的寄存器
I/O空间里的字地址宽度是16位,可以访问64K个地址
对于I/O空间的读写是通过数据读总线DAB和数据写总线EAB进行的
读写时要在16位地址前补0
例。设一条指令从16位地址0102h处读取一个字,则DAB传输的24位地址为00 0102h。
中断处理:略
汇编语言的设计:
COFF目标文件通常包括3个默认段,即
.text段,通常包含可执行代码
.data段,通常包含初始化数据
.bss段,通常为未初始化变量保留存储空间
汇编器通过段伪指令自动识别各个段,并将段名相同的语句汇编在一起
汇编器有5条伪指令可以识别汇编语言程序的各个不同段
.text、.data、.sect创建初始化段
.bss和.usect创建未初始化段
.sect与.usect创建自定义段和子段
C编译器生成的段
C编译器生成的段有两种基本的类型,即初始化段和未初始化段
初始化段有:
.cinit段,包含初始化数据表格和常数
.pinit段,包含实时运行时调用的数据表格
.const段,包含用const定义(不能同时被volatile定义)的字
符串常量和数据
.switch段,包含switch语句所用表
.text段,包含所有可执行代码
未初始化段保留了存储器空间,一段程序可以在运行期间使用这个空间来生成和存储变量:
.bss段,为全局和静态变量保留了空间。在启动和装载的时候,
C启动程序或装载程序从.cinit段(通常在ROM中)复制数
据并用这些数据来初始化.bss段中的变量
.stack段,为C系统堆栈分配存储地址。这个存储地址用来传递变量和局部存储
.sysmem段,为动态存储分配保留空间。这个空间被malloc、
calloc和realloc函数调用。如果C程序不使用这些函数,编译
器就不会创建.sysmem段
.cio段,支持C I/O。这个空间用来作为标签为_CIOBUF_缓冲
区。当任何类型的C I/O被执行(如printf和scanf),就会建
立缓冲区。缓冲区包含一个对stream I/O类型的内部C I/O命
令(和需要的参数)及从C I/O命令返回的数据。.cio段必须
放在链接器命令文件中才能使用C I/O
为变量动态分配存储器的函数(malloc、calloc和realloc)
从C代码中访问汇编语言函数。
(a)C程序:
/*声明汇编函数*/ extern int asmfunc(int,int *);
int gvar ;/*定义全局变量*/
main()
{
int i;
i=asmfunc(i,&gvar) ;/*调用函数*/
}
(b)汇编程序:
_asmfunc:
ADD *AR0,T0,T0 ; T0+gvar=>i,i=T0
RET;
访问.bss段或.usect段中没有初始化的变量:
使用.bss或.usect指令来定义变量
使用.global指令来定义为外部变量
在汇编语言中的变量前加下划线“_”
在C代码中声明变量为外部变量并正常地访问它
从C程序中访问定义在.bss段的变量
(a)C程序:
extern int var ; /* 外部变量*/
var = 1; /* 使用变量*/
(b)汇编语言程序:
.bss var,1 ;定义变量
.gloabal bar ;声明变量为外部变量
当变量不是被存放在.bss段时,比如用汇编语言定义的查找表并不希望放在RAM中,这时应该定义一个指向该变量的指针并从C语言中对其间接访问。
首先,要定义变量
其次,声明一个指向该变量起始地址的全局指针,这个变量就可以被链接到存储空间的任何地方
最后,在C程序中访问时,必须先声明该对象为extern型,并且不能在其名称前面加下划线,然后就可以正常访问它了
在C代码中访问没有在.bss段中声明的变量。
(a)C程序:
extern float sine[] ; /*这就是对象*/
float *sine_p=sine; /*声明指针指向它*/
f=sine_p[2]; /*正常访问该对象*/
(b)汇编程序:
.global _sine;声明变量为外部变量
.sect ”sine_tab” ;创建单独的段
_sine: ;表从此开始
.float 0.0
.float 0.015987
.float 0.022145
在C 代码中访问汇编语言常数。 (a )C语言程序: extern int table_size;
/* 声明table_size 为外部参数*/
#define TABLE_SIZE ((int)(&table_size)) …… …… ……
For(i=0;i .global _table_size ;定义该常量为全局常量 #pr agma CODE_SECTION(func_name, ”section_name”) 作用:把C 函数func_name 的代码配置到由section_name 定义的程序段中 #pragma DATA_SECTION(var_name,”section_name”) 作用: var_name 是包含在C 函数内的变量名称,该指令将数据var_name 配置到由section_name 定义的数据段中 Dsp 与.dat1651 1 0 1 0文件的入口地址 2.LED #include PLL_setFreq(1,0xf,0,1,3,3,0); GPIO_RSET(IODIR,0XF0); for(;;) { GPIO_FSET(IODATA,IO7D,1); delay(1000); GPIO_FSET(IODATA,IO7D,0); delay(1000); CHIP_FSET(STI_55,XF,1); delay(2000); CHIP_FSET(STI_55,XF,0); delay(2000); } } void delay(Uint32 M) { Uint32 i,j; for(i=M;i>0;i--) for(j=0xffff;j>0;j--); } 对照书本P110的寄存器进行复习,此句代码是修改时钟的关键! 输出频率=(PLL MULT*输入频率) /(PLL DIV+1) ② 状态寄存器ST1_55 C16FRCT C54CM ASM 7654~0R/W-00000 BRAF CPL XF HM INTM M40SATD SXMD 8R/W-0R/W-0R/W-1R/W-0 R/W-1 R/W-0R/W-0 R/W-1 1514131211109ST1_55R/W-0 R/W-0 R/W-1 BIT 向状态寄存器保护地址的写操作无效,在读操作时这个位总是0 R/W 可进行读写访问 —X X 是DSP 复位后的值,如果X 是pin,X 是pin 上复位后的电平 IV.INTM位 *如果INTM=0,C55x使能所有可屏蔽中断 *如果INTM=1,C55x禁止所有可屏蔽中断 *使用INTM位需要注意的要点: INTM位能够全局使能或禁止可屏蔽中断,但是它对不可屏蔽中断无效。在使用INTM位时,要使用状态位清零和置位指令来修改INTM位。其它能影响INTM位的,只有软件中断指令和软件置位指令。 * CPU响应中断请求时,自动保存INTM位。特别地,CPU 把ST1_55保存到数据堆栈时,INTM位也被保存起来。 *执行中断服务子程序(ISR)之前,CPU自动置位INTM位,禁止所有的可屏蔽中断。ISR可以通过清零INTM位,来重新开放可屏蔽中断。 *中断返回指令,从数据堆栈恢复INTM位的值。 *在调试器实时仿真模式下,CPU暂停时,忽略INTM位,CPU 只处理临界时间中断。 V.XF位 XF是通用的输出位,能用软件处理且可输出至DSP引脚 . 3.定时器 寄存器 Timer Counter Registers (CNT1–4) The timer counter register (Figure 24) is a 64-bit wide register consisting of four 16-bit count registers (Figure 25): CNT1, CNT2, CNT3, and CNT4. # In the general-purpose timer mode, the 64-bit timer counter increments when it is enabled to count. The timer counter register is cleared to 0 at reset. # In the enabled continuous mode (ENAMODE = 10), the 64-bit timer count-er increments until the value in the timer counter matches the timer period.The timer counter register resets to 0 and continues to increment on the next clock after the value in the timer counter matches the timer period. # In the dual 32-bit timers mode, the 64-bit timer counter register is divided into two pairs of 16-bit registers: CNT2:CNT1 and CNT4:CNT3. These two register pairs can be configured as chained or unchained。 代码:定义段在汇编中.sect ".vectors" #include #include #include #include #include #include /* Define and initialize the GPT module configuration structure */ GPT_Config MyGptConfig = { 0, //Emulation management register 0, //GPIO interrupt control register 0, //GPIO enable register 0, //GPIO direction register 0, //GPIO data register 0xB9EF, //Timer period register 1 0x05F5, //Timer period register 2 0, //Timer period register 3 0, //Timer period register 4 GPT_GPTCTL1_RMK( //Timer control register 1 GPT_GPTCTL1_TIEN_NOT_GATED,//Timer没选通 //GPT_GPTCTL1_TIEN_DEFAULT与上等价 GPT_GPTCTL1_CLKSRC_VBUS, //外部时钟源驱动TINP引脚 //GPT_GPTCTL1_CLKSRC_DEFAULT GPT_GPTCTL1_ENAMODE_CONTINUOUS,//定时器不断激活模式多次匹配复位 //GPT_GPTCTL1_ENAMODE_ONCE只启动一次 GPT_GPTCTL1_PWID_INACTIVE_1CYCLE,//在定时器到达周期后TSTAT停止计数时钟表达//在clock模式下无效。。主要是配置脉冲占空比 GPT_GPTCTL1_CP_CLOCK_MODE, //时钟模式 GPT_GPTCTL1_INVIN_DONT_INVERT_OUTPUT,//不反相TINP驱动定时器 GPT_GPTCTL1_INVOUT_DONT_INVERT_OUTPUT//不反相的TSTAT驱动TOUT ), GPT_GPTCTL2_RMK( //Timer control register 2和寄存器1的配置一样 GPT_GPTCTL2_TIEN_NOT_GATED, GPT_GPTCTL2_CLKSRC_VBUS, GPT_GPTCTL2_ENAMODE_CONTINUOUS, GPT_GPTCTL2_PWID_INACTIVE_1CYCLE, GPT_GPTCTL2_CP_CLOCK_MODE, GPT_GPTCTL2_INVIN_DONT_INVERT_OUTPUT, GPT_GPTCTL2_INVOUT_DONT_INVERT_OUTPUT ), GPT_GPTGCTL1_RMK( //Global timer control register GPT_GPTGCTL1_TDDR34_DEFAULT, GPT_GPTGCTL1_PSC34_DEFAULT, GPT_GPTGCTL1_TIMMODE_DEFAULT,//64bit普通模式 //GPT_GPTGCTL1_TIMMODE_32BIT_ CHAINED 级联 //GPT_GPTGCTL1_TIMMODE_32BIT_DUAL 不级联 GPT_GPTGCTL1_TIM34RS_NOT_IN_RESET, GPT_GPTGCTL1_TIM12RS_NOT_IN_RESET ) }; /* Function/ISR prototypes */ interrupt void Timer0Isr(void); extern void VECSTART(void); /* Create a TIMER_Handle object for use with TIMER_open */ GPT_Handle hGpt; //定义句柄 Uint16 EventId0; // 定时器0所对应的事件ID号 /* 通过定义宏来控制两个外围存储器映射的寄存器,从而实现对GPIO口的控制*/ #define GPIODIR (*(volatile ioport Uint16*)(0x3400)) #define GPIODATA (*(volatile ioport Uint16*)(0x3401)) void main(void) { CSL_init(); PLL_setFreq(1, 0xF, 0, 1, 3, 3, 0); /* Set IVPH/IVPD to start of interrupt vector table */ IRQ_setVecs((Uint32)(&VECSTART)); /* Temporarily disable all maskable interrupts */ IRQ_globalDisable(); /* Open Timer 0, set registers to power on defaults */ /* And return handle of Timer 0 */ hGpt = GPT_open(GPT_DEV0, GPT_OPEN_RESET); /* Get Event Id associated with Timer 0, for use with */ /* CSL interrupt enable functions. */ EventId0 = GPT_getEventId(hGpt); /* Clear any pending Timer interrupts */ IRQ_clear(EventId0); /* Place interrupt service routine address at */ /* associated vector location */ IRQ_plug(EventId0,&Timer0Isr); /* Write configuration structure values to Timer control regs */ GPT_config(hGpt, &MyGptConfig); /* Enable Timer interrupt */ IRQ_enable(EventId0); /* Enable all maskable interrupts */ IRQ_globalEnable(); /* Start Timer */ GPT_start(hGpt); /* Config GPIO7 in order to ignite led D5*/ GPIODIR = 0x80; // config the GPIO7 as output pin for(;;) { /* Enter system loop and waiting for interrupt */ } } /*定时器0的中断程序*/ interrupt void Timer0Isr(void) { 。。。。省 } 4.EMIF——SDRAM #include #include #include #include #include #include "5502_FLASH.h" Uint16 ReturnState; // FLASH验证函数的返回状态 #define DataLength 2048 // 数据长度 Uint16 SourData[DataLength]; // 源数据,给FLASH赋值 #pragma DATA_SECTION (DestData,".destdata") Uint16 DestData[DataLength]; // 目标数据,FLASH的编程空间 EMIF_Config MyEmifConfig = { /*FLASH的EMIF设置*/ EMIF_GBLCTL1_RMK( // EMIF Global Control Register 1 EMIF_GBLCTL1_NOHOLD_HOLD_ENABLED, // Hold enable EMIF_GBLCTL2_EK2HZ_HIGHZ, // EMIF_GBLCTL1_EK1HZ_EK1ENHigh-Z control EMIF_GBLCTL1_EK1EN_ENABLED // ECLKOUT1 Enable ), EMIF_GBLCTL2_RMK( // EMIF Global Control Register 2 EMIF_GBLCTL2_EK2RATE_1XCLK, // ECLKOUT2 Rate EMIF_GBLCTL2_EK2HZ_HIGHZ, EMIF_GBLCTL2_EK2EN_DISABLED // ECLKOUT2 Enable (enabled by default) ), EMIF_CE1CTL1_RMK( // CE1 Space Control Register 1 EMIF_CE1CTL1_TA_OF(3), // Turn-Around time EMIF_CE1CTL1_READ_STROBE_OF(6), // Read strobe width EMIF_CE1CTL1_MTYPE_16BIT_ASYNC, // Access type EMIF_CE1CTL1_WRITE_HOLD_MSB_LOW,// Write hold width MSB EMIF_CE1CTL1_READ_HOLD_OF(3) // Read hold width ), EMIF_CE1CTL2_RMK( // CE1 Space Control Register 2 EMIF_CE1CTL2_WRITE_SETUP_OF(4), // Write setup width EMIF_CE1CTL2_WRITE_STROBE_OF(10), // Write strobe width EMIF_CE1CTL2_WRITE_HOLD_OF(2), // Write hold width EMIF_CE1CTL2_READ_SETUP_OF(2) // Read setup width ), EMIF_CE0CTL1_RMK( // CE0 Space Control Register 1 EMIF_CE0CTL1_TA_DEFAULT, EMIF_CE0CTL1_READ_STROBE_DEFAULT, EMIF_CE0CTL1_MTYPE_DEFAULT, EMIF_CE0CTL1_WRITE_HOLD_MSB_DEFAULT, EMIF_CE0CTL1_READ_HOLD_DEFAULT ), EMIF_CE0CTL2_RMK( // CE0 Space Control Register 2 EMIF_CE0CTL2_WRITE_SETUP_DEFAULT, EMIF_CE0CTL2_WRITE_STROBE_DEFAULT, EMIF_CE0CTL2_WRITE_HOLD_DEFAULT, EMIF_CE0CTL2_READ_SETUP_DEFAULT ), EMIF_CE2CTL1_RMK( // CE2 Space Control Register 1 EMIF_CE2CTL1_TA_DEFAULT, // Not use for SDRAM (asynchronous memory types only) EMIF_CE2CTL1_READ_STROBE_DEFAULT, // Read strobe width EMIF_CE2CTL1_MTYPE_32BIT_SDRAM, // 32-bit-wide SDRAM EMIF_CE2CTL1_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE2CTL1_READ_HOLD_DEFAULT // Read hold width ), EMIF_CE2CTL2_RMK( // CE2 Space Control Register 2 EMIF_CE2CTL2_WRITE_SETUP_DEFAULT, // Write setup width EMIF_CE2CTL2_WRITE_STROBE_DEFAULT,// Write strobe width EMIF_CE2CTL2_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE2CTL2_READ_SETUP_DEFAULT // Read setup width ), EMIF_CE3CTL1_RMK( // CE3 Space Control Register 1 EMIF_CE3CTL1_TA_DEFAULT, // Not use for SDRAM (asynchronous memory types only) EMIF_CE3CTL1_READ_STROBE_DEFAULT, // Read strobe width EMIF_CE2CTL1_MTYPE_32BIT_SDRAM, // 32-bit-wide SDRAM EMIF_CE3CTL1_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE3CTL1_READ_HOLD_DEFAULT // Read hold width ), EMIF_CE3CTL2_RMK( // CE3 Space Control Register 2 EMIF_CE3CTL2_WRITE_SETUP_DEFAULT, // Write setup width EMIF_CE3CTL2_WRITE_STROBE_DEFAULT,// Write strobe width EMIF_CE3CTL2_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE3CTL2_READ_SETUP_DEFAULT // Read setup width ), EMIF_SDCTL1_RMK( // SDRAM Control Register 1 EMIF_SDCTL1_TRC_OF(6), // Specifies tRC value of the SDRAM in EMIF clock cycles. EMIF_SDCTL1_SLFRFR_DISABLED // Auto-refresh mode ), EMIF_SDCTL2_RMK( // SDRAM Control Register 2 0x11, // 4 banks,11 row address, 8 column address EMIF_SDCTL2_RFEN_ENABLED, // Refresh enabled EMIF_SDCTL2_INIT_INIT_SDRAM, EMIF_SDCTL2_TRCD_OF(1),// Specifies tRCD value of the SDRAM in EMIF clock cycles EMIF_SDCTL2_TRP_OF(1) // Specifies tRP value of the SDRAM in EMIF clock cycles ), 0x61B, // SDRAM Refresh Control Register 1 0x0300, // SDRAM Refresh Control Register 2 EMIF_SDEXT1_RMK( // SDRAM Extension Register 1 EMIF_SDEXT1_R2WDQM_1CYCLE, EMIF_SDEXT1_RD2WR_3CYCLES, EMIF_SDEXT1_RD2DEAC_1CYCLE, EMIF_SDEXT1_RD2RD_1CYCLE, EMIF_SDEXT1_THZP_OF(1), // tPROZ2=2 EMIF_SDEXT1_TWR_OF(0), // EMIF_SDEXT1_TRRD_2CYCLES, EMIF_SDEXT1_TRAS_OF(4), EMIF_SDEXT1_TCL_2CYCLES ), EMIF_SDEXT2_RMK( // SDRAM Extension Register 2 EMIF_SDEXT2_WR2RD_0CYCLES, EMIF_SDEXT2_WR2DEAC_1CYCLE, 0, EMIF_SDEXT2_R2WDQM_1CYCLE ), EMIF_CE1SEC1_DEFAULT, // CE1 Secondary Control Register 1 EMIF_CE0SEC1_DEFAULT, // CE0 Secondary Control Register 1 EMIF_CE2SEC1_DEFAULT, // CE2 Secondary Control Register 1 EMIF_CE3SEC1_DEFAULT, // CE3 Secondary Control Register 1 EMIF_CESCR_DEFAULT // CE Size Control Register }; main() { Uint16 i; Uint16 Errcount = 0; CSL_init(); /*初始化CSL库*/ PLL_setFreq(1, 0xF, 0, 1, 3, 3, 0); /*设置系统的运行速度为300MHz*/ CHIP_RSET(XBSR,0x0001); /*EMIF为全EMIF接口*/ EMIF_config(&MyEmifConfig); /*初始化DSP的外部EMIF*/ for(i=0;i { SourData[i] = i; } ReturnState = Check_SST_39VF400A(); // 检查产家设备ID Erase_One_Sector (DestData); // Erase a sector of 2048 words Program_One_Sector (SourData,DestData); // Program a sector Errcount = 0; /* 判断操作是否正确*/ for(i=0;i { if(i != DestData[i]) Errcount++; } if(Errcount != 0) printf("SEED_DEC5502 Flash 操作失败\n"); else printf("SEED_DEC5502 Flash 操作成功\n"); } 外扩SDRAM存储器(同步存储器): 5.EMIF——FLASH Flash: 1) 5502_FLASH.h #ifndef dec_5502_flash_h #define dec_5502_flash_h extern void Delay_150_Nano_Seconds(); extern void Delay_25_Milli_Seconds(); extern void Delay_100_Milli_Seconds(); extern int C heck_SST_39VF400A(); // Check manufacturer and device ID extern void CFI_Query(); // CFI Query Entry/Exit command sequence extern void Erase_One_Sector(); // Erase a sector of 2048 words extern void Erase_One_Block(); // Erase a block of 32K words extern void Erase_Entire_Chip(); // Erase the contents of the entire chip extern void Program_One_Word(); // Alter data in one word extern void Program_One_Sector(); // Alter data in 2048 word sector extern void Program_One_Block(); // Alter data in 32K word block //extern void Check_Toggle_Ready();//erase detection using Toggle bit extern void Check_Data_Polling();//program or erase detection usingData polling #endif 2) SST39VF400A.c #define FALSE 0 #define TRUE 1 #define SECTOR_SIZE 2048 /* Must be 2048 words for 39VF400A */ #define BLOCK_SIZE 32768 /* Must be 32K words for 39VF400A */ #define SST_ID 0x00BF /* SST Manufacturer's ID code */ #define SST_39VF400A 0x2780 /* SST39VF400A device code */ #define Addr5555 (WORD *)0x205555 /* typedef unsigned int WORD */ #define Addr2AAA (WORD *)0x202AAA #define Addr0000 (WORD *)0x200000 #define Addr0001 (WORD *)0x200001 typedef unsigned char BYTE; typedef unsigned int WORD; void Delay_150_Nano_Seconds(); void Delay_25_Milli_Seconds(); void Delay_100_Milli_Seconds(); void Check_Toggle_Ready(); void Check_Data_Polling(); extern int Check_SST_39VF400A(void) /* same device code as SST39VF400 */ { WORD * Temp; WORD SST_id1; WORD * Temp1; WORD SST_id2; int ReturnStatus;/* Issue the Software Product ID code to 39VF400A */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1= 0xAAAA; /* write data 0xAAAA to the address */ Temp1 = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp1= 0x5555; /* write data 0x5555 to the address */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1= 0x9090; /* write data 0x9090 to the address */ Delay_150_Nano_Seconds(); /* insert delay time = Tida*/ /* Read the product ID from 39VF400A */ Temp = Addr0000; /* set up address to be C000:0000h */ SST_id1 = *Temp; /* get first ID word */ SST_id1 = SST_id1 & 0xFF; /* mask of higher byte */ Temp1 = Addr0001; /* set up address to be C000:0001h */ SST_id2 = *Temp1; /* get second ID word */ /* Determine whether there is a SST39VF400A installed or not */ if ((SST_id1 == SST_ID) && (SST_id2 ==SST_39VF400A)) ReturnStatus = TRUE; else ReturnStatus = FALSE; /* Issue the Soffware Product ID Exit code thus returning the 39VF400A*/ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1 = 0xAAAA; /* write data 0xAAAA to the address */ Temp1 = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp1 = 0x5555; /* write data 0x5555 to the address */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1 = 0xF0F0; /* write data 0xF0F0 to the address */ Delay_150_Nano_Seconds(); /* insert delay time = Tida */ return(ReturnStatus); } extern void CFI_Query(void) { WORD * Temp1;/* Issue the Software Product ID code to 39VF400A */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1= 0xAAAA; /* write data 0xAAAA to the address */ Temp1 = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp1= 0x5555; /* write data 0x5555 to the address */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1= 0x9898; /* write data 0x9898 to the address */ Delay_150_Nano_Seconds(); /* insert delay time = Tida */ /* Issue the CFI Exit code thus returning the 39VF400A to the read operating mode Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1 = 0xAAAA; /* write data 0xAAAA to the address */ Temp1 = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp1 = 0x5555; /* write data 0x5555 to the address */ Temp1 = Addr5555; /* set up address to be C000:5555h */ *Temp1 = 0xF0F0; /* write data 0xF0F0 to the address */ Delay_150_Nano_Seconds(); /* insert delay time = Tida */ } extern void Erase_One_Sector (WORD * Dst){ WORD * Temp;/* Issue the Sector Erase command to 39VF400A */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x8080; /* write data 0x8080 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Dst; /* set up starting address to be erased */ *Temp = 0x3030; /* write data 0x3030 to the address */ Delay_25_Milli_Seconds(); /* Delay time = Tse */ } extern void Erase_One_Block (WORD * Dst){ WORD * Temp; /* Issue the Sector Erase command to 39VF400A */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x8080; /* write data 0x8080 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Dst; /* set up starting address to be erased */ *Temp = 0x5050; /* write data 0x5050 to the address */ Delay_25_Milli_Seconds(); /* Delay time = Tbe */ } extern void Erase_Entire_Chip(void) { WORD * Temp; /* Issue the Chip Erase command to 39VF400A */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x00AA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x0055; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x0080; /* write data 0x8080 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x00AA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x0055; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0x0010; /* write data 0x1010 to the address */ Delay_100_Milli_Seconds(); /* Delay Tsce time*/ } extern void Program_One_Word (WORD SrcWord, WORD * Dst) { WORD * Temp; WORD * DestBuf; DestBuf = Dst; Temp = Addr5555; /* set up address to be C000:555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xA0A0; /* write data 0xA0A0 to the address */ *DestBuf = SrcWord; /* transfer the byte to destination */ Check_Toggle_Ready(DestBuf); /* wait for TOGGLE bit to get ready */ } extern void Program_One_Sector (WORD * Src, WORD * Dst) { WORD * Temp; WORD * SourceBuf; WORD * DestBuf; int Index; SourceBuf = Src; DestBuf = Dst; Erase_One_Sector(Dst); /* erase the sector first */ for (Index = 0; Index < SECTOR_SIZE; Index++) { Temp = Addr5555; /* set up address to be C000:555h */ *Temp = 0x00AA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x0055; /* write data 0x5555 to the address */ Temp = Addr5555;/* set up address to be C000:5555h */ *Temp = 0x00A0;/* write data 0xA0A0 to the address */ Temp = DestBuf;/* save the original Destination address */ *DestBuf++ = *SourceBuf++;// transfer data from source to destination Check_Toggle_Ready(Temp); /* wait for TOGGLE bit to get ready */ } } extern void Program_One_Block(WORD * Src, WORD * Dst) { WORD * Temp; WORD * SourceBuf; WORD * DestBuf; int Index; SourceBuf = Src; DestBuf = Dst; Erase_One_Block(Dst); /* erase the sector first */ for (Index = 0; Index < BLOCK_SIZE; Index++) { Temp = Addr5555; /* set up address to be C000:555h */ *Temp = 0xAAAA; /* write data 0xAAAA to the address */ Temp = Addr2AAA; /* set up address to be C000:2AAAh */ *Temp = 0x5555; /* write data 0x5555 to the address */ Temp = Addr5555; /* set up address to be C000:5555h */ *Temp = 0xA0A0; /* write data 0xA0A0 to the address */ Temp = DestBuf; /* save the original Destination address */ *DestBuf++ = *SourceBuf++;// transfer data from source to destination Check_Toggle_Ready(Temp);//wait for TOGGLE bit to get ready } } extern void Check_Toggle_Ready(WORD * Dst) { BYTE Loop = TRUE; WORD PreData; WORD CurrData; unsigned long TimeOut = 0; PreData = *Dst; PreData = PreData & 0x4040; while ((TimeOut< 0x07FFFFFF) && (Loop)) { CurrData = *Dst; CurrData = CurrData & 0x4040; if (PreData == CurrData) Loop = FALSE; /* ready to exit the while loop */ PreData = CurrData; TimeOut++; } } extern void Check_Data_Polling(WORD * Dst, WORD TrueData) { BYTE Loop = TRUE; WORD CurrData; unsigned long TimeOut = 0; TrueData = TrueData & 0x8080; while ((TimeOut< 0x07FFFFFF) && (Loop)) { CurrData = *Dst; CurrData = CurrData & 0x8080; if (TrueData == CurrData) Loop = FALSE; /* ready to exit the while loop */ TimeOut++; } } extern void Delay_150_Nano_Seconds(void) { int i; // System main clock 200MHz, 5 nanoseconds per instruction cycle for(i = 0; i < 40; i++) { } // 延时200纳妙 } extern void Delay_25_Milli_Seconds(void) { int i,j; // System main clock 200MHz, 5 nanoseconds per instruction cycle for(i = 0; i < 1100; i++) // Perform 5000000 instruction cycles { // Perform 5500000 instruction cycles 为27.5Ms for(j = 0; j < 5000; j++) { } } } extern void Delay_100_Milli_Seconds(void) { int i,j; // System main clock 200MHz, 5 nanoseconds per instruction cycle for(i = 0; i < 5000; i++) // Perform 20000000 instruction cycles { // Perform 25000000 instruction cycles 为125Ms for(j = 0; j < 5000; j++) { } } } 3)5502_FLASH.c #include #include #include #include #include #include "5502_FLASH.h" Uint16 ReturnState; // FLASH验证函数的返回状态 #define DataLength 2048 // 数据长度 Uint16 SourData[DataLength]; // 源数据,给FLASH赋值 #pragma DATA_SECTION (DestData,".destdata") Uint16 DestData[DataLength]; // 目标数据,FLASH的编程空间 EMIF_Config MyEmifConfig = { /*FLASH的EMIF设置*/ EMIF_GBLCTL1_RMK( // EMIF Global Control Register 1 EMIF_GBLCTL1_NOHOLD_HOLD_ENABLED, // Hold enable EMIF_GBLCTL2_EK2HZ_HIGHZ, // EMIF_GBLCTL1_EK1HZ_EK1ENHigh-Z control EMIF_GBLCTL1_EK1EN_ENABLED // ECLKOUT1 Enable ), EMIF_GBLCTL2_RMK( // EMIF Global Control Register 2 EMIF_GBLCTL2_EK2RATE_1XCLK, // ECLKOUT2 Rate EMIF_GBLCTL2_EK2HZ_HIGHZ, EMIF_GBLCTL2_EK2EN_DISABLED // ECLKOUT2 Enable (enabled by default) ), EMIF_CE1CTL1_RMK( // CE1 Space Control Register 1 EMIF_CE1CTL1_TA_OF(3), // Turn-Around time EMIF_CE1CTL1_READ_STROBE_OF(6), // Read strobe width EMIF_CE1CTL1_MTYPE_16BIT_ASYNC, // Access type EMIF_CE1CTL1_WRITE_HOLD_MSB_LOW,// Write hold width MSB EMIF_CE1CTL1_READ_HOLD_OF(3) // Read hold width ), EMIF_CE1CTL2_RMK( // CE1 Space Control Register 2 EMIF_CE1CTL2_WRITE_SETUP_OF(4), // Write setup width EMIF_CE1CTL2_WRITE_STROBE_OF(10), // Write strobe width EMIF_CE1CTL2_WRITE_HOLD_OF(2), // Write hold width EMIF_CE1CTL2_READ_SETUP_OF(2) // Read setup width ), EMIF_CE0CTL1_RMK( // CE0 Space Control Register 1 EMIF_CE0CTL1_TA_DEFAULT, EMIF_CE0CTL1_READ_STROBE_DEFAULT, EMIF_CE0CTL1_MTYPE_DEFAULT, EMIF_CE0CTL1_WRITE_HOLD_MSB_DEFAULT, EMIF_CE0CTL1_READ_HOLD_DEFAULT ), EMIF_CE0CTL2_RMK( // CE0 Space Control Register 2 EMIF_CE0CTL2_WRITE_SETUP_DEFAULT, EMIF_CE0CTL2_WRITE_STROBE_DEFAULT, EMIF_CE0CTL2_WRITE_HOLD_DEFAULT, EMIF_CE0CTL2_READ_SETUP_DEFAULT ), EMIF_CE2CTL1_RMK( // CE2 Space Control Register 1 EMIF_CE2CTL1_TA_DEFAULT, // Not use for SDRAM (asynchronous memory types only) EMIF_CE2CTL1_READ_STROBE_DEFAULT, // Read strobe width EMIF_CE2CTL1_MTYPE_32BIT_SDRAM, // 32-bit-wide SDRAM EMIF_CE2CTL1_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE2CTL1_READ_HOLD_DEFAULT // Read hold width ), EMIF_CE2CTL2_RMK( // CE2 Space Control Register 2 EMIF_CE2CTL2_WRITE_SETUP_DEFAULT, // Write setup width EMIF_CE2CTL2_WRITE_STROBE_DEFAULT,// Write strobe width EMIF_CE2CTL2_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE2CTL2_READ_SETUP_DEFAULT // Read setup width ), EMIF_CE3CTL1_RMK( // CE3 Space Control Register 1 EMIF_CE3CTL1_TA_DEFAULT, // Not use for SDRAM (asynchronous memory types only) EMIF_CE3CTL1_READ_STROBE_DEFAULT, // Read strobe width EMIF_CE2CTL1_MTYPE_32BIT_SDRAM, // 32-bit-wide SDRAM EMIF_CE3CTL1_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE3CTL1_READ_HOLD_DEFAULT // Read hold width ), EMIF_CE3CTL2_RMK( // CE3 Space Control Register 2 EMIF_CE3CTL2_WRITE_SETUP_DEFAULT, // Write setup width EMIF_CE3CTL2_WRITE_STROBE_DEFAULT,// Write strobe width EMIF_CE3CTL2_WRITE_HOLD_DEFAULT, // Write hold width EMIF_CE3CTL2_READ_SETUP_DEFAULT // Read setup width ), EMIF_SDCTL1_RMK( // SDRAM Control Register 1 EMIF_SDCTL1_TRC_OF(6), // Specifies tRC value of the SDRAM in EMIF clock cycles. EMIF_SDCTL1_SLFRFR_DISABLED // Auto-refresh mode ), EMIF_SDCTL2_RMK( // SDRAM Control Register 2 0x11, // 4 banks,11 row address, 8 column address EMIF_SDCTL2_RFEN_ENABLED, // Refresh enabled EMIF_SDCTL2_INIT_INIT_SDRAM, EMIF_SDCTL2_TRCD_OF(1),// Specifies tRCD value of the SDRAM in EMIF clock cycles EMIF_SDCTL2_TRP_OF(1) // Specifies tRP value of the SDRAM in EMIF clock cycles ), 0x61B, // SDRAM Refresh Control Register 1 0x0300, // SDRAM Refresh Control Register 2 EMIF_SDEXT1_RMK( // SDRAM Extension Register 1 EMIF_SDEXT1_R2WDQM_1CYCLE, EMIF_SDEXT1_RD2WR_3CYCLES, EMIF_SDEXT1_RD2DEAC_1CYCLE, EMIF_SDEXT1_RD2RD_1CYCLE, EMIF_SDEXT1_THZP_OF(1), // tPROZ2=2 EMIF_SDEXT1_TWR_OF(0), // EMIF_SDEXT1_TRRD_2CYCLES, EMIF_SDEXT1_TRAS_OF(4), EMIF_SDEXT1_TCL_2CYCLES ), EMIF_SDEXT2_RMK( // SDRAM Extension Register 2 EMIF_SDEXT2_WR2RD_0CYCLES, EMIF_SDEXT2_WR2DEAC_1CYCLE, 0, EMIF_SDEXT2_R2WDQM_1CYCLE ), EMIF_CE1SEC1_DEFAULT, // CE1 Secondary Control Register 1 EMIF_CE0SEC1_DEFAULT, // CE0 Secondary Control Register 1 EMIF_CE2SEC1_DEFAULT, // CE2 Secondary Control Register 1 EMIF_CE3SEC1_DEFAULT, // CE3 Secondary Control Register 1 EMIF_CESCR_DEFAULT // CE Size Control Register }; main() { Uint16 i; Uint16 Errcount = 0; CSL_init(); /*初始化CSL库*/ PLL_setFreq(1, 0xF, 0, 1, 3, 3, 0); /*设置系统的运行速度为300MHz*/ CHIP_RSET(XBSR,0x0001); /*EMIF为全EMIF接口*/ EMIF_config(&MyEmifConfig); /*初始化DSP的外部EMIF*/ for(i=0;i { SourData[i] = i; } ReturnState = Check_SST_39VF400A(); // 检查产家设备ID Erase_One_Sector (DestData); // Erase a sector of 2048 words Program_One_Sector (SourData,DestData); // Program a sector Errcount = 0; /* 判断操作是否正确*/ for(i=0;i { if(i != DestData[i]) Errcount++; } if(Errcount != 0) printf("SEED_DEC5502 Flash 操作失败\n"); else printf("SEED_DEC5502 Flash 操作成功\n"); } 6.EMIF 1.