哈工大威海大四通信课设 下载本文

课程设计

报 告

日 期: 2014.01.09 姓 名: 吕程 学 号: 100240217

同组成员:于晓菲 赵海娜 韩天 罗紫丹

高尚

哈尔滨工业大学(威海)课程设计

哈尔滨工业大学(威海)

此次课程设计主要基于DSP5509A开发板进行板上一系列功能的实验验证与实现,具体内容如下:

? LED闪烁实验

? 中断的软件编程——外部中断实验 ? 通用计时器的使用——timer实验 ? 通用计时器的使用——看门狗wdt实验 ? RTC实时时钟实验

? 外部存储器接口——SDRAM实验 ? 外部存储器接口——键盘扫描实验 ? Flash的使用——扩展flash读写实验 ? 数字信号处理——FIR&IIR滤波器实验 ? UART通信实验——McBSP的使用与配置 ? UART通信实验——McBSP软件模拟异步通信 ? 数字图像处理(一) ? 数字图像处理(二)

2

哈尔滨工业大学(威海)课程设计

一、 LED闪烁实验

(一)

GPIO简介

GPIO,通用型之输入输出(General Purpose I/O)的简称,功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。

既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电平的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电平或者低电平;对于其他特殊功能,则有另外的寄存器来控制它们。

GPIO (通用输入/输出)或总线扩展器利用工业标准I2C、SMBus?或SPI?接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。

每个GPIO端口可通过软件分别配置成输入或输出。

5509芯片提供了8个通用输入/输出引脚,即GPIO0?GPIO7。每个引脚可以通过IODIR寄存器被独立的设置为输入或输出引脚。IODATA寄存器用来监控输入引脚的状态,控制输出引脚的状态。

(二)

相关寄存器

1) IODIR寄存器

IOXDIR为输入/输出控制位。当IOXDIR=0,IOX引脚为输入引脚,当IOXDIR=1,IOX引脚为输出引脚。

1) IODATA寄存器

第0到7位IOXD为IOX数据位。

3

哈尔滨工业大学(威海)课程设计

当IOX为输入引脚,IOXD=0说明在IOX引脚上的信号为低电平,IOXD=1说明在IOX引脚上的信号为高电平。

当IOX为输出引脚,IOXD=0说明驱动IOX引脚上的信号为低电平,IOXD=1说明驱动IOX引脚上的信号为高电平。

(三)

PLL锁相环输出频率的计算

输出频率计算公式:

将输入时钟频率乘以CLKMD中PLL_MULT的值,再除以PLL_DIV的值。 PLL_MULT的取值范围是2-31。

PLL_DIV是从0(除以1)到3(除以4)。 输出频率=(PLL_MULT/(PLL_DIV+1))*输入时钟频率 例如:(24/(1+1))*12M=144M

源码及注释 #include #include #include #include void delay(); /*锁相环的设置*/

PLL_Config myConfig = {

0, //IAI: the PLL locks using the same process that was underway //before the idle mode was entered

1, //IOB: If the PLL indicates a break in the phase lock, //it switches to its bypass mode and restarts the PLL phase-locking //sequence

24, //PLL multiply value; multiply 24 times

1 //Divide by 2 PLL divide value; it can be either PLL divide value

//(when PLL is enabled), or Bypass-mode divide value //(PLL in bypass mode, if PLL multiply value is set to 1) };

4

(四)

哈尔滨工业大学(威海)课程设计

/*输出频率= (PLL_MULT/(PLL_DIV+1))*输入时钟频率 =12M*24/(1+1)=144M*/ main() {

int i = 0; /*初始化CSL库*/ CSL_init();

/*设置系统的运行速度为144MHz*/

PLL_config(&myConfig); /*时钟配置/

/*确定方向为输出*/

GPIO_RSET(IODIR,0xFF); /每个端口通过软件配置为输入或输出,1为输出*/ for(i = 0;i<0x0a;i++) {

/*全亮*/

GPIO_RSET(IODATA,0xff);//设置IODATA寄存器 delay();//延时

/*全灭*/

GPIO_RSET(IODATA,0x0); delay(); }

/*循环闪烁*/ for(;;) {

GPIO_RSET(IODATA,0x1); delay(); delay();

GPIO_RSET(IODATA,0x2); delay(); delay();

GPIO_RSET(IODATA,0x4); delay(); delay();

GPIO_RSET(IODATA,0x8); delay(); delay();

GPIO_RSET(IODATA,0x10); delay(); delay();

GPIO_RSET(IODATA,0x40); delay(); delay();

GPIO_RSET(IODATA,0x80); delay();

5

哈尔滨工业大学(威海)课程设计

delay(); } }

void delay() {

Uint32 j = 0,k = 0; for(j = 0;j<0x0c;j++) {

for(k= 0;k<0xffff;k++) {} } }

(五) 实验现象

板上LED先闪亮一次后循环点亮,每个LED灯点亮时间和熄灭时间均约1s。 二、 中断的软件编程——外部中断实验

(一)

外部中断简介

VC5509一共有5个外部中断,为INT[0-4],中断时序如下:

关于中断的处理方法,VC5509通过以下的寄存器来管理中断。

6

哈尔滨工业大学(威海)课程设计

其中:

IVPD与IVPH是中断入口的定位寄存器,也就是说VC5509的中断向量也是可以重新定位的。

IFR0、IFR1是中断状态寄存器。 IER0、IER1是中断使能寄存器。

DBIER0、DBIER1是用来确定在调试时是否将可屏蔽的中断作为事件敏感的中断处理。

在设置与修改中断向量表时应注意:

在修改中断向量表寄存器IVPD与IVPH之前,设置INTM为1,阻止外来的中断使程序跑飞。

对于不可屏蔽的中断,应有新旧两个中断向量表,来保证在修改期间,不会执行错误的指令使程序跑飞。

中断向量表的安排如下表:

7

哈尔滨工业大学(威海)课程设计

(一)

#include #include #include #include #include #include

CSLBool b;

Uint16 eventId0; int old_intm;

interrupt void int1(void);

//---------Function prototypes---------

/* Reference start of interrupt vector table */ /* This symbol is defined in file, vectors_IP.s55 */

8

源码及注释

哈尔滨工业大学(威海)课程设计

extern void VECSTART(void); /*锁相环的设置*/

PLL_Config myConfig = {

0, //IAI: the PLL locks using the same process that was underway //before the idle mode was entered

1, //IOB: If the PLL indicates a break in the phase lock, //it switches to its bypass mode and restarts the PLL phase-locking

//sequence

12, //PLL multiply value; multiply 12 times

1 //Divide by 2 PLL divide value; it can be either PLL divide value

//(when PLL is enabled), or Bypass-mode divide value //(PLL in bypass mode, if PLL multiply value is set to 1) };

/***************5509A终端设置,使能INT1中断***********************/ /*参考资料 TMS320C55x Chip Support Library API Reference Guide (Rev. J) TMS320VC5509A Data Sheet

HX-5509A 开发板使用手册 */ void INTconfig() {

/* Temporarily disable all maskable interrupts */ IRQ_setVecs((Uint32)(&VECSTART));

/* Temporarily disable all maskable interrupts */ old_intm = IRQ_globalDisable();

/* Get Event Id associated with External INT1(8019), for use with */ eventId0 = IRQ_EVT_INT0;

/* Clear any pending INT1 interrupts */ IRQ_clear(eventId0);

/* Place interrupt service routine address at */ /* associated vector location */ IRQ_plug(eventId0,&int1);

/* Enable INT1(8019) interrupt */ IRQ_enable(eventId0);

/* Enable all maskable interrupts */ IRQ_globalEnable(); } main() {

/*初始化CSL库*/ CSL_init();

9

哈尔滨工业大学(威海)课程设计

/*EMIF为全EMIF接口*/

CHIP_RSET(XBSR,0x0a01);

/*设置系统的运行速度144MHz*/ PLL_config(&myConfig);

//设置并使能5509A芯片的INT0中断(EXINT中断) INTconfig();

while(1); }

//External INT0(EXINT)中断处理函数 interrupt void int1() {

int i,j;

printf(\ for(i=0; i<0xfff; i++) {

for(j=0; j<0xffff; j++) { ; } } }

(一) 实验现象及分析

当按下中断的按键时,打印出EXINT occurs。 注意程序的最后一段: for(i=0; i<0xfff; i++) {

for(j=0; j<0xffff; j++) { ; }

}

这段程序是作延时消按键抖动之用的,实际情况下可合理设置到几十毫秒左右。如果不加这一段程序,按键抖动可能导致打印出几行EXINT occurs而不是一行,产生错误。

10

哈尔滨工业大学(威海)课程设计

三、 通用计时器的使用——timer实验

(一)

通用定时器包括一个4位的预定标计数器(PSC)和一个16位的主计数器(TIM),从而提供20位的动态范围。它还包含两个周期寄存器,即TDDR和PRD。Timer的结构如下图:

通用定时器Timer简介

在Timer初始化过程中,周期寄存器中的内容加载给计数器,其中TDDR加载到PSC,PRD加载到TIM中,开始工作。Timer控制寄存器TCR控制并监控Timer的操作及其引脚(TIN/TOUT)。

PSC由CPU输入时钟或者外部时钟驱动,计数器工作,开始计数。计时器发出信号的速率

11

哈尔滨工业大学(威海)课程设计

(一)

相关寄存器

2个计数寄存器 和2个周期寄存器 PSC预定标计数器 TIM 主计数寄存器 TDDR预定标周期寄存器 PRD 主周期计数器

计时器控制寄存器 TCR

TCR可以实现Timer的配置、工作、停止、加载、重新加载等。

12

哈尔滨工业大学(威海)课程设计

1) IDLEEN:Timer的空闲使能位。IDLEEN=0,Timer不能置于空闲状态;IDLEEN=1,当PERIPH域为空闲状态,Timer终止在低功耗状态。

2) FUNC:可以将定时器引脚配置为:通用输出(10b);计时器输出(01b);一个时钟输入(11b)或高阻状态 (00b)。

