DSP TMS320F2803x、TMS320F2806x CLA开发笔记(代码基于TMS320F28069 详解)- 使用C语言编程CLA

CLA的相关介绍请看上篇 here

CLA使用C语言编程的配置

cmd文件部分

/**********需要定义的变量*************/
CLA_SCRATCHPAD_SIZE = 0x100;
_Cla1Prog_Start = _Cla1funcsRunStart;	//cla 程序的起始地址定义
--undef_sym=__cla_scratchpad_end
--undef_sym=__cla_scratchpad_start
/*********************************/

MEMORY
{
PAGE 0 :   /* Program Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
   RAML0       : origin = 0x008000, length = 0x000800     /* on-chip RAM block L0 */
   //RAML1       : origin = 0x008800, length = 0x000400     /* on-chip RAM block L1 */
   RAML3       : origin = 0x009000, length = 0x001000	  /* on-chip RAM block L3 */
   OTP         : origin = 0x3D7800, length = 0x000400     /* on-chip OTP */

   FLASHH      : origin = 0x3D8000, length = 0x004000     /* on-chip FLASH */
   FLASHG      : origin = 0x3DC000, length = 0x004000     /* on-chip FLASH */
   FLASHF      : origin = 0x3E0000, length = 0x004000     /* on-chip FLASH */
   FLASHE      : origin = 0x3E4000, length = 0x004000     /* on-chip FLASH */   
   FLASHD      : origin = 0x3E8000, length = 0x004000     /* on-chip FLASH */
//   FLASHC      : origin = 0x3EC000, length = 0x004000     /* on-chip FLASH */
   FLASHA_B    : origin = 0x3F0000, length = 0x007F80     /* on-chip FLASH */
   CSM_RSVD    : origin = 0x3F7F80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
   BEGIN       : origin = 0x3F7FF6, length = 0x000002     /* Part of FLASHA.  Used for "boot to Flash" bootloader mode. */
   CSM_PWL_P0  : origin = 0x3F7FF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA */

   FPUTABLES   : origin = 0x3FD590, length = 0x0006A0	 /* FPU Tables in Boot ROM */
   IQTABLES    : origin = 0x3FDC30, length = 0x000B50    /* IQ Math Tables in Boot ROM */
   IQTABLES2   : origin = 0x3FE780, length = 0x00008C    /* IQ Math Tables in Boot ROM */
   IQTABLES3   : origin = 0x3FE80C, length = 0x0000AA	 /* IQ Math Tables in Boot ROM */

   ROM         : origin = 0x3FF3B0, length = 0x000C10     /* Boot ROM */
   RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM  */
   VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM  */

PAGE 1 :   /* Data Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
           /* Registers remain on PAGE1                                                  */

   BOOT_RSVD   : origin = 0x000000, length = 0x000050     /* Part of M0, BOOT rom will use this for stack */
   RAMM0       : origin = 0x000050, length = 0x0003B0     /* on-chip RAM block M0 */
   RAMM1       : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
   RAML1       : origin = 0x008800, length = 0x000400     /* on-chip RAM block L1 */
   RAML2       : origin = 0x008C00, length = 0x000400     /* on-chip RAM block L2 */
   RAML4       : origin = 0x00A000, length = 0x002000     /* on-chip RAM block L4 */
   RAML5       : origin = 0x00C000, length = 0x002000     /* on-chip RAM block L5 */
   RAML6       : origin = 0x00E000, length = 0x002000     /* on-chip RAM block L6 */
   RAML7       : origin = 0x010000, length = 0x002000     /* on-chip RAM block L7 */
   RAML8       : origin = 0x012000, length = 0x001800     /* on-chip RAM block L8 */
   USB_RAM     : origin = 0x040000, length = 0x000800     /* USB RAM		  */
   FLASHC      : origin = 0x3EC000, length = 0x004000     /* on-chip FLASH */

   CLATOCPU_MSGRAM	:origin = 0x001480, length = 0x000080
   CPUTOCLA_MSGRAM	:origin = 0x001500, length = 0x000080
}

/* Allocate sections to memory blocks.
   Note:
         codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code
                   execution when booting to flash
         ramfuncs  user defined section to store functions that will be copied from Flash into RAM
*/


