关于自己加头文件和源文件编译不通过问题。

2019-07-21 20:30发布

     小弟最近在试着编写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
我也看了论坛上的解决方法可是仍旧解决不了。所以请教各位大师帮忙。
下面是我的代码首先是头文件
  1. #ifndef SVPWM_CAL_H_
  2. #define SVPWM_CAL_H_
  3. //#include "DSP2833x_Project.h"

  4. #define PI 3.14159

  5. struct SVPWM_REG{
  6.                                         float32 Ta;
  7.                                     float32 Tb;
  8.                                     float32 Tc;
  9.                                     Uint16  N;
  10.               };         
  11. void SVPWM_cal(Uint16 ang);
  12. void Init_STR(void);
  13. extern volatile struct SVPWM_REG SVREG;
  14. #endif
复制代码
然后是源文件
  1. #include "DSP2833x_Project.h"
  2. #include "math.h"

  3. float32 Ua,Ub,X,Y,Z,t1,t2,t0,U1,U2,U3;
  4. Uint16 A,B,C;

  5. void Init_STR(void)
  6. {       
  7.         SVREG.Ta = 0;
  8.         SVREG.Tb = 0;
  9.         SVREG.Tc = 0;
  10.         SVREG.N = 0;

  11. }

  12. void SVPWM_cal(Uint16 ang)
  13. {
  14.     Ua=cos(ang/100*PI);
  15.     Ub=sin(ang/100*PI);
  16.     X=0.866*Ub;
  17.     Y=0.433*Ub+0.75*Ua;
  18.     Z=0.433*Ub-0.75*Ua;
  19.     U1=Ub;
  20.     U2=0.866*Ua-Ub;
  21.     U3=-0.866*Ua-Ub;
  22.     if(U1>0)
  23.     A=1;
  24.     else
  25.     A=0;
  26.     if(U2>0)
  27.     B=1;
  28.     else
  29.     B=0;
  30.     if(U3>0)
  31.     C=1;
  32.     else
  33.     C=0;
  34.     SVREG.N=A+2*B+4*C;
  35.     switch(SVREG.N)
  36.     {
  37.             case 1:t1=Z;t2=Y;break;
  38.         case 2:t1=Y;t2=-X;break;
  39.         case 3:t1=-Z;t2=X;break;
  40.         case 4:t1=-X;t2=Z;break;
  41.         case 5:t1=X;t2=Y;break;
  42.         case 6:t1=-Y;t2=-Z;break;
  43.     }
  44.     SVREG.Ta=(1-t1-t2)/4*7500;
  45.     SVREG.Tb=SVREG.Ta+t1/2*7500;
  46.     SVREG.Tc=SVREG.Tb+t2/2*7500;
  47. }
复制代码
我将头文件包含在了库函数中DSP2833x_DEVICE_H这个头文件中
  1. #include "DSP2833x_SysCtrl.h"            // System Control/Power Modes
  2. #include "DSP2833x_XIntrupt.h"           // External Interrupts
  3. #include "DSP2833x_Xintf.h"              // XINTF External Interface

  4. [b]#include "SVPWM.H"
  5. #include "Config_PWM.h"[/b]

  6. #if DSP28_28335
  7. #define DSP28_EPWM1  1
复制代码