3) TLB:Timer加载位。当TLB=0,TIM与PSC不被加载;直到TLB=1,PRD加载到TIM,TDDR加载到PSC。

4) SOFT:Soft终止位。SOFT=0,硬终止,Timer直接终止;SOFT=1,软终止,当main中的TIM计数到0时终止。

5) FREE:自由运行位。 FREE=0,Timer如受SOFT位一样被影响;FREE=1,Timer继续运行。

6) PWID:定时器输出的脉冲宽度位。1个CPU时钟周期(00b);2个CPU时钟周期(01b);4个CPU时钟周期(10b);8个(11b)。

7) ARB:自动重新装入位。ARB=1,主计数器(TIM)一旦减少为0,计数寄存器自动从周期寄存器重新装入 。

8) TSS:Timer停止状态位。TSS=0,启动Timer;TSS=1,终止Timer; 9) CP:时钟模式/脉冲模式位。CP=0,脉冲模式;CP=1,时钟模式。 10) DATOUT:数据输出位。DATOUT=0,驱动Timer引脚信号为低;DATOUT=1,驱动Timer引脚信号为高。

11) 源码及注释

#include #include #include #include #include extern void VECSTART(void);

#define TIMER_CTRL TIMER_TCR_RMK(\\

TIMER_TCR_IDLEEN_DEFAULT, /* IDLEEN == 0 */ TIMER_TCR_FUNC_OF(0), /* FUNC == 0 */ TIMER_TCR_TLB_RESET, /* TLB == 1 */ TIMER_TCR_SOFT_BRKPTNOW, /* SOFT == 0 */ TIMER_TCR_FREE_WITHSOFT, /* FREE == 0 */ TIMER_TCR_PWID_OF(0), /* PWID == 0 */ TIMER_TCR_ARB_RESET, /* ARB == 1 */

13

哈尔滨工业大学(威海)课程设计

TIMER_TCR_TSS_START, /* TSS == 0 */ TIMER_TCR_CP_PULSE, /* CP == 0 */ TIMER_TCR_POLAR_LOW, /* POLAR == 0 */ TIMER_TCR_DATOUT_0 /* DATOUT == 0 */ )

/*Timer寄存器配置,信号输出频率1Khz左右*/ TIMER_Config timCfg0 = {

TIMER_CTRL, /* TCR0 */ 0x3400u, /* PRD0 */ 0x0000 /* PRSC */ };

Uint16 eventId0;

/* Create a TIMER_Handle object for use with TIMER_open */ TIMER_Handle mhTimer0;

volatile Uint16 timer0_cnt = 0; /* Function/ISR prototypes */ interrupt void timer0Isr(void); void taskFxn(void);

int old_intm; Uint16 tim_val;

Uint16 xfchange = 0; //控制输出方向/

void main(void) {

/*CLS库的初始化,这是必需的*/ CSL_init();

/*修改寄存器IVPH,IVPD重新定义中断向量表*/ IRQ_setVecs((Uint32)(&VECSTART));

/*禁止所有可屏蔽的中断源*/

old_intm = IRQ_globalDisable();

/*打开定时器0,设置其为上电的默认值,并返回其句柄*/

mhTimer0 = TIMER_open(TIMER_DEV0, TIMER_OPEN_RESET);

/* CSL interrupt enable functions. */ /*获得定时器0的中断ID号*/

eventId0 = TIMER_getEventId(mhTimer0);

/*清除定时器0的中断状态位*/ IRQ_clear(eventId0);

14

哈尔滨工业大学(威海)课程设计

/*为定时器0设置中断服务程序*/

IRQ_plug(eventId0,&timer0Isr);

/*设置定时器0的控制与周期寄存器*/

TIMER_config(mhTimer0, &timCfg0);

/*使能定时器的中断*/

IRQ_enable(eventId0);

/*设置寄存器ST1的INTM位,使能所有的中断*/ IRQ_globalEnable();

/*启动定时器0*/

TIMER_start(mhTimer0); for(;;) {

/* Wait for at least 10 timer periods */ /*等待10个定时周期*/ if(xfchange == 0) {

/*点亮XF的LED*/

CHIP_FSET(ST1_55,XF,1); } else {

/*关掉XF的LED*/

CHIP_FSET(ST1_55,XF,0); } /*XF输出01010101…*/ }

/* Restore old value of INTM */ /*恢复INTM旧的值*/

IRQ_globalRestore(old_intm);

/* We are through with timer, so close it */ /*关掉定时器0*/

TIMER_close(mhTimer0); }

