小弟最近在试着编写SVPWM程序,奈何TI给的例程有些NB,不太适合我所以我就自己整理了一个头文件和一个源文件。但是编译的时候总是出现这样的错误,如下:
undefined first referenced
symbol in file
--------- ----------------
_SVREG ./SRC/SVPWM.obj
error: unresolved symbols remain
error: errors encountered during linking; "SVPWM_CONTROL.out" not build
我也看了论坛上的解决方法可是仍旧解决不了。所以请教各位大师帮忙。
下面是我的代码首先是头文件
- #ifndef SVPWM_CAL_H_
- #define SVPWM_CAL_H_
- //#include "DSP2833x_Project.h"
- #define PI 3.14159
- struct SVPWM_REG{
- float32 Ta;
- float32 Tb;
- float32 Tc;
- Uint16 N;
- };
- void SVPWM_cal(Uint16 ang);
- void Init_STR(void);
- extern volatile struct SVPWM_REG SVREG;
- #endif
复制代码
然后是源文件
- #include "DSP2833x_Project.h"
- #include "math.h"
- float32 Ua,Ub,X,Y,Z,t1,t2,t0,U1,U2,U3;
- Uint16 A,B,C;
- void Init_STR(void)
- {
- SVREG.Ta = 0;
- SVREG.Tb = 0;
- SVREG.Tc = 0;
- SVREG.N = 0;
- }
- void SVPWM_cal(Uint16 ang)
- {
- Ua=cos(ang/100*PI);
- Ub=sin(ang/100*PI);
- X=0.866*Ub;
- Y=0.433*Ub+0.75*Ua;
- Z=0.433*Ub-0.75*Ua;
- U1=Ub;
- U2=0.866*Ua-Ub;
- U3=-0.866*Ua-Ub;
- if(U1>0)
- A=1;
- else
- A=0;
- if(U2>0)
- B=1;
- else
- B=0;
- if(U3>0)
- C=1;
- else
- C=0;
- SVREG.N=A+2*B+4*C;
- switch(SVREG.N)
- {
- case 1:t1=Z;t2=Y;break;
- case 2:t1=Y;t2=-X;break;
- case 3:t1=-Z;t2=X;break;
- case 4:t1=-X;t2=Z;break;
- case 5:t1=X;t2=Y;break;
- case 6:t1=-Y;t2=-Z;break;
- }
- SVREG.Ta=(1-t1-t2)/4*7500;
- SVREG.Tb=SVREG.Ta+t1/2*7500;
- SVREG.Tc=SVREG.Tb+t2/2*7500;
- }
复制代码
我将头文件包含在了库函数中DSP2833x_DEVICE_H这个头文件中
- #include "DSP2833x_SysCtrl.h" // System Control/Power Modes
- #include "DSP2833x_XIntrupt.h" // External Interrupts
- #include "DSP2833x_Xintf.h" // XINTF External Interface
- [b]#include "SVPWM.H"
- #include "Config_PWM.h"[/b]
- #if DSP28_28335
- #define DSP28_EPWM1 1
复制代码
最后是主程序
- #include "DSP2833x_Project.h"
- Uint16 i,flag,sector;
- interrupt void epwm1_timer_isr(void);
- interrupt void epwm2_timer_isr(void);
- interrupt void epwm3_timer_isr(void);
- void main(void)
- {
- InitSysCtrl();
- DINT;
- InitPieCtrl();
- IER = 0x0000;
- IFR = 0x0000;
- InitPieVectTable();
-
- EALLOW;
- PieVectTable.EPWM1_INT = &epwm1_timer_isr;
- PieVectTable.EPWM2_INT = &epwm2_timer_isr;
- PieVectTable.EPWM3_INT = &epwm3_timer_isr;
- EDIS;
-
- EALLOW;
- SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
- EDIS;
-
-
-
- InitEPWMALL();
-
-
- EALLOW;
- SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
- EDIS;
-
- IER |= M_INT3;
-
- PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
- PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
- PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
- EINT;
- ERTM;
-
-
- Init_STR();
-
- for(;;)
- {
- if(flag==1)
- {
- flag=0;
- i++;
- if(i>200)
- i=0;
- SVPWM_cal(i);
- sector = SVREG.N;
- }
- else
- asm(" NOP");
- }
- }
- interrupt void epwm1_timer_isr(void)
- {
- flag=1;
- switch(sector)
- {
- case 1:EPwm1Regs.CMPA.half.CMPA =SVREG.Tb ;
- EPwm1Regs.CMPB =SVREG.Tb;
- break;
-
- case 2:EPwm1Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm1Regs.CMPB =SVREG.Ta;
- break;
-
- case 3:EPwm1Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm1Regs.CMPB = SVREG.Ta;
- break;
-
- case 4:EPwm1Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm1Regs.CMPB = SVREG.Tc;
- break;
-
- case 5:EPwm1Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm1Regs.CMPB =SVREG.Tc;
- break;
-
- case 6:EPwm1Regs.CMPA.half.CMPA = SVREG.Tb;
- EPwm1Regs.CMPB =SVREG.Tb;
- break;
- }
- EPwm1Regs.ETCLR.bit.INT = 1;
- PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
- }
- interrupt void epwm2_timer_isr(void)
- {
- switch(sector)
- {
- case 1:EPwm2Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm2Regs.CMPB = SVREG.Ta;
- break;
- case 2:EPwm2Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm2Regs.CMPB =SVREG.Tc;
- break;
- case 3:EPwm2Regs.CMPA.half.CMPA = SVREG.Tb;
- EPwm2Regs.CMPB = SVREG.Tb;
- break;
-
- case 4:EPwm2Regs.CMPA.half.CMPA = SVREG.Tb;
- EPwm2Regs.CMPB = SVREG.Tb;
- break;
-
- case 5:EPwm2Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm2Regs.CMPB = SVREG.Ta;
- break;
-
- case 6:EPwm2Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm2Regs.CMPB =SVREG.Tc;
- break;
- }
-
- EPwm2Regs.ETCLR.bit.INT = 1;
- PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
- }
- interrupt void epwm3_timer_isr(void)
- {
- switch(sector)
- {
- case 1:EPwm3Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm3Regs.CMPB = SVREG.Tc;
- break;
- case 2:EPwm3Regs.CMPA.half.CMPA = SVREG.Tb;
- EPwm3Regs.CMPB = SVREG.Tb;
- break;
- case 3:EPwm3Regs.CMPA.half.CMPA = SVREG.Tc;
- EPwm3Regs.CMPB = SVREG.Tc;
- break;
-
- case 4:EPwm3Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm3Regs.CMPB = SVREG.Ta;
- break;
-
- case 5:EPwm3Regs.CMPA.half.CMPA = SVREG.Tb;
- EPwm3Regs.CMPB = SVREG.Tb;
- break;
-
- case 6:EPwm3Regs.CMPA.half.CMPA = SVREG.Ta;
- EPwm3Regs.CMPB = SVREG.Ta;
- break;
- }
-
-
- EPwm3Regs.ETCLR.bit.INT = 1;
- PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
- }
复制代码
最后还有关于配置EPWM模块的C文件和头文件,我就不粘了属于常规配置。
最后重申我的问题,就是编译时出现undefined first referenced
symbol in file
--------- ----------------
_SVREG ./SRC/SVPWM.obj
error: unresolved symbols remain
error: errors encountered during linking; "SVPWM_CONTROL.out" not built
导致编译不过。小弟急求!
1.首先这个问题是出现在我定义的结构体上,最早学习51,C语言编程的时候,大家在自己编写的头文件中定义所需要结构体变量,然后在主程序中调用这个头文件,并且使用extern指令声明一下这个结构体就可以使用了,编译软件会自动给结构体分配内存空间。虽然原理是一样的,但是在DSP中,我发现TI自己的结构体的使用略有不同,既然学习了DSP就应当用TI的规范。
2.不同之处在三个地方,如下:
第一:
- struct SVPWM_REG{
- float32 Ta;
- float32 Tb;
- float32 Tc;
- Uint16 N;
- };
- extern volatile struct SVPWM_REG SVREG;
复制代码根据TI的头文件,我写了这样的一个结构体。里面是四个元素,同时它又定义了这样的一个结构体类型SVREG。但是这个结构体类型却使用了extern,也就是说真正定义这个结构体类型在别的文件中,这里只是单纯的声明了一下,这样对应的C文件就可以使用。
第二:当写完这样一个头文件后,就需要到在DSP28335x_GlobalVaribaleDefs.c这个文件中定义我们之前所声明的结构体类型,并且给我们定义的结构体并且为分配的数据段起名。
。
- #ifdef __cplusplus
- #pragma DATA_SECTION("SVREGFile")
- #else
- #pragma DATA_SECTION(SVREG,"SVREGFile");
- #endif
- volatile struct SVPWM_REG SVREG;
复制代码这里#pragma DATA_SECTION(函数名或全局变量名,"用户自定义在数据空间的段名"),注意这里是全局变量,这样刚才的extern也就能说的通了,所以我们才可以在不声明的情况下直接在主函数中直接使用我们的结构体。
第三 当我们把数据段名起好之后就要在内存空间中分配我们所需要的存储的地址了,这里就用到了DSP2833x_Headers_nonBIOS.cmd这个文件,我们需要在里面分配我们结构体的地址空间,首先是在SECTIONS里
- ScibRegsFile : > SCIB, PAGE = 1
- ScicRegsFile : > SCIC, PAGE = 1
- I2caRegsFile : > I2CA, PAGE = 1
- /*user use struct*/
- SVREGFile : > SVPWMREG, PAGE = 1
- /*** Code Security Module Register Structures ***/
- CsmPwlFile : > CSM_PWL, PAGE = 1
复制代码将我们刚才起得空间段名与起始地址名联系起来(这里我理解可能不到位,请大家海涵,不吝赐教)。然后在MEMORY,PAGE1中写入我们的起始地址和长度。
-
- I2CA : origin = 0x007900, length = 0x000040 /* I2C-A registers */
-
- SVPWMREG : origin = 0x007980, length = 0x000010 /*USER' struct define*/
-
- CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* Part of FLASHA. CSM password locations. */
复制代码这里我的起始地址为0X007980,总共16位。够我定义的结构体用了。
这里有几点说明,第一我的C语言功底不是很扎实,不过现在越学就越觉得为啥从业多年的高手们也只敢说会C语言而不是精通C语言,应聘的人只敢说熟悉,了解C语言,其中千变万化。大家有兴趣可以看看TI给的SVPWM的例子,那真是高手编的,第二,关于DSP的CMD文件,我仍旧在学习中,所以有些不确切之处还望大家不吝赐教,帮帮小弟。第三,我只是解决了这个问题,CCS4.2的编译通过,但是我的SVPWM程序并未调通,后续有问题,我继续和大家讨论。
能用,但是我觉得既然懂原理了 就应该自己是去编一下。毕竟对于这样的程序模块以后使用要知道怎么改。TI给的历程,编写的很好,但是用的是Q格式。但是我用的28335,个人觉得为什么不可以直接使用浮点运算,所以就尝试一下。在并未使用指针的情况下,编写的程序也可以在100US内计算完成,当然比TI给的例子要慢了接近三分之一。
一周热门 更多>