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.

[参考译文] TMDSPREX2.8335万:从ADC读取信息时,在图形窗口中记录和查看的数据不正确

Guru**** 2582595 points
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1092112/tmdsprex28335-improper-data-logging-and-viewing-in-the-graph-window-while-reading-information-from-adc

部件号:TMDSPREX2.8335万
主题中讨论的其他部件: C2000WAREcontrolSUITE

大家好,

我代表客户发布。

我使用的是TMDSPREX2.8335万板。 我正在尝试使用其ADC端口将外部正弦信号(50 Hz的栅电压)转储到控制器中。 信号调节良好,处于0至3伏的安全限值之间。

最初,我将ADC绑定到CPU Timer0中断(每25微秒或40 kHz发生一次),并观察图形窗口中的信号。

CPU TIMER0中断触发的ADC代码如下所示:

包含 "math.h"

#include  "IQmathlib.h"

#include  "DSP2833x_Device.h"     // DSP2833x  Headerfile  include文件

#include  "DSP2833x_examples.h"   // DSP2833x examples include File

 

//本文件中找到的函数的prototype语句。

中断 void  CPU_timer0_ISR(void);

 

 

//用于绘图,从ADC读取和中断计数的变量

UINT32 计数=1;

Int 样本= 0;

float  array_sine[800];

float  voltage_grid = 0,vg1 = 0,volt_offset = 0,voft1 = 0;

 

主要()

   InitSysCtrl();

//   EALLOW;

//   SysCtrlRegs.HISPPCP.ALL = 0x3; // HSPCLK = SYSCLKOUT/6

//   EDIS;

   dint;   //禁用CPU中断

   InitPieCtrl();//  禁用所有外围设备中断

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  =0;//      停止所有TB时钟

   EDIS;

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  = 1;         //启动所有 同步的计时器

   EDIS;

   IER = 0x0000;   //禁用所有中断

   IFR = 0x0000;   //清除所有中断的标志

   InitPieVectorTable();

 

 

//************** ADC初始化和配置开始************ //

   InitAdc();//                               基本ADC设置(包括校准)

   AdcRegs.ADCTRL1.ALL  =0;                 //初始化前清除ADCTRL1

   AdcRegs.ADCTRL1.bit.ACQ_PS  = 0xF;        //采样和保持(15+1)=16个ADC周期

   AdcRegs.ADCTRL1.bit.cps  = 0;             //进一步除以1

   ADcRegs.ADCTRL1.bit.SEQ_CASC=1 ;        // ADC的级联模式(16状态)

   AdcRegs.ADCTRL1.bit.con_run  =0;        //禁用ADC的连续运行模式

 

//   AdcRegs.ADCTRL2.ALL =0;                //初始化前清除ADCTRL2

   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1  = 1;      //在SEQ1上启用中断

   AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1  = 0;    //在序列的每一端启用中断

   AdcRegs.ADCTRL2.bit.RST_SEQ1  = 1;        //重置SEQ1

   AdcRegs.ADCTRL2.bit.so_SEQ1  = 0;        //从ePWM1_SOCA触发启动SEQ1

 

 

   ADcRegs.ADCTRL3.bit.SMODE_SEL  = 0;       // ADC的连续同步转换

   AdcRegs.ADCTRL3.bit.ADCCLKPS  = 3;//         3,因为ADC的HSPCLK为75  MHz  (150/6);请参阅上文

                                                 //来自DSP2833x_sysctrl.c用于ADC的FCLK为75 MHz而不是150 MHz;

                                                 //75/(2*3)= 12.5 兆赫

 

   AdcRegs.ADCMAXCONV.ALL  = 0x0001;              // 2个转换

   AdcRegs.ADCCHSELSEQ1.bit.CONV00  = 0x2;     //将ADCINA2分配给CONV00

   AdcRegs.ADCCHSELSEQ1.bit.CONV01  = 0x3;     //将ADCINA3分配给conv01

 

//************** ADC初始化和配置结束************ //

 

   EALLOW;  //这是写入EALLOW保护寄存器所必需的

   PieVectorTable.TINT0  =&CPU_timer0_ISR;

   EDIS;

 

   InitCpuTimers();

   ConfigCpuTimer(&CpuTimer0150,25); //以25 us或40 kHz的频率生成TINT0

   CpuTimer0Regs.tcr.all  = 0x4001;       //禁用 CPU  timer0中断(不需要)

 

 

  IER |=1; //启用所有INT1组

  PieCtrlRegs.PIEIER1.bit.INTx7=1 ;   //启用ADC INT (组1中的第6个中断)

  EINT;          //启用全局中断INTM

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

 

 

}

 

中断 无效 CPU_TIMER0_ISR(void)

   count++;                                    //检查是否正在生成中断

   AdcRegs.ADCTRL2.bit.so_SEQ1  = 1;

   volt_grid = AdcRegs.ADCRESULT0>>4;//       从ADC读取

   volt_offset = AdcRegs.ADCRESULT1>>4;//     从ADC读取

   vg1 = voltage_grid*3/4095;                  //获取原始值

   voft1 = volt_offset*3/4095;              //获取原始值

 

        IF  (样本> 799)

           样本= 0;

       array_sine[sample]= vg1;

       示例++;

 

  //为下一个ADC序列重新初始化

 AdcRegs.ADCTRL2.bit.RST_SEQ1  = 1;         //重置SEQ1

 AdcRegs.ADCST.Bit.INT_SEQ1_CLR  = 1;       //清除INT SEQ1位

 PIECtrlRegs.PIEACK/ALL  = PIEACK_Group1;   //确认中断到PIE

}

 

//===========================================================================================================================================

//源代码结束。

//===========================================================================================================================================

与上述代码对应的图形如下所示:

如您所见,(转换的)查看信号中存在不连续性。

然后,我通过从ePWM1中断向ADC发出命令(在相同条件下,即每25微秒或40 kHz)重试一次。 ePWM1中断的ADCSoC代码如下:

/*     目标:

 * A)在25 us时使用ePWM1触发ADC中断

 * b)级联模式下的ADC

 * c) ADC执行顺序采样

 * d) ACQ_PS = 0xF (15+1=16个保持周期)

 * e) ADC频率为12.5 MHz

 * f)观察图解

 */

 

