DSP2812+FPGA常见问题汇总之三:软件问题

问:我测试你们的程序的时候,go main 进不去主函数,进入的是一段汇编。是怎么回事?
答:程序如果要进行设断点,观察变量等操作,要先调入project文件,然后再调入out文件。如果是可以直接执行能看到结果的,就直接调入out文件,run就可以。
问:CY68013的固件程序怎么修改?
答:在把QQ2812都研究清楚了,有精力有兴趣自己可以买一本EZ-USB的书好好看看。在此之前,请不要随便更改固件代码,因为一旦出错,可能带来不必要的麻烦。

固件代码是通过USBControlPanel,使用USB接口进行下载的。

2812的主频是最大150M,我如果想设为100M是在那里设置?
答:打开工程,在Source文件夹下,打开DSP28_SysCtro.c文件,找到如下语句,修改即可。

// Initalize PLL
SysCtrlRegs.PLLCR = 0x02;///
锁相环产生的时钟频率定标,这里配置为30M

问:为什么我的程序在SRAM中正常,烧入Flash后不对?

答:1、请先确认你编译的时候使用了flash.cmd,推荐使用我们提供的flash.cmd,如果自己更改了这个文件,请先确认cmd文件的正确性;

2、编译的时候,如果选择release模式,请检查一下build option,把其中的opt level改为none,即取消编译优化选项,很多语句在优化的时候可能会产生错误的优化结果。
或者选择debug模式编译,烧写正确后再改为release模式,通过对比两种模式的编译选项也能看出其中的区别。

3
、程序在flash中运行会比在ram中运行大概慢20%,因此对于一些时序敏感的外设,比如usb总线,就有可能需要调整时序,否则就会有问题。

问:数码管LED显示的时候发送的数据是怎么规定和产生的?

答:其实如果自己看程序和原理图自己就可以知道是怎么产生的。

数码管数据如下:
Uint16 SpiCode[]={0x7E7E,0x2929,0x2c2c,0x6666,0xa4a4,0xa0a0,0x3e3e,0x2020,0x2424,0x2222,0xe0e0,0xb1b1,0x6868,0xa1a1,0xa3a3,0xffff,0xdfdf};
数码管的笔画对应关系如下:
    6
3    7
    4
2    0
    1    5

就是说07分别对应笔画的ah,在原理图看就是分别连接的Q0Q7
这个数码管的型号是LG3611BH,是共阳级的,也就是说某个笔画为0的时候,这个笔画被点亮。

我们以 "1",0x7E7E为例说明
7E
的二进制是01111110,对应点亮的就是Q0Q7,也就是“1”了。
其他的自己拿笔画一下就清楚了。

问:FPGA中的各个外设地址是如何定义和产生的?
答:2812开发板使用XZCS0ANDCS1来片选CPLDXINTF ZONE1),这里是当CS1=1的时候对外设译码,因此外设起始地址为0x4000

DSP引入FPGA进行逻辑粘合的地址线有6根,分别为:A8~A13FPGA使用这6根地址线产生不同外设的地址。
LED灯地址为例说明,LED灯的地址为0x4100
FPGA代码,找到如下这段
`define LedAdd  6'h01
这个就是说A13~A8 这个地址为01的时候,选中LED灯。.
对照如下:

A13 A12 A11 A10 A9 A8 A7 A6  A5 A4  A3  A2 A1 A0
   0   0   0   0   0   1  x   x   x   x   x   x   x   x
那么A14A0的数据即为: 0x4100
 

问:关于可屏蔽中断的问题板上的那几路中断管脚分别对应的是DSP的那几个管脚?原理图上我看不出来?能不能告诉我那几路可屏蔽中断分别对应的是那几个中断向量?比如您那个可以用按键进行试验的对应的是INT1,其他的呢?
答:EXINT1~5中断从cpld输入,输出int1接到了dspxint1,看原理图可以看到。

详细可参看Ex09_Ext_Int实验。
//
实验目的:通过实验了解DSP内部的外部中断控制寄存器,知道怎样去实现外中断.

//硬件电路描述:要知道F2812有三个独立的外部可屏蔽中断XINT1,XINT2,XINT13
//            
一个不可屏蔽中断XNMI(XINT13共用一个脚),我们的电路用CPLD
//            
扩展出了5个可屏蔽中断EXINT1,EXINT2,EXINT3,EXINT4,EXINT5

//             2
个不可屏蔽中断NMI1NMI2.
//          1
、外部扩展的5个可屏蔽中断通过CPLD之后,CPLD输出一INT1DSP

//            
外中断一XINT1连接在一起;
//          2
、外部扩展的2个不可屏蔽中断通过CPLD之后,CPLD输出一NMI1DSP
//            
XNMI连接到了一起

//          3
DSPXINT2中断分配给了USB68013/INT 68013。具体可查看原理图

//实验效果:我们这里的实验只用了EXINT5,就是通过按键S3产生一中断,看在程
//         
序运行时能否跳入中断,在指定位置设置的断点停下。

ex15都是
接在xint1,就是说
任何一个产生中断,都是在xint1中断,对应的向量是INTx4

问:用其中的两路产生中断执行不同的代码?
答:可以变通啊,你把代码看懂就清楚了。
比如在中断处理程序中,根据temp,不同中断会返回不同的值,可以使用一个全局变量,在主程序判断这个值,执行不同的代码。

interrupt void ExtIntISR(void)
{
Uint16 Temp; ///
用此临时变量读取外部可屏蔽中断,对应关系为:

              /// bit7  bit6   bit5   bit4   bit3   bit2   bit1   bit0
              ///                    Eint5  Eint4  Eint3  Eint2  Eint1
PieCtrl.PIEACK.all = 0xFFFF;///
响应中断,写10,允许INT1~INT12CPU发起中断
PieCtrl.PIEIFR1.bit.INTx4 = 0;///
相应的中断标志寄存器清0
ERTM;
Temp = *INT1Add;
Temp |= 0xffe0; ///////////
设断点


Temp = Temp;
//
    }
:如何将数组存放在指定的数据空间内()
答:在CCS编程中,如果我们不指定变量的存放位置,编译器会自动的给变量分配一个位置,但是如果有的时候需要把变量放在一个特定的空间内,我们应该如何操作呢,CCS提供了如下的两个指令:

#pragma CODE_SECTION
#pragma DATA_SECTION
其中data_section是针对数据空间的,code_section是针对程序空间的,具体的使用办法是

#pragma CODE_SECTION(fn, ”my_sect”)
int fn(int x)
{
return c;
}

#pragma DATA_SECTION(bufferB, ”my_sect”)
char bufferA[512];
char bufferB[512];

.cmd文件中建立对应的section就可以使用了。eg:

MEMORY
{

       PAGE 1: spacename  : origin = 0x....,  length 0x..
}

SECTIONS
{
       .my_sect    : {}  >spacename PAGE 1

}

顶顶很有用的东西,对于dsp来说!
因为这个#pragma DATA_SECTION(,"")这个语句配合CMD文件可以将特定的数据放在特定的地方。举个例子:

对数据分析时比如讲采样点数2000个放在一些寄存器中导出出分析可能就需要开辟一段特定的内存来分析。可以用以上方法。