DSP学习心得笔记
---------------- 白建成
.baijc.icekoor
引言:学习
DSP的时间有两个多月了,收获很多新知识,我们要每天都有进步才行,以下内容没有特别的顺序,跟具自己的学习情况写的,如果有不对的地方希望指出来,如果有不懂得也可以问我,大家相互交流很重要,我的一个邮箱:
baijc@163.com欢迎联系!
建立新工程过程中:
问题
1:
"GPIO_Study.c", line 61: fatal error: could not open source file "DSP280x_Device.h"
1 fatal error detected in the compilation of "GPIO_Study.c".
解决方法:
因为
project à
build optionsà
compilerà
preprocessor中,要包含的头文件的地址没有加进去,你可以找到头文件的地址,然后加进去。
问题
2:
undefined first referenced
symbol in file
--------- ----------------
_c_int00 D:DSP study est3DebugDSP280x_CodeStartBranch.obj
FS$$MPY D:DSP study est3DebugDSP280x_CpuTimers.obj
FS$$TOL D:DSP study est3DebugDSP280x_CpuTimers.obj
>> error: symbol referencing errors - './Debug/test3.out' not built
或者下面的问题:
undefined first referenced
symbol in file
--------- ----------------
_c_int00 D:DSP studyGPIO_StudyDebugDSP280x_CodeStartBranch.obj
>> error: symbol referencing errors - './Debug/GPIO_Study.out' not built
解决办法都是下面:
这个问题是因为没有加在库文件,请在
project à
build optionsà
linkerà
libraries中加入
rts2800.lib。
问题
3:
>> warning: creating .stack section with default size of 400 (hex) words.
Use
-stack option to change the default size.
>> error: can't allocate .stack, size 00000400 (page 1) in RAMM1 (avail:
00000380)
>> error: errors in input - ./Debug/GPIO_Study.out not built
解决办法:
这个问题是关于堆栈存储大小的问题,他是说,创建堆栈段使用与设置
400个字,并建议在
“堆栈操作
”中改变这。
个与设置。这时,需要进行如下修改就可通过:
projectà
build optionsà
Linkerà
basic,在
Stack
Size(-stack):填入
800或者其他小于
1024的数值
调试程序:在编译完成之后,要来下载程序并进行功能调试。FileLoad Program,在工程文件夹下面的Debug文件夹下,选中**.out文件,点击打开,便开始下载程序了。将**.out文件下载到目标板上2812的RAM中。注意,这里是调试,所以将程序下载到RAM。等到最后您要固化程序的时候,就得下载到FLASH了,因为断电之后,RAM里面所有的数据都会消失。(Run和Animate的区别,Run是如果遇到断点的话它就停下来了。而Animate就算遇到断点时先停止DSP内核,刷新窗口,然后接着继续启动运行,常用来连续刷新变量窗口和生成graph图形等)——知识储备。添加断点:加上断点的方法很简单,只要在该行代码前双击就行。双击之后,这行代码前面会出现一个红 {MOD}圆块。另外一种添加断点的方法,就是在刚才的编译工具栏上,点一下那个小手图形的按钮,前提是你要把光标移动到想要设置断点的哪一行上。使用watch window:Watch window的作用是来观察程序运行过程中的各个变量的值。调用watch window的方法是点击菜单栏的"View ","watch window",这时watch window就会显示在CCS下方的信息区域;选中所要观察的变量,然后右键,在右键菜单中选择add to watch window。调试代码观察:我们在调试程序的时候经常想让程序从Main函数开使运行,点DebugGo main。 既能看到源文件中代码的执行情况,又能看到汇编指令的执行情况ViewMixed Source/Asm;关于F2812中用C语言来实现中断的说明1.首先在.cmd中定位系统中断表:MEMORY{PAGE 0 : ......................................PAGE 1 : ......................................PIE_VECT : origin = 0x000D00, length = 0x000100...................................... }SECTIONS{................................... PieVectTable : > PIE_VECT, PAGE = 1.....................................}2.在C中制定该中断的结构体:#pragma DATA_SECTION(PieVectTable,"PieVectTable");struct PIE_VECT_TABLE PieVectTable;(在DSP28_GlobalVariableDefs.C中初始化)3.用一组常数(按照中断向量的顺序)初始化该名字为PIE_VECT_TABLE的表:typedef interrupt void(*PINT)(void);这里有些一问,一下应该为函数名??// Define Vector Table:struct PIE_VECT_TABLE {// Reset is never fetched from this table. // It will always be fetched from 0x3FFFC0 in either// boot ROM or XINTF Zone 7 depending on the state of// the XMP/MC input signal. On the F2810 it is always// fetched from boot ROM. PINT PIE1_RESERVED; PINT PIE2_RESERVED;PINT PIE3_RESERVED;PINT PIE4_RESERVED;PINT PIE5_RESERVED;PINT PIE6_RESERVED;PINT PIE7_RESERVED;PINT PIE8_RESERVED;PINT PIE9_RESERVED;PINT PIE10_RESERVED;PINT PIE11_RESERVED;PINT PIE12_RESERVED;PINT PIE13_RESERVED;// Non-Peripheral Interrupts:PINT XINT13; // XINT13PINT TINT2; // CPU-Timer2PINT DATALOG; // Datalogging interruptPINT RTOSINT; // RTOS interruptPINT EMUINT; // Emulation interruptPINT XNMI; // Non-maskable interruptPINT ILLEGAL; // Illegal operation TRAPPINT USER0; // User Defined trap 0PINT USER1; // User Defined trap 1PINT USER2; // User Defined trap 2PINT USER3; // User Defined trap 3PINT USER4; // User Defined trap 4PINT USER5; // User Defined trap 5PINT USER6; // User Defined trap 6PINT USER7; // User Defined trap 7PINT USER8; // User Defined trap 8PINT USER9; // User Defined trap 9PINT USER10; // User Defined trap 10PINT USER11; // User Defined trap 11// Group 1 PIE Peripheral Vectors:PINT PDPINTA; // EV-APINT PDPINTB; // EV-BPINT rsvd1_3;PINT XINT1; PINT XINT2;PINT ADCINT; // ADCPINT TINT0; // Timer 0PINT WAKEINT; // WD..........................// Group 12 PIE Peripheral Vectors:PINT rsvd12_1;PINT rsvd12_2;PINT rsvd12_3;PINT rsvd12_4;PINT rsvd12_5;PINT rsvd12_6;PINT rsvd12_7;PINT rsvd12_8;};然后在使我们在.cmd文件中定义的表有以上属性:extern struct PIE_VECT_TABLE PieVectTable;(在.h文件中)4.初始化该表(在.c文件中)使之能够为主程序所使用:const struct PIE_VECT_TABLE PieVectTableInit = {PIE_RESERVED, // Reserved spacePIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, PIE_RESERVED, // Non-Peripheral InterruptsINT13_ISR, // XINT13 or CPU-Timer 1INT14_ISR, // CPU-Timer2DATALOG_ISR, // Datalogging interruptRTOSINT_ISR, // RTOS interruptEMUINT_ISR, // Emulation interruptNMI_ISR, // Non-maskable interruptILLEGAL_ISR, // Illegal operation TRAPUSER0_ISR, // User Defined trap 0USER1_ISR, // User Defined trap 1USER2_ISR, // User Defined trap 2USER3_ISR, // User Defined trap 3USER4_ISR, // User Defined trap 4USER5_ISR, // User Defined trap 5USER6_ISR, // User Defined trap 6USER7_ISR, // User Defined trap 7USER8_ISR, // User Defined trap 8USER9_ISR, // User Defined trap 9USER10_ISR, // User Defined trap 10USER11_ISR, // User Defined trap 11// Group 1 PIE VectorsPDPINTA_ISR, // EV-APDPINTB_ISR, // EV-Brsvd_ISR,XINT1_ISR, XINT2_ISR,ADCINT_ISR, // ADCTINT0_ISR, // Timer 0WAKEINT_ISR, // WD..........................// Group 12 E Vectorsrsvd_ISR, rsvd_ISR, rsvd_ISR, rsvd_ISR, rsvd_ISR, rsvd_ISR, rsvd_ISR, rsvd_ISR, };//---------------------------------------------------------------------------// InitPieVectTable: //---------------------------------------------------------------------------// This function initializes the PIE vector table to a known state.// This function must be executed after boot time.//void InitPieVectTable(void){int16 i;Uint32 *Source = (void *) &PieVectTableInit;Uint32 *Dest = (void *) &PieVectTable;EALLOW; for(i=0; i < 128; i++)*Dest++ = *Source++; EDIS;// Enable the PIE Vector TablePieCtrl.PIECRTL.bit.ENPIE = 1; }5.中断服务程序:让以上的数值指向你所要的服务程序,例如:PieVectTable.TINT2 = &ISRTimer2;那么,ISRTimer2也就成了中断服务程序,×××切记:一定要在主程序的开始先声明该程序:interrupt void ISRTimer2(void);..........................然后按照您的需要编制该程序:interrupt void ISRTimer2(void){CpuTimer2.InterruptCount++;}
编程中遇到的问题:
1、 line 257: warning: last line of file ends without a newline;
解决方法:
点击出现的问题条,看光标定位在哪里,然后一点点删除,直到把编程的文字删除,最后把删除的写出来,回车就行了,因为回车的格式要在编辑状态哈哈!
28016的定时器笔记
学过
2812的人会知道,
2812的定时器和
28016的定时器的寄存器很不一样。但是从功能上将差不多。
关于28016定时器的时钟的讨论;
定时器的时钟是由
SYSCLKOUT经过
TBCTL中的
CLKDIV和
HSPCLKDIV进行配置;
和
主要说明,我们应该记得
SYSCLKOUT和
HSPCLK之间还可以分频,但是在这里这个寄存器不影响。
关于28016定时器的时钟同步的讨论;
如果我们想使每个
PWM模块具有同步时钟,我们可以通过软件强制各个模块之间同步,设定步骤如下:
EPwm1Regs.TBCTL.bit.SYNCOSEL = 0 // Pass through
EPwm2Regs.TBCTL.bit.SYNCOSEL = 0; // Pass through
EPwm3Regs.TBCTL.bit.SYNCOSEL = 0; // Pass through
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
EPwm3Regs.TBCTL.bit.SWFSYNC = 1;
以上程序是设定
PWM1/2/3同步,我们由于我们只采用向上计数,所以不需要设定计数方向位。
接下来如果我们想
PWM1与
PWM2输出相位不一样,保持某个相位差,我们可以通过寄存器设定;
EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm2Regs.TBPHS.half.TBPHS = 250;
EPwm3Regs.TBPHS.half.TBPHS = 500;
首先使能,然后赋予值;
关于一些其他的配置如下:
EPwm3Regs.TBPRD = PWM3_TIMER_TBPRD;
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Enable INT on Zero event
EPwm3Regs.ETSEL.bit.INTEN = PWM3_INT_ENABLE; // Enable INT
EPwm3Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 3rd event
关于28016PWM配置的讨论
PWM1的
A/B的独立配置;
除了
counter-compare比较寄存器,
CMPA,
CMPB,主要还是配置控制寄存器
CMPCTL,对于影子寄存器的配置,还有影子寄存器的装载模式。
这里主要讲关于
PWM中
action qualifier的配置;
模式
1:
// Setup shadow register load on ZERO
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = EPWM1_MIN_CMPA; // Set compare A value
EPwm1Regs.CMPB = 500; // Set Compare B value
// Set actions
EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up coun
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, up count
// Interrupt where we will change the Compare Values
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
其中红 {MOD}的为
PWM的输出方式配置,当
PWM1.A在
counter==0时,输出为
0,在
counter==CMPA时,且在向上计数,输出为
1;而
PWM1.B相反。
模式二:
// Set actions
EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR; // Clear PWM2A on Period
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count
EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Clear PWM2B on Period
EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count
其中红 {MOD}的为
PWM的输出方式配置,当
PWM1.A在
counter==period时,输出为
0,在
counter==CMPA时,且在向上计数,输出为
1;而
PWM1.B相同;
模式三:
// Set Actions
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM3A on event B, up count
EPwm3Regs.AQCTLA.bit.CBU = AQ_CLEAR; // Clear PWM3A on event B, up count
其中红 {MOD}的为
PWM的输出方式配置,当
PWM1.A在
counter==CMPA时,输出为
1,在
counter==CMPB时,且在向上计数,输出为
0,也就是计数在
CMPA与
CMPB之间时输出为
1;
模式四:
EPwm3Regs.AQCTLB.bit.ZRO = AQ_TOGGLE; // Toggle EPWM3B on Zero
此模式强制整个周期输出高或者输出地,与
CMPA与
CMPB无关,
关于28016PWM死区时间配置的讨论
主要与死区有关的是三个寄存器:
Dead-Band Generator Control Register (DBCTL);
Dead-Band Generator Rising Edge Delay Register (DBRED);
Dead-Band Generator Rising Edge Delay Register (DBRED) Field Descriptions;
首先清楚延时时间的计算
为:DBRED*TBCLK;
然后弄懂DBCTL就可以了。
注意理解下图:
弄懂
3个控制位什么意思;
OUT_MODE,POLSEL,IN_MODE
注意第二位,这位通常用在输入为同一个通道时,也就是
IN_MODE=0X00/0X03时。
简单看一些
deadband的配置:
EPwm1Regs
.DBCTL
.bit
.OUT_MODE
= DB_FULL_ENABLE;
输出之前,输入上升沿下降沿都被延时;
EPwm1Regs
.DBCTL
.bit
.POLSEL
= DB_ACTV_HI;
没有取反过程;
EPwm1Regs
.DBCTL
.bit
.IN_MODE
= DBA_ALL;
输入全部为A,此为习惯性的配置;
EPwm1Regs
.DBRED
=1000;
EPwm1Regs
.DBFED
=500;
一周解决的为题:
我的
sin()函数能够正常执行,
cos()函数也能正常执行,但是当
sin()计算完再计算
cos(),仿真环境就会进入逻辑错误中断,请问怎么解决,是不是该重装
CCS。
原因:之前一直把程序烧到
RAM里,总是只能执行一个
sin()和
cos()函数,然后
RAM的空间就不够了,由于也不会改
RAM空间的大小,所以就把程序直接下到
flash里面,结果就好了。
遇到CCS和仿真器连不上的问题;
Error connecting to the target:
Error 0x80000240/134
Fatal Error during: Initialization, OCS
Unknown Error
Sequence ID: 0
Error Code: 134
Error Class: 0x80000240
I/O Port = 240
解决办法:
我也试着解决这个问题,重装了一次,结果没有用。想着觉得是USB驱动的问题,然后就在设备管理器中,把USB的驱动删除了,有重新装了一遍,结果没问题了。原因应该是以前用的USB口安装的驱动,又被用于安装其他的驱动,结果以前的USB驱动不能用了
2011.1.19
我在用
dsp中的
cos()与
sin()函数时,对他们的结果做验证,
发现他们有的计算出来的结果,和我用计算器计算出来的结果不一样,还差不少。
解决办法:
首先坚信
CCS的函数计算不会轻易的出错,然后我就去查程序的问题,查不好长时间觉得没问题,就继续看程序运行的结果,结果发现有些计算正确,有些不正确,就在想执行过程中难道有随机性,结果突然想到中断的问题,我是在中断中作了个旋转矢量,通过中断来使它旋转,而直接把中断中的值,拿来在每个
sin,cos中用,所以才出问题的。
结果改动了一点就行了,将中断中的值,在用的地方,重新付给另一个变量,这样就能解决了。因为
sin,cos执行需要时间较长,而普通的赋值却不是。
Flash API Error #65535:
The device is in limp mode, operation failed。以前一直没有问题,不知道怎么突然就这样了。
解决办法:
烧写的插件(网上这么叫)没有装好的原因,我觉得就是仿真器第一次没连接好,拔掉再连接几