包含 "math.h"

#include  "IQmathlib.h"

#include  "DSP2833x_Device.h"    // DSP2833x  Headerfile  include文件

#include  "DSP2833x_examples.h"   // DSP2833x examples include File

 

//本文件中找到的函数的prototype语句。

void  InitEPwmTimer(void);

中断 无效 ADC_ISR(void);

 

 

//用于绘图,从ADC读取和中断计数的变量

UINT32 计数=1;

Int 样本 = 0;

float  array_sine[800];

float  voltage_grid = 0,vg1 = 0,volt_offset = 0,voft1 = 0;

 

主要()

   InitSysCtrl();

//   EALLOW;

//   SysCtrlRegs.HISPPCP.ALL = 0x3; // HSPCLK = SYSCLKOUT/6

//   EDIS;

   dint;   //禁用CPU中断

   InitPieCtrl();//  禁用所有外围设备中断

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  =0;//      停止所有TB时钟

   EDIS;

   InitEPwmTimer();//    启动所需的ePWM寄存器并配置中断要求

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC  = 1;         //启动所有 同步的计时器

   EDIS;

   IER = 0x0000;   //禁用所有中断

   IFR = 0x0000;   //清除所有中断的标志

   InitPieVectorTable();

 

 

//************** ADC初始化和配置开始************ //

   InitAdc();//                               基本ADC设置(包括校准)

   AdcRegs.ADCTRL1.ALL  =0;                 //初始化前清除ADCTRL1

   AdcRegs.ADCTRL1.bit.ACQ_PS  = 0xF;        //采样和保持(15+1)=16个ADC周期

   AdcRegs.ADCTRL1.bit.cps  = 0;             //进一步除以1

   ADcRegs.ADCTRL1.bit.SEQ_CASC=1 ;        // ADC的级联模式(16状态)

   AdcRegs.ADCTRL1.bit.con_run  =0;        //禁用ADC的连续运行模式

 

//   AdcRegs.ADCTRL2.ALL =0;                //初始化前清除ADCTRL2

   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1  = 1;      //在SEQ1上启用中断

   AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1  = 0;    //在序列的每一端启用中断

   AdcRegs.ADCTRL2.bit.RST_SEQ1  = 1;        //重置SEQ1

   AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1  = 1;        //从ePWM1_SOCA触发启动SEQ1

 

 

   ADcRegs.ADCTRL3.bit.SMODE_SEL  = 0;       // ADC的连续同步转换

   AdcRegs.ADCTRL3.bit.ADCCLKPS  = 3;//         3,因为ADC的HSPCLK为75  MHz  (150/6);请参阅上文

                                                 //来自DSP2833x_sysctrl.c用于ADC的FCLK为75 MHz而不是150 MHz;

                                                 //75/(2*3)= 12.5 兆赫

 

   AdcRegs.ADCMAXCONV.ALL  = 0x0001;              // 2个转换

   AdcRegs.ADCCHSELSEQ1.bit.CONV00  = 0x2;     //将ADCINA2分配给CONV00

   AdcRegs.ADCCHSELSEQ1.bit.CONV01  = 0x3;     //将ADCINA3分配给conv01

 

//************** ADC初始化和配置结束************ //

 

   EALLOW;  //这是写入EALLOW保护寄存器所必需的

   PieVectorTable.ADCINT  =&ADC_ISR;

   EDIS;

 

   InitCpuTimers();

   ConfigCpuTimer(&CpuTimer0150,25); //以25 us或40 kHz的频率生成TINT0

//   CpuTimer0Regs.tcr.all = 0x4001;      //禁用 CPU  timer0中断(不需要)

 

 

  IER |=1; //启用所有INT1组

  PieCtrlRegs.PIEIER1.bit.INTx6=1 ;   //启用ADC INT (组1中的第6个中断)

  EINT;          //启用全局中断INTM

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

 

 

}

 

void  InitEPwmTimer (void)

   EALLOW;

   GpioCtrlRegs.GPAMUX1.bit.GPIO0  = 1; // ePWM1A激活

   gpioCtrlRegs.GPAMUX1.bit.GPIO1  = 1; // ePWM1B激活

   EDIS;

 

 

//     ePWM 1模块时钟同步已禁用

 

//     ePWM1 TBCTL初始化

   EPwm1Regs.TBCTL.bit.FREE_SOFT  = 11;     //自由运行

   EPwm1Regs.TBCTL.bit.PHSDIR  = 1;         //同步后计数

   EPwm1Regs.TBCTL.bit.CLKDIV  = 0;         // TBCLK = HSPCLK/1

   EPwm1Regs.TBCTL.bit.HSPCLKDIV  = 1;      // HSPCLK = SYSCLK/2

   EPwm1Regs.TBCTL.bit.SWFSYNC  = 0;        //软件同步已禁用

   EPwm1Regs.TBCTL.bit.SYNCOSEL  = 3;      //禁用同步

   EPwm1Regs.TBCTL.bit.PRDLD  = 0;          // CTR上的负载= 0

   EPwm1Regs.TBCTL.bit.PHSEN  = 0;          //禁用相位启用

   EPwm1Regs.TBCTL.bit.SYNCOSEL  = 3;       //禁用同步

   EPwm1Regs.TBCTL.bit.CTRMODE  = 0;       //在上模式下计数

 

//     ePWM1 ETPS初始化

   EPwm1Regs.etps.bit.SOCBCNT  = 0;         //这是只读位

   EPwm1Regs.ETPS.bit.SOCBPRD  =0;         //已禁用,因为中断由ePWM1A生成

   EPwm1Regs.etps.bit.SOCACNT  = 0;         //这是只读位

   EPwm1Regs.ETPS.bit.SOCAPRD  = 1;         //每次ePWM1A都会生成中断

   EPwm1Regs.ETPS.bit.INTCNT  = 0;          //只读位无关紧要

   EPwm1Regs.ETPS.bit.INTPRD  =1;         //生成每个事件的中断

 