SECTIONS
{

   /* Allocate program areas: */
   .cinit              : > FLASHA_B,   PAGE = 0
   .pinit              : > FLASHA_B,   PAGE = 0
   .text               : > FLASHA_B,   PAGE = 0
   codestart           : > BEGIN,      PAGE = 0
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAML0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         PAGE = 0

   csmpasswds          : > CSM_PWL_P0, PAGE = 0
   csm_rsvd            : > CSM_RSVD,   PAGE = 0

   /* Allocate uninitalized data sections: */
   .stack              : > RAMM0,      PAGE = 1
   .ebss               : > RAML2,    PAGE = 1
   .esysmem            : > RAML2,    PAGE = 1

   /* Initalized sections to go in Flash */
   /* For SDFlash to program these, they must be allocated to page 0 */
   .econst             : > FLASHA_B,   PAGE = 0
   .switch             : > FLASHA_B,   PAGE = 0

   /* Allocate IQ math areas: */
   IQmath              : > FLASHA_B,   PAGE = 0            /* Math Code */
   IQmathTables        : > IQTABLES,   PAGE = 0, TYPE = NOLOAD
   
   /* Allocate FPU math areas: */
   FPUmathTables       : > FPUTABLES,  PAGE = 0, TYPE = NOLOAD
   
   DMARAML5	           : > RAML5,      PAGE = 1
   DMARAML6	           : > RAML6,      PAGE = 1
   DMARAML7	           : > RAML7,      PAGE = 1
   DMARAML8	           : > RAML8,      PAGE = 1   

   Cla1Prog			   : LOAD = FLASHE,
   						 RUN  = RAML3,
   						 LOAD_START(_Cla1funcsLoadStart),
   						 LOAD_END(_Cla1funcsLoadEnd),
   						 RUN_START(_Cla1funcsRunStart),
   						 LOAD_SIZE(_Cla1funcsLoadSize),
   						 PAGE = 0

   	Cla1ToCpuMsgRAM		: > CLATOCPU_MSGRAM,	PAGE = 1
   	CpuToCla1MsgRAM		: > CPUTOCLA_MSGRAM,	PAGE = 1

	/*CLAscratch作用:
	当使用v6.1及以上的编译器时,CLA的代码可以使用C语言,
	由于不是汇编,它需要有类似于多余的区间用于存放局部变量等,
	你可以理解它为暂存器或者C里的堆栈。如果使用汇编写CLA的代码,则可以忽略。
	选择使用在RAML1区中作为CLA的使用内存,需要在C文件配置RAML1映射给CLA。
	*/
   	 CLAscratch       :
                        { *.obj(CLAscratch)
                        . += CLA_SCRATCHPAD_SIZE;
                        *.obj(CLAscratch_end) } > RAML1,  PAGE = 1


  /* Uncomment the section below if calling the IQNexp() or IQexp()
      functions from the IQMath.lib library in order to utilize the
      relevant IQ Math table in Boot ROM (This saves space and Boot ROM
      is 1 wait-state). If this section is not uncommented, IQmathTables2
      will be loaded into other memory (SARAM, Flash, etc.) and will take
      up space, but 0 wait-state is possible.
   */
   /*
   IQmathTables2    : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
   {

              IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)

   }
   */
   /* Uncomment the section below if calling the IQNasin() or IQasin()
      functions from the IQMath.lib library in order to utilize the
      relevant IQ Math table in Boot ROM (This saves space and Boot ROM
      is 1 wait-state). If this section is not uncommented, IQmathTables2
      will be loaded into other memory (SARAM, Flash, etc.) and will take
      up space, but 0 wait-state is possible.
   */
   /*
   IQmathTables3    : > IQTABLES3, PAGE = 0, TYPE = NOLOAD
   {

              IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)

   }
   */

   /* .reset is a standard section used by the compiler.  It contains the */
   /* the address of the start of _c_int00 for C Code.   /*
   /* When using the boot ROM this section and the CPU vector */
   /* table is not needed.  Thus the default type is set here to  */
   /* DSECT  */
   .reset              : > RESET,      PAGE = 0, TYPE = DSECT
   vectors             : > VECTORS,    PAGE = 0, TYPE = DSECT

}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

cmd的重点修改地方如下:
在这里插入图片描述
在这里插入图片描述

CLAShared.h

#ifndef CLA_SHARED_H
#define CLA_SHARED_H

#ifdef __cplusplus
extern "C" {
#endif

// 
// Included Files
//
//  #include "IQmathLib.h"
  #include "DSP28x_Project.h"

//
// Defines
//
  #define DS_CLA_DEBUG    1	//需要要调试时置1
extern Uint16  VoltFilt;	//在main.c中有定义
extern Uint16  GOTO_CLA[3];	//在main.c中有定义

  extern float32 ClaVal;	//在main.c中有定义


//
// The following are symbols defined in the CLA assembly code
// Including them in the shared header file makes them
// .global and the main CPU can make use of them.
//
  extern Uint16 Cla1Prog_Start;	//cla 程序的起始地址
  __interrupt void Cla1Task1();
  __interrupt void Cla1Task2();
  __interrupt void Cla1Task3();
  __interrupt void Cla1Task4();
  __interrupt void Cla1Task5();
  __interrupt void Cla1Task6();
  __interrupt void Cla1Task7();
  __interrupt void Cla1Task8();


#ifdef __cplusplus
}
#endif /* extern "C" */


