This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS320F28377D:调试 ADC+DMA 问题

Guru**** 2611705 points
Other Parts Discussed in Thread: CONTROLSUITE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/690573/ccs-tms320f28377d-debug-adc-dma-problems

器件型号:TMS320F28377D
Thread 中讨论的其他器件:controlSUITE

工具/软件:Code Composer Studio

 这是我从 ti controlSUITE 上的 EPWM_ADC.c 和 dma_transfer.c 中更改的 ADC+DMA。 以前使用的 controlSUITE 新 ADC+DMA.c 已长时间更改、无法满足要求、这是对连续采样的单次更改、在完全缺少数据后更改为连续采样、正弦图像不完整、然后我自己在 EPWM_ADC 上更改。 在数据从 AdcResults []传递到 RDATA []后、通过 DmaRegs.ch1.control.bit.PERINTFRC=1直接在 ADC 中断中或软件触发 DMA 的循环中、我希望通过一轮采样来完成该程序。 然而,这似乎没有效果。 目前只有 AdcaResults 有正确的数据。 RDATA、全为0、我看到 dma_transfer.c 正在这样做、我似乎没有找到缺失的器件、所以我觉得很愚蠢、不知道如何参与、下面是我更改的一些代码、感谢您的回复。

//######################################################################################################################

//

//文件: adc_soc_ePWM_cpu01.c

//

//标题:   针对 F2837xD 通过 ePWM 触发 ADC。

//

//! addtogroup cpu01_example_list

//!

ADC ePWM 触发(ADC_SoC_ePWM)

//!

//! 此示例设置 EPWM 以定期触发 ADC。

//!

//! 程序运行后,内存将包含:\n

//! -\b 结果:一系列的模数转换样本

//! 引脚 A0。 采样之间的时间根据周期确定

//! PWM 计时器的功能。

//

//######################################################################################################################

//$TI 版本:F2837xD 支持库 V210 $

//$Release Date:Tue  Nov1 14:46:15 CDT 2016 $

//版权所有:版权所有(C) 2013-2016 Texas Instruments Incorporated -

//            http://www.ti.com/ 保留所有权利$

//######################################################################################################################

 

//

//包含的文件

//

#include "F28x_Project.h"

 

//

//函数原型

//

void  ConfigureADC (void);

void  ConfigureEPWM (void);

void  SetupADCepwm (uint16 通道);

中断  void  adca1_ISR (void);

中断   LOCAL_D_INTCH1_ISR ();

void  dma_init (void);

//

//定义

//

#define results_buffer_size 512

 

//

//全局

//

uint16 AdcaResults[results_buffer_size];

uint16 RDATA[Results_buffer_size];

uint16 结果索引;

易失 性 uint16 bufferFull;

易失 性 uint16 * DMADest;

易失 性 uint16 * DMASSOURCE;

 

void  main (void)

//

//步骤1. 初始化系统控制:

// PLL、安全装置、启用外设时钟

//此示例函数位于 F2837xD_SYSCTRL.c 文件中。

//

    InitSysCtrl()

 

//

//步骤2. 初始化 GPIO:

//此示例函数位于 F2837xD_GPIO.c 文件和中

//说明了如何将 GPIO 设置为其默认状态。

//

    InitGpio(); //针对此示例跳过

 

//

//步骤3. 清除所有中断并初始化 PIE 矢量表:

//禁用 CPU 中断

//

  Dint;

 

//

//将 PIE 控制寄存器初始化为默认状态。

//默认状态为禁用所有 PIE 中断和标志

//被清除。

//此函数位于 F2837xD_PIECTRL.c 文件中。

//

    InitPieCtrl()

 

//

//禁用 CPU 中断并清除所有 CPU 中断标志:

//

  IER = 0x0000;

  IFR = 0x0000;

 

//

//使用指向 shell 中断的指针初始化 PIE 矢量表

//服务例程(ISR)。

//这将填充整个表,即使是中断也是如此

//在本例中未使用。  这对于调试很有用。

//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程

//此函数可在 F2837xD_PieVect.c 中找到

//

    InitPieVectTable()

 

//

//映射 ISR 函数

//

  EALLOW;

  PieVectTable.ADCA1_INT =&adca1_ISR; //针对 ADCA 中断1的函数

  PieVectTable.DMA_CH1_INT=&LOCAL_D_INTCH1_ISR;//中断入口函数 μ s

  EDIS;

 

 

    //启用全局中断和更高优先级的实时调试事件:

    //

      IER |= M_INT1; //启用组1中断

       IER |= M_INT7;//启用组1中断

        //

      PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   //启用 PIE 块

      PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

      PieCtrlRegs.PIEIER7.bit.INTx1 = 1;   //启用 PIE 组7、INT 2 (DMA CH2)

                              //启用 CPU INT6

      EINT;  //启用全局中断 INTM

      ERTM;  //启用全局 实时 中断 DBGM

 

//

//配置 ADC 并为其加电

//

  ConfigureADC();

 

//

//配置 ePWM

//

  ConfigureEPWM();

 

//

//在通道0上设置用于 ePWM 触发转换的 ADC

//

  SetupADCepwm (2);

 

  dma_init ();  //设置  DMA

 

    //确保 DMA 连接到外设帧2桥接器(EALLOW 受保护)

    //

 EALLOW;

  CpuSysRegs.SECMSEL.bit.PF2SEL = 1;

  EDIS;

 

//

  DmaRegs.ch1.control.bit.PERINTCLR = 1;

 

   // StartDMACH1();    //启动 DMA 通道