//     ePWM1 ETSEL初始化

   EPwm1Regs.ETSEL.bit.SOCBEN  = 0;         //禁用SOCB

   EPwm1Regs.ETSEL.bit.SOCBSEL  = 0;        //因为SOCB已禁用

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

   EPwm1Regs.ETSEL.bit.SOCASEL  = 1;        //在CTR = 0时生成中断

   EPwm1Regs.ETSEL.bit.inten  = 0;          //禁用PWM中断

   EPwm1Regs.ETSEL.bit.INTSEL  = 0;         //不重要,因为PWM中断已禁用

 

//     ePWM1 ETSEL初始化

   EPwm1Regs.TBPRD  = 1875;                 //  fpwm  = 40  kHz  =  finterrupt

}

 

中断 无效 ADC_ISR(void)

   count++;                                    //检查是否正在生成中断

   volt_grid = AdcRegs.ADCRESULT0>>4;//       从ADC读取

   volt_offset = AdcRegs.ADCRESULT1>>4;//     从ADC读取

   vg1 = voltage_grid*3/4095;                  //获取原始值

   voft1 = volt_offset*3/4095;              //获取原始值

 

        IF  (样本 > 799)

            样本 = 0;

       array_sine[sample]= vg1;

        示例++;

 

  //为下一个ADC序列重新初始化

 AdcRegs.ADCTRL2.bit.RST_SEQ1  = 1;         //重置SEQ1

 AdcRegs.ADCST.Bit.INT_SEQ1_CLR  = 1;       //清除INT SEQ1位

 PIECtrlRegs.PIEACK/ALL  = PIEACK_Group1;   //确认中断到PIE

}

 

//===========================================================================================================================================

//源代码结束。

//===========================================================================================================================================

 

统计图窗口中的相应输出如下所示:

正如您在这两种情况下所看到的(无论是ADC连接到TIMER0中断还是ADC连接到ePWM1中断),即使我正在收集800点(50 Hz =20毫秒,40 kHz =25 us),我也会得到不连续的数据; 20 m /25u = 800点)并绘制所有点。

另一个有趣的事情是,即使ADCTRL2在TIMER0中断的情况下应该显示0x4800或0x2800 (取决于RST =1或SOC =1),或者在ePWM1的SOC的情况下显示0x4900或0x0999 (取决于RST =1或0)。 但是,ACTRL2为TIMER0保留了一个永久值0x0800,为ePWM1保留了一个永久值0x0900。

为什么在这两种情况下统计图窗口中都缺少数据,为什么ADCTRL2保持永久值?

C2000专家能否帮助我调试这些问题,因为我已经尝试解决这个问题几个星期了,但问题仍然存在。

我希望您能提供帮助。

此致,