#endif  // end of CLA_SHARED definition

//
// End of File
//

main.c,里面的ADC模块,ePWM模块请看上一篇介绍。

#include "DSP28x_Project.h"
#include "Usart.h"
#include <stdio.h>
#include "ADC.h"
#include "ePWM.h"

#include "CLAShared.h"
#include <string.h>

/**
 * main.c
 **/


#pragma DATA_SECTION(VoltFilt,   "Cla1ToCpuMsgRAM");
#pragma DATA_SECTION(ClaVal,    "Cla1ToCpuMsgRAM");

 Uint16  VoltFilt;
 
#pragma DATA_SECTION(GOTO_CLA,    "Cla1ToCpuMsgRAM");
Uint16  GOTO_CLA[3];

float32 ClaVal;



extern Uint16 Cla1funcsLoadStart;
extern Uint16 Cla1funcsLoadEnd;
extern Uint16 Cla1funcsRunStart;
extern Uint16 Cla1funcsLoadSize;
void init_cla(void);//cla初始化函数

interrupt void cla1_isr1(void);//cla 任务1完成后在C28x CPU中触发的中断服务函数


int main(void)
{

    InitSysCtrl();

    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    init_cla();
    Usart_Init(9600);	//此函数需要各位自己写

    //adc
    ADC_Init();
    InitAdcConfigAndIO();
#if Interrupt_Allow == 1
    OpenAdcInterrupt_PIE();
#endif

    ePWM_init();
    
    msg="Hello,CLA TEST!\r\n\0";
    UARTa_SendString(msg);

    GetChResult(1,9,5);//5-epwm1a SOCa 触发

    while(1);
}


void init_cla(void)
{
    EALLOW;
    //在PCLKCR3寄存器中使能CLA时钟,一般这句话不用写,因为在InitSysCtrl();函数中就已经配置了所有外设的时钟;
    SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK=1;

    //将CLA的TASK函数绑定到中断向量表上

    Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 -(Uint32)&Cla1Prog_Start);
    Cla1Regs.MVECT8 = (Uint16)((Uint32)&Cla1Task8 -(Uint32)&Cla1Prog_Start);

    //设置每个TASK的触发源,有三种选项,PWM触发、ADC触发以及软件触发
    Cla1Regs.MPISRCSEL1.bit.PERINT1SEL=CLA_INT1_ADCINT1;//ADCINT1触发任务1
    Cla1Regs.MPISRCSEL1.bit.PERINT2SEL=CLA_INT2_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT3SEL=CLA_INT3_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT4SEL=CLA_INT4_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT5SEL=CLA_INT5_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT6SEL=CLA_INT6_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT7SEL=CLA_INT7_NONE;
    Cla1Regs.MPISRCSEL1.bit.PERINT8SEL=CLA_INT8_NONE;

    //将CLA代码拷贝入CLA的代码段,因为CLA的代码需要单独放在一个固定的位置,所以需要执行这一段代码
    memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);

    //如果需要使用到软件触发,那么需要执行Cla1Regs.MCTL.bit.IACKE = 1;
    Cla1Regs.MCTL.bit.IACKE = 1;//使能软件中断
    Cla1Regs.MIER.all = (M_INT1  | M_INT8);//使能2个任务中断

    //将CLA的数据段和程序段都映射到CLA空间
    Cla1Regs.MMEMCFG.bit.PROGE = 1;//把RAML3映射为CLA的程序空间

    Cla1Regs.MMEMCFG.bit.RAM1CPUE=0;//RAML1区,CPU不允许读写
    Cla1Regs.MMEMCFG.bit.RAM1E=1;//RAML1区,CLA允许读写

    // Enable INT 11.1 in the PIE (CLA Task1)
    // Enable INT 11 at the CPU level
    // Enable Global interrupts with INTM
    // Enable Global realtime interrupts with DBGM
    //
    EALLOW;
    PieVectTable.CLA1_INT1 = &cla1_isr1;   //自定义中断函数
    EDIS;
    PieCtrlRegs.PIEIER11.bit.INTx1 = 1;
    IER |= M_INT11;
    EINT;
    ERTM;

    //触发TASK8
    Cla1ForceTask8();


}