最后是主程序
  1. #include "DSP2833x_Project.h"

  2. Uint16 i,flag,sector;


  3. interrupt void epwm1_timer_isr(void);
  4. interrupt void epwm2_timer_isr(void);
  5. interrupt void epwm3_timer_isr(void);


  6. void main(void)
  7. {
  8.    InitSysCtrl();

  9.    DINT;
  10.    InitPieCtrl();
  11.    IER = 0x0000;
  12.    IFR = 0x0000;
  13.    InitPieVectTable();

  14.    EALLOW;
  15.    PieVectTable.EPWM1_INT = &epwm1_timer_isr;
  16.    PieVectTable.EPWM2_INT = &epwm2_timer_isr;
  17.    PieVectTable.EPWM3_INT = &epwm3_timer_isr;
  18.    EDIS;   
  19.    
  20.    EALLOW;
  21.    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;         
  22.    EDIS;
  23.    
  24.    
  25.    
  26.    InitEPWMALL();
  27.    
  28.    
  29.    EALLOW;
  30.    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
  31.    EDIS;

  32.    IER |= M_INT3;
  33.    
  34.    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
  35.    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
  36.    PieCtrlRegs.PIEIER3.bit.INTx3 = 1;

  37.    EINT;   
  38.    ERTM;   
  39.    
  40.    
  41.    Init_STR();
  42.    
  43.    for(;;)
  44.    {
  45.                 if(flag==1)
  46.                 {
  47.                         flag=0;
  48.                         i++;
  49.                         if(i>200)
  50.                         i=0;
  51.                         SVPWM_cal(i);
  52.                         sector = SVREG.N;
  53.                 }          
  54.               else
  55.        asm("   NOP");
  56.     }
  57. }



  58. interrupt void epwm1_timer_isr(void)
  59. {
  60.          flag=1;
  61.      switch(sector)
  62.     {
  63.             case 1:EPwm1Regs.CMPA.half.CMPA =SVREG.Tb ;
  64.                    EPwm1Regs.CMPB =SVREG.Tb;
  65.                    break;
  66.                    
  67.             case 2:EPwm1Regs.CMPA.half.CMPA = SVREG.Ta;
  68.                    EPwm1Regs.CMPB =SVREG.Ta;
  69.                    break;
  70.         
  71.             case 3:EPwm1Regs.CMPA.half.CMPA = SVREG.Ta;
  72.                    EPwm1Regs.CMPB = SVREG.Ta;
  73.                    break;
  74.            
  75.             case 4:EPwm1Regs.CMPA.half.CMPA = SVREG.Tc;
  76.                    EPwm1Regs.CMPB = SVREG.Tc;
  77.                    break;
  78.            
  79.             case 5:EPwm1Regs.CMPA.half.CMPA = SVREG.Tc;
  80.                    EPwm1Regs.CMPB =SVREG.Tc;
  81.                    break;
  82.            
  83.             case 6:EPwm1Regs.CMPA.half.CMPA = SVREG.Tb;
  84.                    EPwm1Regs.CMPB =SVREG.Tb;
  85.                    break;

  86.     }
  87.     EPwm1Regs.ETCLR.bit.INT = 1;
  88.     PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
  89. }

  90. interrupt void epwm2_timer_isr(void)
  91. {
  92.     switch(sector)
  93.     {
  94.             case 1:EPwm2Regs.CMPA.half.CMPA = SVREG.Ta;
  95.                    EPwm2Regs.CMPB = SVREG.Ta;
  96.                    break;
  97.              case 2:EPwm2Regs.CMPA.half.CMPA = SVREG.Tc;
  98.                    EPwm2Regs.CMPB =SVREG.Tc;
  99.                    break;                  
  100.              case 3:EPwm2Regs.CMPA.half.CMPA = SVREG.Tb;
  101.                    EPwm2Regs.CMPB = SVREG.Tb;
  102.                    break;
  103.            
  104.             case 4:EPwm2Regs.CMPA.half.CMPA = SVREG.Tb;
  105.                    EPwm2Regs.CMPB = SVREG.Tb;
  106.                    break;
  107.            
  108.             case 5:EPwm2Regs.CMPA.half.CMPA = SVREG.Ta;
  109.                    EPwm2Regs.CMPB = SVREG.Ta;
  110.                    break;
  111.            
  112.             case 6:EPwm2Regs.CMPA.half.CMPA = SVREG.Tc;
  113.                    EPwm2Regs.CMPB =SVREG.Tc;
  114.                    break;                  
  115.     }

  116.    
  117.                 EPwm2Regs.ETCLR.bit.INT = 1;
  118.                 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;


  119. }

  120. interrupt void epwm3_timer_isr(void)
  121. {
  122.          switch(sector)
  123.     {
  124.             case 1:EPwm3Regs.CMPA.half.CMPA = SVREG.Tc;
  125.                    EPwm3Regs.CMPB = SVREG.Tc;
  126.                    break;
  127.              case 2:EPwm3Regs.CMPA.half.CMPA = SVREG.Tb;
  128.                    EPwm3Regs.CMPB = SVREG.Tb;
  129.                    break;                  
  130.              case 3:EPwm3Regs.CMPA.half.CMPA = SVREG.Tc;
  131.                    EPwm3Regs.CMPB = SVREG.Tc;
  132.                    break;
  133.            
  134.             case 4:EPwm3Regs.CMPA.half.CMPA = SVREG.Ta;
  135.                    EPwm3Regs.CMPB = SVREG.Ta;
  136.                    break;
  137.            
  138.             case 5:EPwm3Regs.CMPA.half.CMPA = SVREG.Tb;
  139.                    EPwm3Regs.CMPB = SVREG.Tb;
  140.                    break;
  141.            
  142.             case 6:EPwm3Regs.CMPA.half.CMPA = SVREG.Ta;
  143.                    EPwm3Regs.CMPB = SVREG.Ta;
  144.                    break;                  
  145.     }
  146.    
  147.    
  148. EPwm3Regs.ETCLR.bit.INT = 1;
  149. PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
  150. }