马文

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

    Marvin,

    我认为问题是时间问题,或者从您读取ADC值到下一个值被替换之间的时间不足。  

    我想利用更多的序列插槽(实际上所有这些插槽)和SEQ_OVD功能,使用结果寄存器创建缓冲区,在将8个ADC样本读取到内存之前,我们将它们转换为结果寄存器。 当我们读取结果时,ADC会采集接下来的8个样本并将其填充到接下来的8个结果寄存器中,以此类推。

    您可以查看以下示例:C:\ti\c2000\C2000Ware_4_01_00\DEVICE_support\F2833x\examples\ADC_SEG_ovd_test以2000以了解2833了解我们要在此处执行的操作。  如果要保持采样率相同而不调整ADC时钟(即从计时器或PWM),您可以保留MAX_CONV=0和CONT_RUN=0。  ADC ISR将在每次转换后触发,但在一段时间内不会覆盖当前的ADCRESULT。  

    如果您认为需要所有16个结果注册表,即SEQ_CASC=1或只有8个SEQ_CASC=0,则由您决定。

    您还需要使用ADCRESULT镜像注册表,它具有较低的读取延迟,并且已经正确调整。  整个目标是尽量缩短ADC从寄存器读取结果所需的时间,这样您就不会覆盖尚未读取的寄存器。

    使用覆盖还可以使您不必在每次转换后重置序列发生器,从而最大限度地减少CPU交互/开销。  

    尝试一下,看看这是否可以消除您所看到的不连续现象。

    最佳,

    Matthew

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

    您好,Marvin,

    首先,非常感谢您Marvin代表我发布此查询。

    Matthew,您好!

    你又来救我了。 您是一个非常善良,知识渊博的人。 非常感谢您提供有关查询的见解。 您建议我使用SEQ_OVD功能和ADCRESULT镜像寄存器来解决我的问题。

    我必须 同时查看5个变量(2个交流(50 Hz),2个直流(有明显波纹)和1个直流(几乎恒定)信号)(这意味着可用8个ADC信道中有5个ADC信道,TMDSPREX2.8335万只有8个ADC跳线A2-A5和B2-B5)来控制我的硬件。 过去,由于存储矩阵的大小(在这种情况下为array_sine),当我 尝试通过创建 大小为400x4或更大的二维存储来同时查看多个变量时,我遇到了内存问题。

    此外,在Frank Bormann和 团队设计的教程材料的模块8 (整个材料的压缩版本文件名为ssqc019.zip)的PDF第16页的最后一行中,提到左对齐 (或ADC RESULTn寄存器)是使用以“分数”操作的控制系统时的最佳选择。 即使是2.8335万 TRM也提出了同样的建议。

    再想想,在我的子例程(基于timer0和基于PWM的ADC中断)中,即C200ware和控制套件中可用的示例代码的精确副本(概念方面)中,只有在从带有con_run=0的结果寄存器中读取时,才会清除中断标志。 只有在清除标志后,转换才会开始,并且在发出下一个SOC命令时也会开始转换。 那么,如何在  读取之前覆盖寄存器呢?

    我非常尊敬,如果不解决内存问题,我也不会使用SEQ_OVD功能。

    如果你们能帮助我消除误解,并为我的厚头骨提供知识,那将是非常慷慨的。

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    Ankit,

    我知道左对齐ADC结果上的点更适合使用分数的控制系统。  这是因为左对齐的12位数实际上是IQ数学运算的Q4位数。

    但是,使用默认ADC结果寄存器的问题在于它们存在于PF2总线上,而PF2总线在构造中始终在2等待状态下运行,以进行数据读取。  实际上,每次读取将需要3个CPU时钟周期@150MHz。  

    ADCRESULTMirror Regs存在于PF0总线上,它是用于数据读取的0 WaitStates。  这将节省读取的访问时间。  如果您需要左对齐代码或示例的兼容性,我只需在存储数据之前将镜像结果移动4位。  我认为C28x内核中的转换逻辑应该在不增加读/写操作开销的情况下完成此操作,因此我们应该节省周期时间。

    我需要查看带有CONT_RUN=0的ADC的操作,以了解如果SEQ_INT标志未清除,转换器是否停止运行。  或者,软件代码正在使用清除此位的代码对另一个SOC进行门控。  当我看到ADC结果数据集中的不连续时,通常是由于CPU相对于随时间变化的采样率的时间裕度丢失。  我会看看我是否可以提出您提到的示例代码,以便更好地理解。

    请给我另一天时间尝试重现问题,或者建议我们可以安全删除/编辑哪些代码。

    最佳,

    Matthew

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

    Matthew,您好!

    我很抱歉这么迟才回覆,又给你加了很多额外的东西,我当然不想你替我做肮脏的工作,因为这是不道德的。 请接受我的道歉。

    在您的答复中,您提到应该使用ADCResult镜像寄存器,而不是使用ADCResult。 我写以下等式是否正确?

    (AdcRegs.ADCRESULT0>>4)等于 (AdcMirror.ADCRESULT0)

    如果上述公式正确,那么为什么我要完全移动我的AdcMirror结果。 我觉得这是滥用控制器。

    我所寻找的只是一种在读取ADC时消除这种不连续性的方法,因为如果这种不连续性继续存在于我的代码中,那么我将无法调整我的控制环路,我的硬件将不会成功。

    我将向您解释我目前为止的方法。 我从单相自耦变压器(在我的情况下为50 Hz)获得输出并将其分配给电路。 此电路可在名为"calculation"的Excel文件中找到,该文件位于以下地址: C:\ti\controlSUITE\development _kits\HV_1PH_DCAC\v1_04_00_00\hardware。 此电路的输出已提供给ADC,然后ADC已使用Marvin代表我在上面发布的两个代码(一次一个)进行操作。 然后,我通过绘制array_sine变量来查看图形中的ADC值。

    当然,请尽可能多地花时间,佩特先生。 我一点也不介意。

    请 指导 我 调试此错误。 否则我的硬件实验就不合适了。
    我请佩特先生给予指导。

    保持手指交叉。

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    Ankit,

    请再给我一天时间来回答。

    最佳,

    Matthew

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

    您好,Pate先生,

    完全不用担心。 请别着急,慢慢来。

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    Ankit,

    这:

    2.8335万 -ADC/4048484824#40ULT48s"](AdcULT0>ADES0)[ADCULT0>AD0[ADES0]4048484824(AdcULT0>ADES0)[ADCULT0>AD0[ADES0](ADCULT0)AD0>ADCULT0[ADULT0).ADULT0[AD0  

    正确。  我唯一要说的是,如果您希望ADC的第四季度基数(左对齐12位),那么我仍然建议您使用镜像来节省读取访问时间,然后将读取后的偏移向左移动4。  如果您真的不需要左对齐数据,那么您只需使用镜像中的结果,而无需移动。

    如果我们看一下不连续的间距,它似乎是在数组大小处发生的,每800个计数。  我想知道这是真实的还是CCS中图形的某些伪迹。  您是否可以创建第二个800元素阵列来存储第二个800个样本?  然后,我想将代码分解出来,比较一下第一个数组的元素800和第二个数组的元素1,看看我们是否仍然观察到数据集中的不连续性。  这将排除图表与真正的不连续性之间的关系。

    最佳,
    Matthew

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

    您好,Pate先生,

    我会尝试在明天之前发布您要求我提供的信息,并进行额外的测试以找出问题。 但是,我想我在E2E论坛上看到过这样的帖子,用户遇到了类似的问题。

    下面是指向该主题的链接:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/867065/ccs-tms320f28335-sine-signal-reading-problem</s>2000 200086.7065万2.8335万

    Manish Bhardwaj处理了这条线。 遗憾的是,此线程中没有任何内容可用于解决我的问题。

    我会试着划伤我的头,然后找出问题所在。 并对延长这一职位表示歉意。

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    尊敬的佩特先生:

    很抱歉我的回复太晚了。

    你让我一次绘制前800个样本,然后再绘制下800个样本,以此类推。

    我已经完成了。 很遗憾,由于网站限制,我无法在此处附加图形图像。 然而,我已请马文·加西斯·阿尔卡天使先生代表我张贴这张照片。 您应该很快就能获得该映像。 我将在下面附上我用于获取此图像的代码。

    /*      OBJECTIVE:
     * a) use ePWM1 triggered ADC interrupt at 25 us
     * b) ADC in cascaded mode
     * c) ADC does sequential sampling
     * d) ACQ_PS = 0xf (15+1=16 hold cycles)
     * e) ADC frequency is 12.5 MHz
     * f) observe the plot
     */
    
    #include "math.h"
    #include "IQmathlib.h"
    #include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
    
    // Prototype statements for functions found within this file.
    void InitEPwmTimer(void);
    interrupt void adc_isr(void);
    
    
    // Variables used for plotting, reading from ADC and interrupt count
    Uint32 count=1;
    int plot_count = 0, sample = 0;
    float array_sine[800][2];
    float voltage_grid = 0, vg1 = 0, voltage_offset = 0, voft1 = 0;
    
    main()
    {
        InitSysCtrl();
    //    EALLOW;
    //    SysCtrlRegs.HISPCP.all = 0x3;  // HSPCLK = SYSCLKOUT/6
    //    EDIS;
        DINT;   // disable CPU interrupts
        InitPieCtrl();  // disable all peripheral interrupts
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
        EDIS;
        InitEPwmTimer();    // initiate the required ePWM registers and configure interrupt requirements
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
        EDIS;
        IER = 0x0000;   // disables all interrupts
        IFR = 0x0000;   // clears flags of all interrupts
        InitPieVectTable();
    
    
    //************ADC INITIALISATION and CONFIGURATION BEGINS************//
        InitAdc();                               // basic ADC setup (including calibration)
        AdcRegs.ADCTRL1.all = 0;                 // clear ADCTRL1 before initializing
        AdcRegs.ADCTRL1.bit.ACQ_PS = 0xf;        // sample and hold for (15+1)=16 ADC cycles
        AdcRegs.ADCTRL1.bit.CPS = 0;             // divide further by 1
        AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        // cascaded mode for ADC (16 states)
        AdcRegs.ADCTRL1.bit.CONT_RUN = 0;        // continuous run mode for ADC disabled
    
    //    AdcRegs.ADCTRL2.all = 0;                 // clear ADCTRL2 before initializing
        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;      // enable interrupt on SEQ1
        AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;    // enable interrupt every end of sequence
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;        // reset SEQ1
        AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;        // start SEQ1 from ePWM1_SOCA trigger
    
    
        AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;       // sequential simultaneous conversion for ADC
        AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;        // 3 because HSPCLK for ADC is 75 Mhz (150/6); see above
                                                     // from DSP2833x_SysCtrl.c FCLK for ADC is 75 MHz and not 150 MHz;
                                                     // 75/(2*3) = 12.5 MHz
    
        AdcRegs.ADCMAXCONV.all = 0x0001;              // 2 conversions
        AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;     // assign ADCINA2 to conv00
        AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;     // assign ADCINA3 to conv01
    
    //************ADC INITIALISATION and CONFIGURATION ENDS************//
    
        EALLOW;  // This is needed to write to EALLOW protected registers
        PieVectTable.ADCINT = &adc_isr;
        EDIS;
    
        InitCpuTimers();
        ConfigCpuTimer(&CpuTimer0, 150, 25); // generate TINT0 at 25 us or 40 kHz
    //    CpuTimer0Regs.TCR.all = 0x4001;       // disable cpu timer0 interrupt (not needed)
    
    
       IER |= 1; // Enable all of INT1 group
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;   // enable ADC INT (6th interrupt in group 1)
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
    
    
    }
    
    void InitEPwmTimer(void)
    {
        EALLOW;
        GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
        GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B active
        EDIS;
    
    
    //      ePWM 1 module clock sync disabled
    
    //      ePWM1 TBCTL INITIALISATIONS
        EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;     // free run
        EPwm1Regs.TBCTL.bit.PHSDIR = 1;         // count up after sync
        EPwm1Regs.TBCTL.bit.CLKDIV = 0;         // TBCLK = HSPCLK/1
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;      // HSPCLK = SYSCLK/2
        EPwm1Regs.TBCTL.bit.SWFSYNC = 0;        // software sync disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.PRDLD = 0;          // load on CTR = 0
        EPwm1Regs.TBCTL.bit.PHSEN = 0;          // phase enable disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.CTRMODE = 0;        // count in up-mode
    
    //      ePWM1 ETPS INITIALISATIONS
        EPwm1Regs.ETPS.bit.SOCBCNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCBPRD = 0;         // disabled because interrupt is to be generated by ePWM1A
        EPwm1Regs.ETPS.bit.SOCACNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;         // interrupt is to be generated by ePWM1A every time
        EPwm1Regs.ETPS.bit.INTCNT = 0;          // read only bit doesn't matter
        EPwm1Regs.ETPS.bit.INTPRD = 1;          // generate interrupt every event
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.ETSEL.bit.SOCBEN = 0;         // disable SOCB
        EPwm1Regs.ETSEL.bit.SOCBSEL = 0;        // because SOCB is disabled
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;         // enable SOCA
        EPwm1Regs.ETSEL.bit.SOCASEL = 1;        // generate interrupt when CTR = 0
        EPwm1Regs.ETSEL.bit.INTEN = 0;          // disable PWM interrupt
        EPwm1Regs.ETSEL.bit.INTSEL = 0;         // doesn't matter as PWM interrupt is disabled
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.TBPRD = 1875;                 // fpwm = 40 khz = finterrupt
    }
    
    interrupt void adc_isr(void)
    {
        count++;                                    // check if interrupt is being generated
        voltage_grid = AdcRegs.ADCRESULT0>>4;       // read from ADC
        voltage_offset = AdcRegs.ADCRESULT1>>4;     // read from ADC
        vg1 = voltage_grid*3/4095;                  // get original value
        voft1 = voltage_offset*3/4095;              // get original value
    
            if (plot_count <800)
            {
                if (sample > 799)
                sample = 0;
            array_sine[sample][0] = vg1;        // to collect and plot first 800 samples of grid voltage
            array_sine[sample][1] = 0;          // the second 800 samples are zero during this time
            sample++;
            plot_count++;
            }
            if ((plot_count > 799) && (plot_count<1600))
            {
                if (sample > 799)
                            sample = 0;
                        array_sine[sample][0] = 0;        // the first 800 samples are zero during this time
                        array_sine[sample][1] = vg1;          // to collect the second 800 samples of grid voltage
                        sample++;
                        plot_count++;
            }
            if (plot_count == 1600)
                plot_count = 0;
    
      // Reinitialize for next ADC sequence
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    }
    
    //===========================================================================
    // End of SourceCode.
    //===========================================================================
    

    故障仍然存在。 我仍然可以看到这种不连续性。

    请帮助。

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    您好,Pate and Ankit,

    这是Ankit提到的图形的图像。

    我希望这能有所帮助。

    此致,

    马文

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

    Ankit,

    您是否可以附加/复制采样数组的内容,可能是第一个数组的最后20个计数和第二个数组的前20个计数,等等  

    查看数据图解时,即使存在不连续性,但似乎此数据可能是之前样本的精确副本。 例如,如果我及时推回不连续性,它可能与之前的数据完全重叠。  这将在某种程度上表明我们正在以某种方式在代码中重复使用旧数据。

    最佳,

    Matthew

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

    您好,Marvin,

    非常感谢您代为发布该图片。 真的非常感谢。

    您好,Pate先生,

    请接受我在将近一周后对您的回复的道歉。 我不在实验室,因此我没有资源向您提供您要求我提供的信息。

    以下是我的观察,回应和对您的后续问题:

    A)我考虑了您的观点,并阅读了AdcMirror寄存器的结果。 绘图时,不连续仍显示在图形中。 我将请求Marvin代表我发布图片。

    b)您之前在回复中提到,您会尝试在您的最后重现该问题。您是否能在您的最后看到该错误?

    c)您是否有机会了解 Manish Bhardwaj处理的类似问题? 这是指向该线程的链接:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/867065/ccs-tms320f28335-sine-signal-reading-problem</s>2000 200086.7065万2.8335万

    D)只有在绘制通过ADC馈送至控制器的外部交流信号时,才会出现此故障。 当绘制内部生成的信号或外部信号为DC时,不会显示此消息。

    e)您提到了代码的破裂。 如何操作? 这是否意味着暂停代码? 或者,我是否应该禁用监视窗口中的连续刷新,并在每次单击刷新按钮后复制数据?

    f)我甚至尝试更改图形的采样率,但是仍然存在小故障。

    g)可能这只是一个图形相关的故障,但是,这会影响我的控制算法和控制器增益吗?

    h)您询问前800个样本的最后20个值和接下来800个样本的前20个值,希望这些值相互重叠, 但是,我认为,因为我们正在处理一个正弦信号,最后20个点和前20个点应该都在同一方向上(要么全部增加,要么全部减少),因为 信号正在传输(不断刷新)。 我无法将阵列导出到CSV或Excel文件。 如果你能告诉我如何出口,那么我将在星期一或星期二给你肯定的数值。

    代码也随附以供参考。

    /*      OBJECTIVE:
     * a) use ePWM1 triggered ADC interrupt at 25 us
     * b) ADC in cascaded mode
     * c) ADC does sequential sampling
     * d) ACQ_PS = 0xf (15+1=16 hold cycles)
     * e) ADC frequency is 12.5 MHz
     * f) observe the plot
     */
    
    #include "math.h"
    #include "IQmathlib.h"
    #include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
    
    // Prototype statements for functions found within this file.
    void InitEPwmTimer(void);
    interrupt void adc_isr(void);
    
    
    // Variables used for plotting, reading from ADC and interrupt count
    Uint32 count=1;
    int plot_count = 0, sample = 0;
    float array_sine[800][2];
    float voltage_grid = 0, vg1 = 0, voltage_offset = 0, voft1 = 0;
    
    main()
    {
        InitSysCtrl();
    //    EALLOW;
    //    SysCtrlRegs.HISPCP.all = 0x3;  // HSPCLK = SYSCLKOUT/6
    //    EDIS;
        DINT;   // disable CPU interrupts
        InitPieCtrl();  // disable all peripheral interrupts
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
        EDIS;
        InitEPwmTimer();    // initiate the required ePWM registers and configure interrupt requirements
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
        EDIS;
        IER = 0x0000;   // disables all interrupts
        IFR = 0x0000;   // clears flags of all interrupts
        InitPieVectTable();
    
    
    //************ADC INITIALISATION and CONFIGURATION BEGINS************//
        InitAdc();                               // basic ADC setup (including calibration)
        AdcRegs.ADCTRL1.all = 0;                 // clear ADCTRL1 before initializing
        AdcRegs.ADCTRL1.bit.ACQ_PS = 0xf;        // sample and hold for (15+1)=16 ADC cycles
        AdcRegs.ADCTRL1.bit.CPS = 0;             // divide further by 1
        AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        // cascaded mode for ADC (16 states)
        AdcRegs.ADCTRL1.bit.CONT_RUN = 0;        // continuous run mode for ADC disabled
    
    //    AdcRegs.ADCTRL2.all = 0;                 // clear ADCTRL2 before initializing
        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;      // enable interrupt on SEQ1
        AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;    // enable interrupt every end of sequence
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;        // reset SEQ1
        AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;        // start SEQ1 from ePWM1_SOCA trigger
    
    
        AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;       // sequential simultaneous conversion for ADC
        AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;        // 3 because HSPCLK for ADC is 75 Mhz (150/6); see above
                                                     // from DSP2833x_SysCtrl.c FCLK for ADC is 75 MHz and not 150 MHz;
                                                     // 75/(2*3) = 12.5 MHz
    
        AdcRegs.ADCMAXCONV.all = 0x0001;              // 2 conversions
        AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;     // assign ADCINA2 to conv00
        AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;     // assign ADCINA3 to conv01
    
    //************ADC INITIALISATION and CONFIGURATION ENDS************//
    
        EALLOW;  // This is needed to write to EALLOW protected registers
        PieVectTable.ADCINT = &adc_isr;
        EDIS;
    
        InitCpuTimers();
        ConfigCpuTimer(&CpuTimer0, 150, 25); // generate TINT0 at 25 us or 40 kHz
    //    CpuTimer0Regs.TCR.all = 0x4001;       // disable cpu timer0 interrupt (not needed)
    
    
       IER |= 1; // Enable all of INT1 group
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;   // enable ADC INT (6th interrupt in group 1)
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
    
    
    }
    
    void InitEPwmTimer(void)
    {
        EALLOW;
        GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
        GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B active
        EDIS;
    
    
    //      ePWM 1 module clock sync disabled
    
    //      ePWM1 TBCTL INITIALISATIONS
        EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;     // free run
        EPwm1Regs.TBCTL.bit.PHSDIR = 1;         // count up after sync
        EPwm1Regs.TBCTL.bit.CLKDIV = 0;         // TBCLK = HSPCLK/1
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;      // HSPCLK = SYSCLK/2
        EPwm1Regs.TBCTL.bit.SWFSYNC = 0;        // software sync disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.PRDLD = 0;          // load on CTR = 0
        EPwm1Regs.TBCTL.bit.PHSEN = 0;          // phase enable disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.CTRMODE = 0;        // count in up-mode
    
    //      ePWM1 ETPS INITIALISATIONS
        EPwm1Regs.ETPS.bit.SOCBCNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCBPRD = 0;         // disabled because interrupt is to be generated by ePWM1A
        EPwm1Regs.ETPS.bit.SOCACNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;         // interrupt is to be generated by ePWM1A every time
        EPwm1Regs.ETPS.bit.INTCNT = 0;          // read only bit doesn't matter
        EPwm1Regs.ETPS.bit.INTPRD = 1;          // generate interrupt every event
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.ETSEL.bit.SOCBEN = 0;         // disable SOCB
        EPwm1Regs.ETSEL.bit.SOCBSEL = 0;        // because SOCB is disabled
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;         // enable SOCA
        EPwm1Regs.ETSEL.bit.SOCASEL = 1;        // generate interrupt when CTR = 0
        EPwm1Regs.ETSEL.bit.INTEN = 0;          // disable PWM interrupt
        EPwm1Regs.ETSEL.bit.INTSEL = 0;         // doesn't matter as PWM interrupt is disabled
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.TBPRD = 1875;                 // fpwm = 40 khz = finterrupt
    }
    
    interrupt void adc_isr(void)
    {
        count++;                                    // check if interrupt is being generated
        voltage_grid = AdcMirror.ADCRESULT0;       // read from ADC
        voltage_offset = AdcMirror.ADCRESULT1;     // read from ADC
        vg1 = voltage_grid*3/4095;                  // get original value
        voft1 = voltage_offset*3/4095;              // get original value
    
            if (plot_count <800)
            {
                if (sample > 799)
                sample = 0;
            array_sine[sample][0] = vg1;        // to collect and plot first 800 samples of grid voltage
            array_sine[sample][1] = voft1;          // the second 800 samples are zero during this time
            sample++;
            plot_count++;
            }
            if ((plot_count > 799) && (plot_count<1600))
            {
                if (sample > 799)
                    sample = 0;
                array_sine[sample][0] = voft1;        // the first 800 samples are zero during this time
                array_sine[sample][1] = vg1;          // to collect the second 800 samples of grid voltage
                        sample++;
                        plot_count++;
            }
            if (plot_count == 1600)
                plot_count = 0;
    
      // Reinitialize for next ADC sequence
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    }
    
    //===========================================================================
    // End of SourceCode.
    //===========================================================================

    谨致问候,

    安杰特

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

    Matthew,您好!  

    以下是显示Ankit所述中断的图形。

    我希望这能有所帮助。

    此致,

    马文

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

    Ankit,

    对于数据实验,在获取第二个800时,是否可能保留第一个800 vg1值的数组(即不使用voft1覆盖它)。  然后,我会在所有1600个样本采集完毕后,再设置一个断点。

    此时,您只需打开一个监视窗口,查看array_sine[780-799][0]和array_sine[800-819][1],查看数组中的值/重叠是否相同。  根据图像,我认为图形的某些方面使它看起来存在不连续性,而实际上并不存在。  查看原始数据将有助于证明/否定这一点。

    最佳,

    Matthew

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

    您好,Pate先生,

    按照要求,我已使用您提到的断点技术提取了数组数据。 代码如下所示:

    #include "math.h"
    #include "IQmathlib.h"
    #include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
    
    // Prototype statements for functions found within this file.
    void InitEPwmTimer(void);
    interrupt void adc_isr(void);
    
    
    // Variables used for plotting, reading from ADC and interrupt count
    Uint32 count=1;
    int plot_count = 0, sample = 0;
    float array_sine[800][2];
    float voltage_grid = 0, vg1 = 0, voltage_offset = 0, voft1 = 0;
    
    main()
    {
        InitSysCtrl();
    //    EALLOW;
    //    SysCtrlRegs.HISPCP.all = 0x3;  // HSPCLK = SYSCLKOUT/6
    //    EDIS;
        DINT;   // disable CPU interrupts
        InitPieCtrl();  // disable all peripheral interrupts
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
        EDIS;
        InitEPwmTimer();    // initiate the required ePWM registers and configure interrupt requirements
        EALLOW;
        SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
        EDIS;
        IER = 0x0000;   // disables all interrupts
        IFR = 0x0000;   // clears flags of all interrupts
        InitPieVectTable();
    
    
    //************ADC INITIALISATION and CONFIGURATION BEGINS************//
        InitAdc();                               // basic ADC setup (including calibration)
        AdcRegs.ADCTRL1.all = 0;                 // clear ADCTRL1 before initializing
        AdcRegs.ADCTRL1.bit.ACQ_PS = 0xf;        // sample and hold for (15+1)=16 ADC cycles
        AdcRegs.ADCTRL1.bit.CPS = 0;             // divide further by 1
        AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        // cascaded mode for ADC (16 states)
        AdcRegs.ADCTRL1.bit.CONT_RUN = 0;        // continuous run mode for ADC disabled
    
    //    AdcRegs.ADCTRL2.all = 0;                 // clear ADCTRL2 before initializing
        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;      // enable interrupt on SEQ1
        AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;    // enable interrupt every end of sequence
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;        // reset SEQ1
        AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;        // start SEQ1 from ePWM1_SOCA trigger
    
    
        AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;       // sequential simultaneous conversion for ADC
        AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;        // 3 because HSPCLK for ADC is 75 Mhz (150/6); see above
                                                     // from DSP2833x_SysCtrl.c FCLK for ADC is 75 MHz and not 150 MHz;
                                                     // 75/(2*3) = 12.5 MHz
    
        AdcRegs.ADCMAXCONV.all = 0x0001;              // 2 conversions
        AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;     // assign ADCINA2 to conv00
        AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;     // assign ADCINA3 to conv01
    
    //************ADC INITIALISATION and CONFIGURATION ENDS************//
    
        for (sample = 0; sample < 800; sample++)
        {
            array_sine[sample][0]=0;
            array_sine[sample][1]=0;
        }
        sample = 0;
    
    
        EALLOW;  // This is needed to write to EALLOW protected registers
        PieVectTable.ADCINT = &adc_isr;
        EDIS;
    
        InitCpuTimers();
        ConfigCpuTimer(&CpuTimer0, 150, 25); // generate TINT0 at 25 us or 40 kHz
    //    CpuTimer0Regs.TCR.all = 0x4001;       // disable cpu timer0 interrupt (not needed)
    
    
       IER |= 1; // Enable all of INT1 group
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;   // enable ADC INT (6th interrupt in group 1)
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
    
    
    }
    
    void InitEPwmTimer(void)
    {
        EALLOW;
        GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // ePWM1A active
        GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // ePWM1B active
        EDIS;
    
    
    //      ePWM 1 module clock sync disabled
    
    //      ePWM1 TBCTL INITIALISATIONS
        EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;     // free run
        EPwm1Regs.TBCTL.bit.PHSDIR = 1;         // count up after sync
        EPwm1Regs.TBCTL.bit.CLKDIV = 0;         // TBCLK = HSPCLK/1
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;      // HSPCLK = SYSCLK/2
        EPwm1Regs.TBCTL.bit.SWFSYNC = 0;        // software sync disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.PRDLD = 0;          // load on CTR = 0
        EPwm1Regs.TBCTL.bit.PHSEN = 0;          // phase enable disabled
        EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;       // disable sync
        EPwm1Regs.TBCTL.bit.CTRMODE = 0;        // count in up-mode
    
    //      ePWM1 ETPS INITIALISATIONS
        EPwm1Regs.ETPS.bit.SOCBCNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCBPRD = 0;         // disabled because interrupt is to be generated by ePWM1A
        EPwm1Regs.ETPS.bit.SOCACNT = 0;         // this is a read only bit
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;         // interrupt is to be generated by ePWM1A every time
        EPwm1Regs.ETPS.bit.INTCNT = 0;          // read only bit doesn't matter
        EPwm1Regs.ETPS.bit.INTPRD = 1;          // generate interrupt every event
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.ETSEL.bit.SOCBEN = 0;         // disable SOCB
        EPwm1Regs.ETSEL.bit.SOCBSEL = 0;        // because SOCB is disabled
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;         // enable SOCA
        EPwm1Regs.ETSEL.bit.SOCASEL = 1;        // generate interrupt when CTR = 0
        EPwm1Regs.ETSEL.bit.INTEN = 0;          // disable PWM interrupt
        EPwm1Regs.ETSEL.bit.INTSEL = 0;         // doesn't matter as PWM interrupt is disabled
    
    //      ePWM1 ETSEL INITIALISATIONS
        EPwm1Regs.TBPRD = 1875;                 // fpwm = 40 khz = finterrupt
    }
    
    interrupt void adc_isr(void)
    {
        count++;                                    // check if interrupt is being generated
        voltage_grid = AdcMirror.ADCRESULT0;       // read from ADC
        voltage_offset = AdcMirror.ADCRESULT1;     // read from ADC
        vg1 = voltage_grid*3/4095;                  // get original value
        voft1 = voltage_offset*3/4095;              // get original value
    
        if (plot_count <800)
            {
                if (sample > 799)
                    sample = 0;
                array_sine[sample][0] = vg1;        // to collect and plot first 800 samples of grid voltage
                array_sine[sample][1] = array_sine[sample][1];          // the second 800 samples remain unchanged
                sample++;
            }
        if ((plot_count > 799) && (plot_count<1600))
            {
                if (sample > 799)
                    sample = 0;
                array_sine[sample][0] = array_sine[sample][0];        // the first 800 samples remain unchanged
                array_sine[sample][1] = vg1;          // to collect the second 800 samples of grid voltage
                sample++;
            }
        plot_count++;
        if (plot_count == 1600)
            plot_count = 0;
    
    // Reinitialize for next ADC sequence
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
        AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    }
    
    //===========================================================================
    // End of SourceCode.
    //===========================================================================

    我无法从数据集得出任何结论,但是我请求Marvin将该Excel文件上载到此处或通过电子邮件直接发送给您。 还有一个E2E线程,其中有 一个由tlee编写的句子 ,如下所示:

    图形的连续刷新不能保证与循环缓冲区更新同步,因此您可以在图中看到偶尔出现的“故障”。

    此E2E线程的链接如下所示:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/805741/ccs-tms320f28335-error-adc-sampling</s>2000 200080.5741万2.8335万

    我将截取整个回复的屏幕截图,并与Marvin分享,以便他可以将其发布在此处。

    谨致问候,

    安杰特

    Vit,Vellore,India

    PS:不连续性仍然存在于图形中,不幸的是,它正在耗费我们所有人的大量时间。

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

    Matthew,您好!

    下面是Ankit提到的主题的屏幕截图以及Excel文件。 请参阅以下附件:

    e2e.ti.com/.../dataset.xlsx

    我希望这能有所帮助。

    此致,

    马文

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

    Ankit,

    感谢您采集数据,我们发现数据不会中断,即从第1个数据集的799转换到第2个数据集的第1个数据集仍然显示数据在减少,而不是峰值返回到先前的值。  

    这是由于CCS中的图形功能导致的,您已经找到了一个先前的帖子,它暗示这也是一个问题。

    虽然图形不理想,但基础数据是好的,即对数据进行的任何数学运算也将是好的。  

    我的观点是,我们可以忽略图形的不连续性,因为我们知道C2000收集的数据是好的/正确的。  图表中是否有其他方面会给您带来问题?

    最佳,

    Matthew

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

    您好,Pate先生,

    首先,请接受我的道歉,因为我忙于其他与我的研究相关的活动,没有时间尽快回复。

    我自己做了几次实验来澄清这个问题,幸运的是,我找到了这个问题的解决办法,它真的很简单。 解决方案如下:

    假设存储栅格电压的矢量长度为800个样本。 在这种情况下,用户一次只能绘制800个样本。 如果用户绘制的图解超过矢量(本例中假设为800),则不连续将出现在每个矢量长度的末尾(或在此方案中每800个样本之后)。  当输入信号持续时, 不能保证接下来的800个样本将与之前的800个样本完全相同,并且图形需要自己的时间在每次迭代时获取新鲜数据,从而导致额外的延迟,这进一步导致了此故障。 因此,在800样本当前矢量长度的图形属性中,这两个参数(采集缓冲区大小和显示数据大小)都应保持为800,以查看无信号干扰。 用户应在同一矢量中存储尽可能多的周期,以获得更好的可见性。

    此外,要查看同一矢量中输入信号的多个周期,应存储较少的样本数。 假设输入信号频率为50 Hz,从ADC读取数据的速率为40 kHz。 这意味着在输入信号的一个周期中读取800个值,并给出800向量长度。 如果用户存储每一个备用样本,那么在给定的800大小数组中,可以同时查看输入的2个周期。 如果用户每存储第四个样本,则可以同时查看4个周期,依此类推。

    由于问题不再存在,您现在可以关闭此线程。 如果你同意我的解释,你可以投票赞成我的答复,作为建议的答复。

    非常感谢每次帮助我,也非常抱歉让这个线程打开超过一个月。

    非常感谢Marvin Gasis Arcangel以 闪电般的速度代表我发布了相关图片。

    谨致问候,

    安杰特

    Vit,Vellore,India