interrupt void cla1_isr1(void)
{
    char NUMCHAR_[64];

    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//Must clear ADCINT1 flag since INT1CONT = 0
    PieCtrlRegs.PIEACK.all = 0xFFFF;

	/*串口打印数据*/
    sprintf(NUMCHAR_,"CLA TEST: sample time: %d;cla_val:%f V.\r\n",(Uint16)VoltFilt,ClaVal);
    UARTa_SendString(NUMCHAR_);
    sprintf(NUMCHAR_,"CLA ePWM2 TBPHS: %d.\r\n",EPwm2Regs.TBPHS.half.TBPHS);
    UARTa_SendString(NUMCHAR_);

    sprintf(NUMCHAR_,"CLA info: %c %c %c.\r\n",GOTO_CLA[0],GOTO_CLA[1],GOTO_CLA[2]);
    UARTa_SendString(NUMCHAR_);

}



CLA_Task.cla,在此文件编写CLA的程序,注意保存文件后缀为cla

/*
 * CLA_Task.cla
 *
 *  Created on: 2023年3月6日
 *      Author: chends
 */
#include "DSP28x_Project.h"
#include "CLAShared.h"	//直接引用
//#include XSTRINGIZE(XCONCAT(TEXT,CLAShared.h))	//如果使用此方法,注释上一行。此方法是链接到头文件CLAShared.h,TEXT需要在工程属性里面定义。

__interrupt void
Cla1Task1(void)	//任务1
{
    float phaseVal;

#if DS_CLA_DEBUG ==1
    __mdebugstop();	//调试的断点
#endif
    VoltFilt +=1;	//计数进入Task1的次数

	//计算ADC采样结果
    ClaVal=AdcResult.ADCRESULT0;
    ClaVal +=AdcResult.ADCRESULT1;
    ClaVal +=AdcResult.ADCRESULT2;
    ClaVal +=AdcResult.ADCRESULT3;
    ClaVal +=AdcResult.ADCRESULT4;
    ClaVal +=AdcResult.ADCRESULT5;
    ClaVal +=AdcResult.ADCRESULT6;
    ClaVal +=AdcResult.ADCRESULT7;
    ClaVal +=AdcResult.ADCRESULT8;
    ClaVal +=AdcResult.ADCRESULT9;
    ClaVal +=AdcResult.ADCRESULT10;
    ClaVal +=AdcResult.ADCRESULT11;
    ClaVal +=AdcResult.ADCRESULT12;
    ClaVal +=AdcResult.ADCRESULT13;
    ClaVal +=AdcResult.ADCRESULT14;
    ClaVal +=AdcResult.ADCRESULT15;

    ClaVal /=16;

    ClaVal /=4096;
    ClaVal *=3.3;
	
	//计算PWM偏移的相位
    phaseVal=ClaVal/3.3;
    phaseVal = phaseVal*2500;
    phaseVal = 2500-phaseVal;
    EPwm2Regs.TBPHS.half.TBPHS = (Uint16)phaseVal;

	//设置GOTO_CLA的值
    if(VoltFilt>20){
            GOTO_CLA[0]='C';
            GOTO_CLA[1]='L';
            GOTO_CLA[2]='A';
        }

        if(VoltFilt>50)
        {
            GOTO_CLA[0]='C'+VoltFilt-50;
            GOTO_CLA[1]='L'+VoltFilt-50;
            GOTO_CLA[2]='A'+VoltFilt-50;
        }

}

__interrupt void
Cla1Task2 (void)
{

}
__interrupt void
Cla1Task3 (void)
{

}
__interrupt void
Cla1Task4 (void)
{

}
__interrupt void
Cla1Task5 (void)
{

}
__interrupt void
Cla1Task6 (void)
{

}
__interrupt void
Cla1Task7 (void)
{

}
__interrupt void
Cla1Task8 (void)
{
	//任务8用于初始化参数值
    VoltFilt=0;
    GOTO_CLA[0]='i';
    GOTO_CLA[1]='n';
    GOTO_CLA[2]='t';
}

//
// End of File
//



  • #include XSTRINGIZE(XCONCAT(TEXT,CLAShared.h)) 说明:
    TEXT的定义如下,由于我的共享头文件名称就叫CLAShared.h,所以我直接把TEXT定义为空即可。如果你的文件名为demo_CLAShared.h的话,则需要设置 TEXT=demo,文件中写入#include XSTRINGIZE(XCONCAT(TEXT,_CLAShared.h))。这种方法好处是,可以在不修改源代码下,引入不同的头文件,只需要修改工程属性里的TEXT即可。
    在这里插入图片描述

实验现象

  • 串口打印的数据如下:
    在这里插入图片描述
  • PWM波形图如下:
    • cla_val=3.3V
      在这里插入图片描述
    • cla_val=0V ~ 3.3V之间
      在这里插入图片描述
    • cla_val=0V
      在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木龠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值