//

//初始化结果缓冲区

//

    for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)

  {

      AdcaResults[resultsIndex]=0;

      RDATA[resultsIndex]=0;

  }

  resultsIndex = 0;

  bufferFull = 0;

 

//

//启用 PIE 中断

//

 

    StartDMACH1(); //启动 DMA 通道

//

//同步 ePWM

//

  EALLOW;

  CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1 ;

  EDIS;

 

//

//循环无限地进行转换

//

    操作

  {

        //

        //启动 ePWM

        //

      EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //启用 SOCA

      EPwm1Regs.TBCTL.bit.CTRMODE = 0; //取消冻结、并进入递增计数模式

 

        //

        //等待、而 ePWM 导致 ADC 转换、然后导致中断、

        //填充结果缓冲区,最终设置 bufferFull

        //flag

        //

        while (!bufferFull);

      bufferFull = 0; //清除缓冲区已满标志

       EALLOW;

      // DmaRegs.ch1.control.bit.PERINTFRC = 1;

       EDIS;

        //

        //停止 ePWM

        //

      EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //禁用 SOCA

      EPwm1Regs.TBCTL.bit.CTRMODE = 3; //冻结计数器

 

        //

        //此时,AdcaResults[]包含一系列转换

        //从所选通道

        //

 

        //

        //软件断点,再次点击运行以获取更新的转换

        //

         asm (" ESTOP0");

  } while (1);

 

//

// ConfigureADC -写入 ADC 配置并为两者加电

//              ADC A 和 ADC B

//

 配置 ADC ()

  EALLOW;

 

    //

    //写入配置

    //

    AdcaRegs.ADCCTL2.bit.prescale = 6; //将 ADCCLK 分频器设置为/4

    AdcSetMode (ADC_ADCA、ADC_Resolution_16BIT、ADC_SIGNALMODE_differential);

 

    //

    //将脉冲位置设置为晚期

    //

    AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1 ;

 

    //

    //为 ADC 加电

    //

    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

 

    //

    //延迟1ms 以允许 ADC 加电时间

    //

  DELAY_US (1000);

 

  EDIS;

 

//

// ConfigureEPWM -配置 ePWM SOC 并比较值

//

 配置 EPWM ()

  EALLOW;

    //假设 ePWM 时钟已启用

  EPwm1Regs.ETSEL.bit.SOCAEN  = 0;    //禁用组上的 SOC

  EPwm1Regs.ETSEL.bit.SOCASEL  = 4;   //在递增计数时选择 SOC

  EPwm1Regs.ETPS.bit.SOCAPRD = 1;       //在发生第一个事件时生成脉冲

  EPwm1Regs.CMPA.bit.CMPA = 2000;     //将比较 A 值设置为2000计数

  EPwm1Regs.TBPRD = 4000;             //将周期设置为4000个计数

  EPwm1Regs.TBCTL.bit.CTRMODE = 3;      //冻结计数器

  EDIS;

 

//

// SetupADCepwm -设置 ADC ePWM 采集窗口

//

void  SetupADCepwm (uint16 通道)

    uint16 acqps;

 

    //

    //根据分辨率确定最小采集窗口(在 SYSCLKS 中)

    //

    if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution)

  {

      acqps = 14; //75ns

  }

    否则 、//分辨率为16位

  {

      acqps = 63; //320ns

  }

 

    //

    //选择要转换的通道和转换结束标志

    //

  EALLOW;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道;  //SOC0将转换引脚 A2

    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //采样窗口为100个 SYSCLK 周期

    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; // ePWM1 SOCA/C 上的触发

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // SOC0结束将设置 INT1标志

    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //启用 INT1标志

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //确保 INT1标志被清除

  EDIS;

 

//

// adca1_ISR -在 ISR 中读取 ADC 缓冲器

//

中断  void  adca1_ISR (void)

  AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT0;

 

  // DmaRegs.ch1.control.bit.PERINTFRC = 1;

 

    if (results_buffer_size <= resultsIndex)

  {

      resultsIndex = 0;

      bufferFull=1;

  }

 

   EALLOW;

  DmaRegs.ch1.control.bit.PERINTFRC = 1;

  EDIS;

 

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清除 INT1标志

  PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;

 

 

 

// dma_init - TX 和 RX 通道的 DMA 设置。

//

 

void  dma_init()

    //

    //有关以下函数的说明,请参阅 dma.c。

    //

 

    //

    //初始化 DMA

    //

    DMAInitialize()

 

  DMASSOURCE =结果;

  DMADest = RDATA;

 

    //

    //配置 DMA CH1

    //

    DMACH1AddrConfig (DMADest、DMASource);

    DMACH1BurstConfig (15、1、1);

    DMACH1TransferConfig (31、1、1);

    DMACH1ModeConfig (0、PERINT_ENABLE、OneShot_disable、CONT_ENABLE、

                   SYNC_DISABLE、SYNC_SRC、OVRFLOW_DISABLE、十六位、

                   CHINT_BEGIN、CHINT_ENABLE);

 

 

// local_D_INTCH6_ISR - DMA 通道6 ISR

//

中断   LOCAL_D_INTCH1_ISR ()

 

  PieCtrlRegs.PIEACK.all = PIEACK_group7; // ACK 以接收更多中断

                                            //来自此 PIE 组

 

//

//文件结束

//

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否检查 RDATA 存储在哪个存储器位置? 您需要确保 DMA 在存储器区域中具有访问权限。

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢,这是我的问题所在。我已经解决了。非常感谢。