课程设计
报 告
日 期: 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
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
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
#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
(三)
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
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
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 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 #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