/*定时器0的中断程序*/

interrupt void timer0Isr(void) {

++timer0_cnt;

if(timer0_cnt == 1000)

15

哈尔滨工业大学(威海)课程设计

{

xfchange = 1; }

if(timer0_cnt == 2000) {

timer0_cnt = 0; xfchange = 0; } }

(二) 实验现象

板上LED灯闪亮,间隔时间约1s。

四、 通用计时器的使用——看门狗wdt实验

(一)

看门狗简介

1. 概念

硬件看门狗是利用了一个定时器,来监控主程序的运行,也就是说在主程序的运行过程中,我们要在定时时间到之前对定时器进行复位如果出现死循环,或者说PC指针不能回来。那么定时时间到后就会使单片机复位。常用的WDT芯片MAX813 ,5045, IMP 813等。

软件看门狗技术的原理和这差不多,只不过是用软件的方法实现,用DSP的片上外设资源定时器timer来对主程序的运行进行监控。

2. 作用

监控主程序的运行,也就是说在主程序的运行过程中,我们要在定时时间到之前对定时器进行复位如果出现死循环,或者说PC指针不能回来。那么定时时间到后就会使DSP复位。 即:防止因为软件死循环而造成的系统死锁。

3. HX-5509看门狗的结构

Watchdog Timer包括一个16bit的预定标计数器和一个16bit的主计数器 ,从而提供一个32bit动态范围的计数器

16

哈尔滨工业大学(威海)课程设计

当预定标计数器达到0时,就会被重新加载,并重新开始计数。

装入的值由WDTCR中TDDR位+ WDTCR2中的预定标模式PREMD位来决定。当PREMD位为0时,4位TDDR域的值直接加载到预定标计数器上,提供20位动态范围;当PREMD位为1时,预定标计数器通过非直接的方式加载16位的TDDR,这种模式提供32位动态范围的看门狗计时器。

当主计时器减为0时,产生超时事件,引发以下的可编程事件:

00b,一个看门狗定时器中断 10b,DSP复位

01b,一个非屏蔽中断(NMI) 11b,不发生任何事件

所产生的超时事件,通过编程控制寄存器WDTCR中的WDOUT域来控制 (二)

相关寄存器

计数器寄存器

WDTIM

WDPRD 周期寄存器 WDTCR 控制寄存器 WDTCR2 控制寄存器2 1.WDTCR:看门狗控制寄存器

17

哈尔滨工业大学(威海)课程设计

WDOUT:用来控制超时引发的可编程事件

PSC:当PREMD=0时,用来存放预定标计数器的值。

TDDR:当PREMD=0时,若预定标计数器的值减为0,则将TDDR加载到预定标计数器中。当PREMD=1时,若预定标计数器的值减为0,则通过TDDR中的值选择加载到预定标计数器中的数。

1. WDTCR2:看门狗控制寄存器

PREMD:预定标寄存器模式选择位,0为直接模式,1为间接模式。 2. WDPRD:看门狗周期寄存器

WDPRD用来加载看门狗定时器主计数寄存器(WDTIM)。

源码及注释

#include

#include #include

(三)

int i, pscVal;

WDTIM_Config getConfig; /*配置寄存器*/

WDTIM_Config myConfig = {

18

哈尔滨工业大学(威海)课程设计

0x1000, /* WDPRD */ 0x0000, /* WDTCR */ 0x1000 /* WDTCR2 */

};/*这里看门狗配置时机还未完成,只是一个初始化,下面单独的域配置才算完*/ main() {

CSL_init();

WDTIM_config(&myConfig);//寄存器设置

/*对重要寄存器的域单独设置*/

WDTIM_FSET(WDTCR, WDOUT, 1); /*产生超时事件时引发非屏蔽中断 */ WDTIM_FSET(WDTCR, TDDR, 0xF); /* 设置加载PSC域的值 */ WDTIM_FSET(WDTCR2, PREMD, 0); /* 设置为直接模式 */ /*就是这里,这才算配置完了 在WDTIM_service之前配置完~*/ WDTIM_service(); /* 使能看门狗计时器 */

for (;;) {

WDTIM_getConfig(&getConfig); pscVal = WDTIM_FGET(WDTCR,PSC); printf(\ pscVal, getConfig.wdtcr); } }

(四) 实验结果显示

pscVal: 0, wdtcr: 110f pscVal: 9, wdtcr: 134f pscVal: 6, wdtcr: 128f pscVal: 3, wdtcr: 11cf pscVal: 0, wdtcr: 110f pscVal: 9, wdtcr: 134f

五、 RTC实时时钟实验

(一)

RTC简介

RTC为运行在DSP上的应用程序提供了一个时间基准。当前的日期和时间由一组时间寄存器提供,每秒更新一次。

RTC时钟来源于一个外部频率为32768Hz的晶振,连接在RTCINX1和RTCINX2

19

哈尔滨工业大学(威海)课程设计

信号之间,或一个同频率的外部时钟源。

RTC有单独电源,与DSP的其他部分分开。因此即使DSP没有上电,RTC也能保存当前的时间和日期信息。在这种情况下,RTC的各计时器将持续工作,但不能引起DSP的中断,因为DSP本身没有供电。

RTC提供了中断CPU的能力,它基于以下三个事件:周期中断,定时中断或者更新-结束中断。尽管这三个中断源都是可用的,RTC仍然会给CPU一个单独的中断请求。

(二)

时间日期寄存器的读写

寄存器随着时间的改变每秒更新一次。

为保证该寄存器所存储的时间的准确性,RTC为访问该寄存器提供了1个读缓冲区和1个写缓冲区

RTCINTEN中的SET位用来控制读写缓冲区与时间日期寄存器的隔离。SET=0,读写缓冲区直接连接到时间日期寄存器; SET=1,时间日期寄存器复制到读缓冲区,此时写缓冲区与时间日期寄存器隔离。

向时间日期寄存器写新时间日期步骤:

1) 将RTCINTEN中的SET位置1,此时,写缓存器与时间日期寄存器隔离; 2) 在时间日期寄存器(RTCSECA,RTCMINA,RTCHOURA和RTCDAYW)写入希望的时间和日期,可使用函数RTC_set。当SET=1时,这些数值进入写缓冲区;

3) 将SET位清零,写缓冲区的值直接赋给时间日期寄存器。可用函数

20

哈尔滨工业大学(威海)课程设计

RTC_start 清零。

当RTC更新当前的时间/日期后,时间日期寄存器就可以直接读数。 (三)

源程序及注释

#include #include #include #include void myPeriodicIsr(void); void myUpdateIsr(void);

extern Uint32 VECSTART(); //the content found at the label myVec is of type Uint32