复制代码

最后还有关于配置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
导致编译不过
。小弟急求!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
19条回答
wkwangke123
2019-07-23 01:40
我在论坛上搜索了一下类似于我这样的问题,发现这个问题是属于新手的通病。原先用STM8和32的时候很少关注芯片的内存分配问题,但是到28335的时候发现很多问题其实都和CMD文件有关。好了废话不多说了,和大家分享一下如何解决这样的问题吧。
1.首先这个问题是出现在我定义的结构体上,最早学习51,C语言编程的时候,大家在自己编写的头文件中定义所需要结构体变量,然后在主程序中调用这个头文件,并且使用extern指令声明一下这个结构体就可以使用了,编译软件会自动给结构体分配内存空间。虽然原理是一样的,但是在DSP中,我发现TI自己的结构体的使用略有不同,既然学习了DSP就应当用TI的规范。
2.不同之处在三个地方,如下:
第一:

  1. struct SVPWM_REG{
  2.                                         float32 Ta;
  3.                                     float32 Tb;
  4.                                     float32 Tc;
  5.                                     Uint16  N;
  6.               };
  7. extern volatile struct SVPWM_REG SVREG;
复制代码
根据TI的头文件,我写了这样的一个结构体。里面是四个元素,同时它又定义了这样的一个结构体类型SVREG。但是这个结构体类型却使用了extern,也就是说真正定义这个结构体类型在别的文件中,这里只是单纯的声明了一下,这样对应的C文件就可以使用。
第二:当写完这样一个头文件后,就需要到在DSP28335x_GlobalVaribaleDefs.c这个文件中定义我们之前所声明的结构体类型,并且给我们定义的结构体并且为分配的数据段起名。
  1. #ifdef __cplusplus
  2. #pragma DATA_SECTION("SVREGFile")
  3. #else
  4. #pragma DATA_SECTION(SVREG,"SVREGFile");
  5. #endif
  6. volatile struct SVPWM_REG SVREG;
复制代码
这里#pragma DATA_SECTION(函数名或全局变量名,"用户自定义在数据空间的段名"),注意这里是全局变量,这样刚才的extern也就能说的通了,所以我们才可以在不声明的情况下直接在主函数中直接使用我们的结构体。
第三 当我们把数据段名起好之后就要在内存空间中分配我们所需要的存储的地址了,这里就用到了DSP2833x_Headers_nonBIOS.cmd这个文件,我们需要在里面分配我们结构体的地址空间,首先是在SECTIONS里
  1. ScibRegsFile      : > SCIB,        PAGE = 1
  2.    ScicRegsFile      : > SCIC,        PAGE = 1
  3.    I2caRegsFile      : > I2CA,        PAGE = 1
  4.       /*user use struct*/
  5.    SVREGFile         : > SVPWMREG,    PAGE = 1           
  6. /*** Code Security Module Register Structures ***/
  7.    CsmPwlFile        : > CSM_PWL,     PAGE = 1
复制代码
将我们刚才起得空间段名与起始地址名联系起来(这里我理解可能不到位,请大家海涵,不吝赐教)。然后在MEMORY,PAGE1中写入我们的起始地址和长度。
  1.   
  2.    I2CA        : origin = 0x007900, length = 0x000040     /* I2C-A registers */
  3.    
  4.    SVPWMREG    : origin = 0x007980, length = 0x000010     /*USER' struct define*/
  5.      
  6.    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程序并未调通,后续有问题,我继续和大家讨论。

一周热门 更多>