volatile Uint16 rtc_cnt = 0;

volatile Uint16 counterPer = 0, counterUp = 0, sec; int min0, min1 = 0; int stop = 0; int old_intm; int eventId;

RTC_Date myDate = { 0x03, /* Year */ 0x02, /* Month */ 0x28, /* Daym */ 0x05 /* Dayw */ };

RTC_Time myTime = {

0x1, /* Hour */ 0x4, /* Minutes */ 0x59, /* Seconds */ };

RTC_IsrAddr addr = {

myPeriodicIsr, //当周期中段发生时返回的函数指针// NULL, //当定时中断发生时返回的函数指针// myUpdateIsr //当更新中断发生时返回的函数指针// };//RTC的回调函数,建立并初始化后, //该结构被传递到 RTC_setCallback()中// main() {

CSL_init();

//Configure RTC time and date

21

哈尔滨工业大学(威海)课程设计

//RTC工作时SET默认为1 //写我们的时间日期

RTC_setTime(&myTime); RTC_setDate(&myDate);

//在RTC_start之前都是关于开关全局中断的语句 old_intm = IRQ_globalDisable(); //关掉全局中断

IRQ_setVecs((Uint32)(&VECSTART));//set IVPD 将中断向量表映射

/* Clear any pending RTC interrupts */ eventId = RTC_getEventId(); IRQ_clear(eventId);

//关联RTC中断事件(周期中断,定时中断,更新结束事件)函数

//注意这里的中断都不能使用interrupt(用来声明中断服务程序)关键字来定义 //定义在下面

RTC_setCallback(&addr);

/* Set the RTC periodic interval */ //RTC_setPeriodicInterval(RTC_RATE_250ms); //设置周期中断的间隔是500ms,所以每秒发生两次 RTC_setPeriodicInterval(RTC_RATE_500ms);

/* Enable all maskable interrupts */ //全局使能,使能所有中断 IRQ_globalEnable();

/* Start RTC */

RTC_start(); //清零SET位,打开RTC计时

//RTC_FSET(RTCINTEN,SET,0); //可以用这个语句来代替RTC_start

sec = RTC_RGET(RTCSEC); //读寄存器秒针时间

while (sec != 0) {

sec = RTC_RGET(RTCSEC); }

/* Enable alarm interrupt to start at 1::5::0 - one second after clock is started */ //进中断,中断使能

RTC_eventEnable(RTC_EVT_PERIODIC); RTC_eventEnable(RTC_EVT_UPDATE);

min0 = RTC_RGET(RTCMIN); //起始分钟数

22

哈尔滨工业大学(威海)课程设计

/* Wait for interrupt to happen */

while (!stop) //let interrupts occur for a minute {

while (RTC_FGET(RTCPINTR,UIP) != 0); min1 = RTC_RGET(RTCMIN);//实时读到的分钟数

if ((min1 - min0) >= 1) //超过一分钟退出中断 {

RTC_eventDisable(RTC_EVT_PERIODIC); // disable periodic interrupt after a minute

RTC_eventDisable(RTC_EVT_UPDATE); // disable update interrupt after a minute stop = 1; } }

printf(\interrupts - successful\\n\

RTC_stop(); //关闭RTC for(;;) {} }

void myPeriodicIsr() //注意这里的中断不能使用interrupt关键字来定义 {

++counterPer;

//sec = RTC_RGET(RTCSEC);

printf(\

RTC_FGET(RTCHOUR, HR), min1, RTC_RGET(RTCSEC)); //asm(\routine\ }

void myUpdateIsr() {

++counterUp;

sec = RTC_RGET(RTCSEC);

printf(\ RTC_FGET(RTCHOUR, HR), min1, sec);

//asm(\ }

23

哈尔滨工业大学(威海)课程设计

(一) 实验现象

程序显示计时从1时5分0秒到1时5分59秒,如下:

Update interrupt at: 1::5::0 Periodic interrupt at: 1::5::0 Periodic interrupt at: 1::5::0 Update interrupt at: 1::5::1 Periodic interrupt at: 1::5::1 Periodic interrupt at: 1::5::1 ?-

Update interrupt at: 1::5::59 Periodic interrupt at: 1::5::59 Periodic interrupt at: 1::5::59

RTC - testing a combination of update and periodic interrupts ¨C successful

六、 外部存储器接口——SDRAM实验

(一)

外部存储器接口 EMIF

外部存储器接口(EMIF),External Memory Interface,是TMS DSP器件上的一种接口。 EMIF控制DSP和外部存储器之间的所有数据传输。如下图:

24

哈尔滨工业大学(威海)课程设计

一般来说,EMIF可实现DSP与不同类型存储器的连接。3种类型的存储器提供无缝接口:异步存储器,比如ROM,FLASH;同步突发SRAM(SBSRAM);同步DRAM(SDRAM)。

可接CPLD或不接CPLD对EMIF进行操作,有以下区别:

不接CPLD,对EMIF的操作,只需配置好相关存储器的寄存器,就可以直接进行读写访问;接CPLD,相当于在EMIF操作的前期映射了一个全局的管理寄存器,要对EMIF操作,就必须先对CPLD进行读写,再进行EMIF的读写操作。

(二)

存储器映射和CE空间的配置

对EMIF编程时,必须了解外部存储器地址如何分配给片使能(CE)空间,每个CE空间可以同哪些类型的存储器连接,以及用哪些寄存器bit来配置CE空间。

当EMIF访问CE0空间时,就驱动/CE0变低,使能片选CE0上挂着存储器。 在5509中使用全局控制寄存器(EGCR)和每个CE空间控制寄存器来配置CE空间。SDRAM是同步存储器类型,只需在CE空间控制寄存器里初始化MTYPE域。MTYPE所指示的类型如下:

(三)

SDRAM的访问

SDRAM的存储空间:

25

哈尔滨工业大学(威海)课程设计

开发板上已通过5509的EMIF总线扩展了一片SDRAM,在标准配置时,板上安装一片64M位(4M*16位)的SDRAM,它将占用5509的CE0和CE1两个片外存储空间,可寻址范围为0x040000-0x7fffff;最大配置时,板上可安装一片128M位(8M*16位)的SDRAM,它将占用5509的CE0-CE3全部四个片外存储空间,可寻址范围为0x040000-0xffffff(MPNMC=1时),上电复位时,MPNMC被清为0。根据5509的EMIF接口的特性,SDRAM的工作频率为CPU主时钟的一半,例如主时钟144MHz时,SDRAM的工作频率为72MHz。

对于CE0空间的SDRAM,读写操作不与CPLD的功能寄存器组挂钩,可以直接配置EMIF后读写SDRAM;而对于CE1和CE2的空间,比如SDRAM在CE1有映射,那么必须遵循先对功能寄存器组读写操作时序,才能读写SDRAM。

(四)

源码和注释

#include #include #include #include

Uint16 x; Uint32 y; CSLBool b;

unsigned int datacount = 0; int databuffer[1000] ={0}; int *souraddr,*deminaddr; /*锁相环的设置*/

PLL_Config myConfig = {

0, //IAI: the PLL locks using the same process that was underway //before the idle mode was entered

1, //IOB: If the PLL indicates a break in the phase lock, //it switches to its bypass mode and restarts the PLL phase-locking

//sequence

24, //PLL multiply value; multiply 24 times

1 //Divide by 2 PLL divide value; it can be either PLL divide value

//(when PLL is enabled), or Bypass-mode divide value //(PLL in bypass mode, if PLL multiply value is set to 1) };

/*SDRAM的EMIF设置*/ EMIF_Config emiffig = {

26

哈尔滨工业大学(威海)课程设计

0x221,

//EGCR : the MEMFREQ = 00,the clock for the memory is equal //

the WPE = 0 ,forbiden the writing posting when we

to cpu frequence debug the EMIF

// the MEMCEN = 1,the memory clock is reflected on the // the NOHOLD = 1,HOLD requests are not recognized by //EMI_RST: any write to this register resets the EMIF state //CE0_1: CE0 space control register 1

// MTYPE = 011,Synchronous DRAM(SDRAM),16-bit data bus

CLKMEM pin the EMIF 0xFFFF, machine 0x3FFF, width

0xFFFF, //CE0_2: CE0 space control register 2 0x00FF, //CE0_3: CE0 space control register 3

// TIMEOUT = 0xFF;

//CE1_1: CE0 space control register 1 //CE1_2: CE0 space control register 2 //CE1_3: CE0 space control register 3 //CE2_1: CE0 space control register 1 //CE2_2: CE0 space control register 2 //CE2_3: CE0 space control register 3 //CE3_1: CE0 space control register 1 //CE3_2: CE0 space control register 2 //CE3_3: CE0 space control register 3

0x7FFF, 0xFFFF, 0x00FF, 0x7FFF, 0xFFFF, 0x00FF, 0x7FFF, 0xFFFF, 0x00FF,

0x2911, //SDC1: SDRAM control register 1

//

TRC = 8

// SDSIZE = 0;SDWID = 0 // RFEN = 1 // TRCD = 2 // TRP = 2

//SDPER : SDRAM period register //

7ns *4096

0x0410,

0x07FF, //SDINIT: SDRAM initialization register

// any write to this register to init the all CE spaces, // do it after hardware reset or power up the C55x device // SDACC = 0; // TMRD = 01; // TRAS = 0101; // TACTV2ACTV = 0001;

27

0x0131 //SDC2: SDRAM control register 2

哈尔滨工业大学(威海)课程设计

}; main() {

/*初始化CSL库*/ CSL_init();

/*EMIF为全EMIF接口*/ CHIP_RSET(XBSR,0x0a01);

/*设置系统的运行速度为144MHz*/ PLL_config(&myConfig);

/*初始化DSP的外部SDRAM*/ EMIF_config(&emiffig); /*向SDRAM中写入数据*/ souraddr = (int *)0x40000; deminaddr = (int *)0x41000; while(souraddr

*souraddr++ = datacount*2; datacount++ ; }

/*读出SRAM中的数据*/ souraddr = (int *)0x40000; datacount = 0;

while(souraddr

databuffer[datacount++] = *souraddr++; }

while(1); }

(五) 实验现象及分析

在memory中观察数据的变化情况:

向SDRAM写数据之前,databuffer中数据显示如下:

28

哈尔滨工业大学(威海)课程设计

说明数据还没有刷新;

当向SDRAM写完数据,读出数据之后,databuffer中数据显示如下:

说明已刷新数据,红色字体即表示数据经过刷新。注意此处设置了数据增量的步长为2。

七、 外部存储器接口——键盘扫描实验

(一)

寄存器组映射

TMS320VC5509A 开发板一共有6个扩展寄存器组,用于与板上外设如按键、网络芯片等通信,进行控制或读写信息。这些寄存器通过CPLD扩展,分别是:

(1)功能选择寄存器组

29

哈尔滨工业大学(威海)课程设计

(2)按键寄存器组

(3)Flash地址扩展寄存器组 (4)网络控制寄存器组 (5)LCD控制寄存器组 (6)LCD数据寄存器组 1. 功能寄存器组

功能寄存器组的读写时序:

因为功能寄存器组实际上通过CPLD对DSP和EMIF外设存储器的地址线以及握手信号的控制,所以对功能寄存器组的操作也就是通过DSP给CPLD发命令信号,类似于“一问一答”,那么这个一问一答的时序就很重要。我们HX-5009开发板的功能选择寄存器组是利用CE2,CE3存储空间对各操作寄存器组进行访问操作。

2. 寄存器组的访问

读操作:写功能寄存器组=写CE2任意地址;使能要操作的目标寄存器组;读目标寄存器组=读CE2任意地址;读操作完成后,写功能寄存器组,禁止所有寄存器组。

1) 功能选择寄存器组(W,只写)

功能寄存器组用于选择与切换对其它寄存器组的控制功能,其各位的含义如下: D15-D6 X D5 LCDDIR D4 ALCDC D3 ALDCDD D2 ANET D1 AFLASH D0 AKEY AKEY:控制按键寄存器组的使能,0为使能,1为禁用 2) 按键寄存器组(R,只读)

以K1为例,按下时寄存器值为1110(0xE)。 扫描操作只关心D0位。

30

哈尔滨工业大学(威海)课程设计

按键寄存器组用于读取按键K1-K4的状态,其各位含义如下: D15-D4 X D3 K4 D2 K3 D1 K2 D0 K1 X:无影响,可取任意值

K4:读取K4的状态值,按下为0,未按下为1 K3:读取K3的状态值,按下为0,未按下为1 K2:读取K2的状态值,按下为0,未按下为1 K1:读取K1的状态值,按下为0,未按下为1 (二)

源码及注释

#include #include #include #include #include

Uint16 x; Uint32 y; CSLBool b;

unsigned int datacount = 0; int databuffer[1000] ={0}; int *souraddr,*deminaddr; Uint16 button;

unsigned char k1_down, k2_down, k3_down, k4_down; /*锁相环的设置*/

PLL_Config myConfig = {

0, //IAI: the PLL locks using the same process that was underway //before the idle mode was entered

1, //IOB: If the PLL indicates a break in the phase lock, //it switches to its bypass mode and restarts the PLL phase-locking

//sequence

24, //PLL multiply value; multiply 24 times

1 //Divide by 2 PLL divide value; it can be either PLL divide value

//(when PLL is enabled), or Bypass-mode divide value

31

哈尔滨工业大学(威海)课程设计

//(PLL in bypass mode, if PLL multiply value is set to 1) };

/*SDRAM的EMIF设置*/ EMIF_Config emiffig = {

0x221, //EGCR : the MEMFREQ = 00,the clock for the memory is equal to cpu frequence

//

the WPE = 0 ,forbiden the writing posting when we

debug the EMIF

// the MEMCEN = 1,the memory clock is reflected on the // the NOHOLD = 1,HOLD requests are not recognized by

CLKMEM pin the EMIF

0xFFFF, //EMI_RST: any write to this register resets the EMIF state machine

0x3FFF, //CE0_1: CE0 space control register 1 width

0xFFFF, //CE0_2: CE0 space control register 2 0x00FF, //CE0_3: CE0 space control register 3

// TIMEOUT = 0xFF;

0x1FFF, //CE1_1: CE0 space control register 1 // Asynchronous, 16Bit 0xFFFF, //CE1_2: CE0 space control register 2 0x00FF, //CE1_3: CE0 space control register 3 0x1FFF, //CE2_1: CE0 space control register 1 // Asynchronous, 16Bit 0xFFFF, //CE2_2: CE0 space control register 2 0x00FF, //CE2_3: CE0 space control register 3

0x7FFF, //CE3_1: CE0 space control register 1 0xFFFF, //CE3_2: CE0 space control register 2 0x00FF, //CE3_3: CE0 space control register 3

0x2911, //SDC1: SDRAM control register 1

//

TRC = 8

// SDSIZE = 0;SDWID = 0 // RFEN = 1 // TRCD = 2 // TRP = 2 //

7ns *4096

// MTYPE = 011,Synchronous DRAM(SDRAM),16-bit data bus

0x0410, //SDPER : SDRAM period register

0x07FF, //SDINIT: SDRAM initialization register

// any write to this register to init the all CE spaces, // do it after hardware reset or power up the C55x device

32

哈尔滨工业大学(威海)课程设计

0x0131 //SDC2: SDRAM control register 2 }; main() {

/*初始化CSL库*/ CSL_init();

/*EMIF为全EMIF接口*/ CHIP_RSET(XBSR,0x0a01);

/*设置系统的运行速度为144MHz*/ PLL_config(&myConfig);

/*初始化DSP的EMIF*/ EMIF_config(&emiffig);

souraddr = (int *)0x400001; *souraddr = 0x00fe; while(1) {

button = *souraddr; //scan K1

if(!(button&0x0001)) { } else { }

//scan K2

if(!(button&0x0002)) {

if(k2_down==0)

33

// SDACC = 0; // TMRD = 01; // TRAS = 0101; // TACTV2ACTV = 0001;

if(k1_down==0) { }

printf(\k1_down = 1;

k1_down = 0;

哈尔滨工业大学(威海)课程设计

{ printf(\ k2_down = 1;

}

}

else { k2_down = 0;

}

//scan K3

if(!(button&0x0004)) { if(k3_down==0) { printf(\ k3_down = 1; }

} else { k3_down = 0; }

//scan K4

if(!(button&0x0008)) { if(k4_down==0) { printf(\ k4_down = 1; }

} else { k4_down = 0; }

} }

三) 实验结果

当按下按键时,会打印出对应的语句,如:按下K1键,即打印出K1 press

34

(

哈尔滨工业大学(威海)课程设计

注意上面的源码没有进行消抖,即按下一次按键可能打印出几行相同的语句。解决这一问题的方法是可在扫描时加入延时消抖。 八、 Flash的使用——扩展flash读写实验

(一)

Flash介绍

Am29LV800B :8 Megabit (1 M x 8-Bit/512 K x 16-Bit),Am29LV800B简称LV800,它是一个低功耗flash,工作在2.7 - 3.6v电压下,一般来说存储数据可以保存100年以上,可以重复编程次数高达10万次。A18到A0为外部地址管脚, DQ0–DQ15为16条数据线,CE#为片选控制管脚(低有效),OE#为输出控制管脚(低有效),WE#为写入控制管脚(低有效)。各种flash芯片的编程原理大同小异,只要掌握一种flash的编程方法即可。

hx-5509开发板是5509A即PGE封装,只有14根地址线,所以片选异步空间为8k×16位;而CE1的编址空间为字地址0x200000~0x400000,共4MB,即2M×16位,那么要完全访问这个CE1空间需要21根地址线!本例程的地址线扩展方式:Dsp的13根地址线连接flash,而第14根地址线由cpld来实现扩展。

(二)

擦除

Flash一般有3种擦除方式:1按扇区擦除,2按块擦除,3整片擦除。前两种方法为写入小程序时采用的部分擦除方法。后一种方法适用于大程序编程写入flash。本实验例程给出了第三种擦除方法。

擦除步骤: 步骤 地址(0x) 数据(0x) 在整片擦除中,依次向上表的地址处写入表中的数据,A13-A18受CPLD控制,A0-A12映射在DSP空间中。

35

1 555 AA 2 2AAA 55 3 555 80 4 555 AA 5 2AA 55 6 555 10 哈尔滨工业大学(威海)课程设计

OE#CE#都被CPLD控制,DSP要想读写flash,必须先让CPLD跟flash“握手”。

(三)

DSP的c语言

强制cast:在嵌入式dsp的c语言中,为了访问一个绝对地址,而把一个整型数强制转换(typecast)为一个指针是合法的;比如

int *ptr;

ptr=(int *)0x200000;//ptr指向0x200000这个int地址 *ptr=0x5555;//向0x200000int地址赋值。

而Widons编程中直接访问固定的内存地址并且赋值,编译器是会报错的。 (四)

软件编程

void Flash_CS() { }

deminaddr = (int *)CESECT2; *deminaddr = 0x00fd; *deminaddr = 0x0040; deminaddr = (int *)CESECT2; *deminaddr = 0x00ff;

deminaddr = (int *)CESECT3;

36

哈尔滨工业大学(威海)课程设计

(1)写功能选择寄存器组(写CE2空间任意地址),使能需要操作的目标寄存器组:

功能寄存器组(W,只写)

功能寄存器组用于选择与切换对其它寄存器组的控制功能,其各位的含义如下: D15-D6 X D5 LCDDIR D4 ALCDC D3 ALDCDD D2 ANET D1 AFLASH D0 AKEY X:无影响,可取任意值

LCDDIR:控制LCD的数据输入/输出方向,0为写LCD,1为读LCD ALCDC:控制LCD控制寄存器组的使能,0为使能,1为禁用 ALCDD:控制LCD数据寄存器组的使能,0为使能,1为禁用 ANET:控制8019网络芯片控制寄存器组的使能,0为使能,1为禁用 AFLASH:控制Flash地址扩展寄存器组的使能,0为使能,1为禁用 AKEY:控制按键寄存器组的使能,0为使能,1为禁用 (2)写目标寄存器组(写CE3空间任意地址);

Flash地址扩展寄存器组(W,只写) D15-D8 X D7 FCE D6 FRST D5 FA18 D4 FA17 D3 FA16 D2 FA15 D1 FA14 D0 FA13 X :无影响,可取任意值

FCE:AM29LV800片选信号,0为选中,1为禁用 FRST:复位AM29LV800,0为复位

FA18-FA13:AM29LV800的18-13位地址线

(3)读操作完成后,写功能选择寄存器组,禁用所有寄存器组。

功能选择寄存器(W,只写)

功能寄存器组用于选择与切换对其它寄存器组的控制功能,其各位的含义如下: D15-D6 X D5 LCDDIR D4 ALCDC D3 ALDCDD D2 ANET D1 AFLASH D0 AKEY X:无影响,可取任意值

37

哈尔滨工业大学(威海)课程设计

LCDDIR:控制LCD的数据输入/输出方向,0为写LCD,1为读LCD ALCDC:控制LCD控制寄存器组的使能,0为使能,1为禁用 ALCDD:控制LCD数据寄存器组的使能,0为使能,1为禁用 ANET:控制8019网络芯片控制寄存器组的使能,0为使能,1为禁用 AFLASH:控制Flash地址扩展寄存器组的使能,0为使能,1为禁用 AKEY:控制按键寄存器组的使能,0为使能,1为禁用 (4)写编程

编程步骤有4步:

一般的,写数据到flash内部时,通常应该擦除这部分的内容;否则,可能会出现误码。因此,擦除这一步一般是必不可少的 步骤 1 2 3 4 (五)

地址 0x555 0x2AA 0x555 编程地址 Flash的程序设计

数据 0xAA 0x55 0xA0 编程数据 1)编程使flash进入正常工作状态 2)将要编程的flash空间擦除 3)写flash

4)将写入flash的中数据读出,进行读出校验

注意:操作(读/写)flash前都要进行cpld片选flash的握手操作,即调用CS函数,操作完毕要释放dsp对flash的片选,调用disCS函数。

(六)

源码与注释

#include #include #include #include

#define CESECT1 0x200000 #define CESECT2 0x400000 #define CESECT3 0x600000

38

哈尔滨工业大学(威海)课程设计

Uint16 x; Uint32 y; CSLBool b;

unsigned int datacount = 0;

unsigned int databuffer[1000] ={0}; int *souraddr,*deminaddr; int *fwaddr, *fraddr; Uint16 addbias;

Uint16 fstatus, fstatus2; Uint16 success;

/*锁相环的设置*/

PLL_Config myConfig = {

0, //IAI: the PLL locks using the same process that was underway //before the idle mode was entered

1, //IOB: If the PLL indicates a break in the phase lock, //it switches to its bypass mode and restarts the PLL phase-locking

//sequence

12, //PLL multiply value; multiply 12 times

1 //Divide by 2 PLL divide value; it can be either PLL divide value

//(when PLL is enabled), or Bypass-mode divide value //(PLL in bypass mode, if PLL multiply value is set to 1) };

/*SDRAM的EMIF设置*/ EMIF_Config emiffig = { 0x221,

//EGCR : the MEMFREQ = 00,the clock for the memory is equal //

the WPE = 0 ,forbiden the writing posting when we

to cpu frequence debug the EMIF

// the MEMCEN = 1,the memory clock is reflected on the // the NOHOLD = 1,HOLD requests are not recognized by //EMI_RST: any write to this register resets the EMIF state //CE0_1: CE0 space control register 1

// MTYPE = 011,Synchronous DRAM(SDRAM),16-bit data bus

CLKMEM pin the EMIF 0xFFFF, machine 0x3FFF, width

0xFFFF, //CE0_2: CE0 space control register 2 0x00FF, //CE0_3: CE0 space control register 3

39

哈尔滨工业大学(威海)课程设计

// TIMEOUT = 0xFF;

//CE1_1: CE0 space control register 1 //CE1_2: CE0 space control register 2 //CE1_3: CE0 space control register 3 //CE2_1: CE0 space control register 1 //CE2_2: CE0 space control register 2 //CE2_3: CE0 space control register 3 //CE3_1: CE0 space control register 1 //CE3_2: CE0 space control register 2 //CE3_3: CE0 space control register 3

0x1FFF, 0xFFFF, 0x00FF, 0x1FFF, 0xFFFF, 0x00FF, 0x1FFF, 0xFFFF, 0x00FF,

// Asynchronous, 16Bit

// Asynchronous, 16Bit

// Asynchronous, 16Bit

0x2911, //SDC1: SDRAM control register 1 };

void delay(Uint16 k) { }

void ddelay(Uint16 kt) {

40

// TRC = 8

// SDSIZE = 0;SDWID = 0 // RFEN = 1 // TRCD = 2 // TRP = 2

//SDPER : SDRAM period register //

7ns *4096

0x0410,

0x07FF, //SDINIT: SDRAM initialization register

// any write to this register to init the all CE spaces, // do it after hardware reset or power up the C55x device // SDACC = 0; // TMRD = 01; // TRAS = 0101; // TACTV2ACTV = 0001;

0x0131 //SDC2: SDRAM control register 2

while(k>0) { }

k--;

哈尔滨工业大学(威海)课程设计

Uint16 jj,kk; }

/*************以下内容为AM29LV800BT的读写等函数**************/ /* 参考:AM29LV800BT的芯片手册

TMS320VC5509 DSP External Memory Interface (EMIF) Reference Guide */

void Flash_CS() { }

void Flash_disCS() { }

void Flash_Reset() //AM29LV800复位 {

deminaddr = (int *)CESECT2; *deminaddr = 0x00fd; *deminaddr = 0x0000; delay(1000);

*deminaddr = 0x0040;

41

for(jj=0;jj<65535;jj++) { }

kk = kt; while(kk>0) { }

kk--;

HX-5509A 开发板使用手册

deminaddr = (int *)CESECT2; *deminaddr = 0x00fd; *deminaddr = 0x0040; deminaddr = (int *)CESECT2; *deminaddr = 0x00ff;

deminaddr = (int *)CESECT3;

deminaddr = (int *)CESECT2; *deminaddr = 0x00fd; *deminaddr = 0x00c0; deminaddr = (int *)CESECT2; *deminaddr = 0x00ff;

deminaddr = (int *)CESECT3;

deminaddr = (int *)CESECT3;

哈尔滨工业大学(威海)课程设计

}

*deminaddr = 0x00c0; deminaddr = (int *)CESECT2; *deminaddr = 0x00ff;

Uint16 Flash_Erase_all() //AM29LV800芯片擦除 {

Flash_CS(); }

42

deminaddr = (int *)CESECT1; addbias = 0x0555;

*(deminaddr+addbias) = 0x00aa; addbias = 0x02aa;

*(deminaddr+addbias) = 0x0055; addbias = 0x0555;

*(deminaddr+addbias) = 0x0080; addbias = 0x0555;

*(deminaddr+addbias) = 0x00aa; addbias = 0x02aa;

*(deminaddr+addbias) = 0x0055; addbias = 0x0555;

*(deminaddr+addbias) = 0x0010; delay(100);

fstatus = *(deminaddr+addbias); fstatus &= 0x0040;

fstatus2 = *(deminaddr+addbias); if((fstatus&fstatus2)!=0) { } else { }

while(fstatus!=0x00ff)

ddelay(500);

fstatus = *(deminaddr+addbias); fstatus &= 0x00ff;

{

Flash_disCS(); return 0;

}

Flash_disCS(); return 1;

哈尔滨工业大学(威海)课程设计

Uint16 Flash_Erase_sector() //AM29LV800分段擦除 { }

void Flash_Write_init() //AM29LV800烧写初始化 { }

Uint16 Flash_Write(Uint16 waddr, Uint16 wdata) //AM29LV800烧写 {

*(fwaddr+waddr) = 0x00a0; }

void Flash_Write_end() //AM29LV800烧写结束 { }

Uint16 Flash_Read(Uint16 raddr) //AM29LV800读 {

Uint16 frtemp;

43

return 1;

Flash_CS();

deminaddr = (int *)CESECT1; addbias = 0x0555;

*(deminaddr+addbias) = 0x00aa; addbias = 0x02aa;

*(deminaddr+addbias) = 0x0055; addbias = 0x0555;

*(deminaddr+addbias) = 0x0020;

*(fwaddr+waddr) = wdata; delay(10000);

fstatus = *(fwaddr+waddr); { }

return 1;

delay(10000);

fstatus = *(fwaddr+waddr);

while(fstatus!=wdata)

deminaddr = (int *)CESECT1; *deminaddr = 0x0090; *deminaddr = 0x0000; Flash_disCS();

哈尔滨工业大学(威海)课程设计

}

frtemp = *(fraddr+raddr); return frtemp;

main() {

/*初始化CSL库*/ CSL_init();

/*EMIF为全EMIF接口*/ CHIP_RSET(XBSR,0x0a01);

/*设置系统的运行速度为144MHz*/ PLL_config(&myConfig);

/*初始化DSP的外部SDRAM*/ EMIF_config(&emiffig);

Flash_Reset();

//以下程序为读AM29LV800

for(datacount=0;datacount<1000;datacount++) { }

Flash_CS(); fraddr = fwaddr;

for(datacount=0;datacount<1000;datacount++)

44

//Flash_Erase_all运行大约为14s以上,为节约时间注释掉,用户可自行根success = Flash_Erase_all();

据需要取消注释

//以下程序为烧写AM29LV800 Flash_Write_init();

fwaddr = (int *)CESECT1; //地址首先指向5509的CE1空间(AM29LV800所fwaddr += 0x10000; //指向AM29LV800的1扇区 for(datacount=0;datacount<1000;datacount++) { }

Flash_Write_end();

success = Flash_Write(datacount, datacount);

在)

databuffer[datacount]=0;

哈尔滨工业大学(威海)课程设计

{ } Flash_disCS(); //运行到此处,在view--memory里查看databuffer开始地址的数据,看是否databuffer[datacount] = Flash_Read(datacount); 所写即所读 while(1); } 九、 数字信号处理——FIR&IIR滤波器实验

(一)FIR滤波器

FIR即有限脉冲响应滤波器, 具有线性相位及非递归结构。 线性相位是指不同频率分量的信号经过fir滤波器后时间差不变。 图象处理以及数据传输都要求信道具有线性相位特性

FIR滤波器的单位抽样响应是有限长的,因而滤波器性能稳定。但是同样幅度指标,阶数比IIR的高5~10倍,制造成本高。

(二)IIR滤波器

IIR即无限脉冲响应滤波器, 相位非线性,具有输出对输入的反馈,因而可用比 FIR滤波器较少的阶数来满足指标的要求,这样一来所用的存储单元少,运算次数少,较为经济。

设计同样参数的滤波器,FIR比IIR需要更多的参数。这也就说明,要增加DSP的计算量,DSP需要更多的计算时间。FIR对DSP的实时性有影响。

(三)FIR与IIR的比较 IIR滤波器主要是设计规范化的、频率特性为分段常数的标准低通、高通、带通、带阻、全通滤波器;而FIR滤波器则要灵活得多,可以设计出理想正交变换器、理想微分器、线性调频器等各种网络,适应性较广。

(四) 运行时库的添加

45

哈尔滨工业大学(威海)课程设计

1.Include 中直接路径中添加 2.CMD文件中命令添加 3.Build Options->

(五) CCS的run与animate的区别 1.Run Animate

Linker->

include libraries->” rts55x.lib”

2.如果没有断点的话,这两个没区别.

如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考Help->tutorial里面的“Code Composer Studio?

IDE”->“ developing a simple program\Animating the Program and Graphs \这一个教程

(六)源码及注释

#include \#include \#include \#include

#define FIRNUMBER 25 #define SIGNAL1F 1000 #define SIGNAL2F 4500 #define SAMPLEF 10000 #define PI 3.1415926

float InputWave(); float FIR();

46

哈尔滨工业大学(威海)课程设计

float fHn[FIRNUMBER]={ 0.0,0.0,0.001,-0.002,-0.002,0.01,-0.009, -0.018,0.049,-0.02,0.11,0.28,0.64,0.28, -0.11,-0.02,0.049,-0.018,-0.009,0.01, -0.002,-0.002,0.001,0.0,0.0 }; float fXn[FIRNUMBER]={ 0.0 }; float fInput,fOutput; float fSignal1,fSignal2;

float fStepSignal1,fStepSignal2; float f2PI; int i;

float fIn[256],fOut[256]; int nIn,nOut; main() {

nIn=0; nOut=0; f2PI=2*PI; fSignal1=0.0; fSignal2=PI*0.1; fStepSignal1=2*PI/30; fStepSignal2=2*PI*1.4; while ( 1 ) { } }

float InputWave() {

for ( i=FIRNUMBER-1;i>0;i-- )

fXn[i]=fXn[i-1];

fXn[0]=sin((double)fSignal1)+cos((double)fSignal2)/6.0; fSignal1+=fStepSignal1;

47

fInput=InputWave(); fIn[nIn]=fInput; nIn++; nIn%=256; fOutput=FIR(); fOut[nOut]=fOutput; nOut++; { }

nOut=0;

/* break point */

if ( nOut>=256 )

哈尔滨工业大学(威海)课程设计

if ( fSignal1>=f2PI ) fSignal2+=fStepSignal2; if ( fSignal2>=f2PI ) return(fXn[0]); }

float FIR() {

float fSum; fSum=0;

fSignal1-=f2PI; fSignal2-=f2PI;

for ( i=0;i

return(fSum); }

fSum+=(fXn[i]*fHn[i]);

(七)实验结果

输入实时信号FIR滤波后的结果:

输入实时信号IIR滤波后的结果:

48

哈尔滨工业大学(威海)课程设计

十、 UART通信实验——McBSP的使用与配置 (一) McBSP简介

5509A有3个多通道缓冲串口McBSP,有7个管脚分布在DSP的外围针脚上,有1个发送端,1个接收端,还有接收和发送的时钟信号,帧同步信号,各一对。McBSP内部有一个采样速率发生器,可以产生时钟和帧同步信号,这两个信号可用于发送和接收的时钟和帧同步信号。

McBSP有以下几种工作模式:多通道缓冲模式 ;SPI模式 ;数字回环模式 ;GPIO模式 ;省电模式 。

(二) 1引脚

2时钟及帧同步信号产生 3接收发送部分 4多通道选择 5 CPU中断信号 6 DMA同步信号

49

McBSP的构成

哈尔滨工业大学(威海)课程设计

·McBSP引脚说明

·McBSP的缓冲

(一)

UART通信

UART通信有两种方式:(1)McBSP in Serial Port Mode,(2)McBSP in GPIO Mode。

50