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万:技术问题

Guru**** 2582405 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1086637/tmdsprex28335-technical-issues

部件号:TMDSPREX2.8335万
主题中讨论的其他部件: C2000WARE
大家好,

由于我的客户无法在论坛上发帖,我为他提交了一个问题。

"我正在使用TMDSPREX2.8335万板,我正在尝试转储两个信号:
1)外部50 Hz正弦信号,范围在1伏和2伏之间
2) 1 V直流信号

正确转换信号后,我尝试在同一图形窗口中观察外部交流信号和内部产生的单位振幅50 Hz正弦波。 我在图形窗口中查看外部转储50 Hz信号时发现两个异常。 这些建议如下:

a)频率远高于50 Hz
b)数据未正确记录,且所获得的图解中存在突然中断

我用于ADC初始化,正弦波生成和绘制数据的代码如下所示:

//本示例中使用的全局变量
UINT32 EPwm3TimerIntCount,EPwm5TimerIntCount,CpuTimer0IntCount = 1;
浮子占空比= 0.405 ,omega = 2* 3.1415926535 *50,ref_sine = 0,时间= 0,ref_sine_offset = 0, wt = 0,wt_offset = 0;
float ref_sin弦_n = 0,ref_sine_offset_n = 0;
float voltage_grid = 0,voltage_pv = 0,current_grid = 0,current_pv = 0,volte_offset = 0;

//用于绘图的变量
Int plot_count = 0,样本= 0;
float array_sine[400][2],array_sine_offset[400];
Void主(void)

InitSysCtrl();
dint;//禁用CPU中断
InitPieCtrl();//禁用所有外围设备中断
InitEPwmTimer();//启动所需的ePWM寄存器并配置中断要求
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.con_run =1;// ADC的连续运行模式
ADcRegs.ADCTRL1.bit.SEQ_CASC=1;// ADC的级联模式(16状态)


AdcRegs.ADCTRL2.ALL =0;//初始化前清除ADCTRL2
AdcRegs.ADCTRL2.bit.so_SEQ1 = 1;//启动SEQ1
// AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;//重置SEQ2
// AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//在SEQ1上启用中断

ADcRegs.ADCTRL3.bit.SMODE_SEL = 0;// ADC的连续同步转换
AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;// 3,因为ADC的DSP2833x_sysctrl.c 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 = 0xA;//将ADCINB2分配给conv01
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;//将ADCINA3分配给conv02
// AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 11;//将ADCINB3分配给conv03
// AdcRegs.ADCCHSELSEQ2.bit.CONV04 =4;//将ADCINA4分配给conv04
//************** ADC初始化和配置结束************ //




EALLOW;//这是写入EALLOW保护寄存器所必需的
PieVectorTable.TINT0 =&CPU_timer0_ISR;
PieVectorTable.EPWM3_INT =&epwm3/timer_isr;
PieVectorTable.EPWM5_INT =&epwm5_TIMER_ISR;
EDIS;

ConfigCpuTimer(&CpuTimer0150,25);//以25 us或40 kHz的频率生成TINT0
CpuTimer0Regs.tcr.all = 0x4000;


//初始化计数器:
EPwm3TimerIntCount = 1;
EPwm5TimerIntCount = 1;

IER |=1;//启用timer0中断
IER |=4;//为ePWM3和ePWM5启用INT3
/*启用TINT0
//在PIE中启用EPWM3A INT:组3中断3
//在PIE中启用EPWM5A INT:组3中断5
*/
PieCtrlRegs.PIEIER1.bit.INTx7=1;
PieCtrlRegs.PIEIER3.bit.INTx3=1;
PieCtrlRegs.PIEIER3.bit.INTx5=1;

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

}
中断无效CPU_TIMER0_ISR(void)

CpuTimer0IntCount++;

//********************** 从ADC读取值开始于********************** //
volt_grid = AdcRegs.ADCRESULT0>4;//从ADCINA2读取网格电压到ADCResult2寄存器的volt_grid
current_grid = AdcRegs.ADCRESULT1>>4;//从ADCINB2读取网格电流到ADCResult3寄存器中的current_grid
// voltage_PV = AdcRegs.ADCRESULT6>>4;//从ADCINA3读取PV电压到ADCResult6寄存器中的volt_PV
// current_PV = AdcRegs.ADCRESULT7>4;//从ADCINB3读取PV电流到ADCResult7寄存器的current_PV
// volte_offset = AdcRegs.ADCRESULT8>4;//从ADCINA4读取参考电压到ADCResult8寄存器的volt_offset
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//清除SEQ1生成的中断
//********************** 读取ADC的值********************** //

IF (时间> 0.02)
时间=0;
wt = omega*time;
wt_offset = omega*(Time - 0.0001);//第二个正弦波的偏移量为100微秒
ref_sine = fabs (sin (wt));
ref_sine_n = sin (wt);
ref_sine_offset = fabs (sin (wt_offset));
ref_sine_offset_n = sin (wt_offset);

如果(plot_count == 0)

IF (样本> 399)
样本= 0;
array_sine[sample][0]= voltage_grid/1000;
array_sine[sample][1]= ref_sine_n;
array_sine_offset[sample]= ref_sine_offset_n;
示例++;
plot_count = 2;
}
图解计数--;
时间=时间+ 0.0.0025万 ;
PieCtrlRegs.PIEACG.ALL = PIEACK_GROUP1;
}

有关的图解如下:


您可以看到数据没有正确记录,并且与内部正弦相比,从ADC获得的正弦至少要快5倍。"

非常感谢你的帮助。

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

    我认为问题在于ADC样本的时基设置不正确。  您已经设置了con_run位,它将强制ADC在执行第一个AdcRegs.ADCTRL2.bit.so_SEQ1 =1;//执行指令时启动SEQ1后连续采样。

    使用ADC 时钟=12.5MHz和ACQPS =16的寄存器设置,这相当于每293ns或3.409MSPS进行持续采样。  

    如果您禁用con_run,则上述SW写入每次都会触发新样本,可能是您指定的计时器速率为25us。  如果您使用CPU计时器来控制SOC,则将SOC绑定到PWM可能更具确定性,该PWM在您要采样的相同时基上自由运行。  这样,您就不会面临任何CPU事件更改采样率计时的风险。

    此处显示的示例将提供SOC PWM控制的寄存器设置

    C:\ti\c2000Ware_4_01_00_00\device_support\F2833x\examples\ADC_SoC</s>2833

    该目录中还有一些其他示例,可以帮助您使用DMA来捕获数据。

    最佳,

    Matthew

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

    尊敬的Matthew和Zhonghui:

    首先,我要感谢你们两位。 我很感谢中辉代表我发布此查询,感谢Matthew如此迅速,友好的回复。

    在你的回答中,Matthew,你提到了

    1. a) Con_run = 1可能是出现此问题的原因。

    我对这项关注的答复如下:

    即使con_run为1,在清除SEQ1中断标志之前,不能(或者不应该)进行任何进一步的转换。 根据我的理解,这应该转化为每25个我们就只有一组转换。

    即使我们假设正在进行同步/连续转换,每20毫秒应该只有一个最大值和一个最小值,因为外部信号是50 Hz正弦波。 连续转换应意味着可以获得更多的转换样本,这实际上会提高所获得的图解的精度,而不会违反转储信号的基本属性。 但正如我之前提供的图像中所显示的,转换后的信号的频率远超过50 Hz,而且具有多种不连续(这是我问题的第二部分,但仍未得到解答)。

    如何违反基本原理,获得的频率与原始频率完全不同?

    或者,我是否应该通过低通滤波器传递转换后的信号(在软件中;在ADC之前,硬件中已有RC (R = 120欧姆,C = 0.33 UF) LPF),然后再将其记录到图形窗口中?

    1. B)由于ADC时钟为12.5 MHz,ACQPS为16,因此转换频率为3.409 MSPS (或每293 ns一个采样)。

    因为我不能弄清楚这些数字背后的数学原理,你会不会很友好地向我解释这些数字?

    问题是,根据我的PWM系统和我的要求,软件中断是我唯一可能使用的中断。 为了提高记录精度,我将它与CPU计时器中断一起使用。

    我将使用CONT_RUN=0重新运行代码,在CPU中断中,SEQ1每25 Us重置一次,并在明天发布全新映像。 但是,在那之前,请你看看我根据我的理解在辩护中提出的反驳意见。

     

    提前非常感谢,并保持手指交叉以获得永久补救。

     

    谨致问候,

    安杰特

    Vit,Vellore,India

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

    Ankit,

    将在CONT_RUN =0上查找更新,设置此位将取代SEQ1中断标志行为,这通常会暂停转换器,直到标志清除。

    最佳,

    Matthew

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

    尊敬的Matthew和Zhonghui:

     

    我很抱歉在超过48小时的时间内回复了你们两位。 我正忙于在不同条件下测试ADC。

     

    Matthew,

    根据您的解释,我现在了解了将位con_run设置为1的后果。 我衷心感谢您提供的见解。 非常感谢。

    我当然不会质疑/争论/怀疑有数十年关于C2000控制器的经验和知识的人,因为这些控制器中的每一个都是知识海洋。 从第一天到现在,向这些C2000处理器所涉及/关联的每一位灵魂致敬。

    但是,我可以自己调试代码,运行ADC,并且使用以下设置运行ADC:

    con_run = 1;(根据您的情况,这应该是con_run = 0;)

    级联状态(16状态)

    顺序采样(通道A后跟通道B)

    ACQ_PS = 0xF;(15+1=16 ADC周期保持)

    SOC_SEQ1与CpuTimer0中断相连,每25 us (40 kHz)中断一次

     

    出现该问题是因为我在ADC初始化中未包括以下行:

    InitCpuTimers();

    之前

    ConfigCpuTImer(&CpuTimer0, 150,25);

    不包括InitCpuTImers是我的代码中的错误。 现在ADC正在按我的预期工作。

    我最后有一个问题。 您能否解释一下,由于ADC时钟为12.5 MHz,ACQPS为16,因此转换频率是3.409 MSPS (或每293 ns一个采样)?

     

    谨致问候,

    安杰特

    Vit,Vellore,India

     

    PS:我也会尝试使用ePWM中断的ADCSoC。

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

    Ankit,

    感谢您的更新,无需道歉,这就是为什么我们有E2E论坛来为客户提供帮助的原因。 :)

    重做这些数字后,我意识到我犯了一个错误,如果ACQPS =16 ADC时钟,这就会将采样时间限制为1.28us或781.25kSPS,而不转换样本!

    对于采样率计算,下面是 449页上设备TRM的表格。

    我从表的第5列中取出它,ADC时钟=12.5MHz

    采集时间设置为ACQPS=15,因此变为(15+1)*(1/12.5MHz)= 1.28us。  因此,每次我们对ADC输入引脚进行采样时,我们将在转换值之前保持采样/保持盖关闭1.28us。

    以下是根据此特定转换器的拓扑而引起关注的地方。

    S/H相位完成后的第一个示例需要4个ADC时钟周期才能完成

    因此,对于单个样品,我们的样品为1.28us,而4*(1/12.5MHz)= 320ns或1.28us+320ns = 1.6us总数。  

    如果每个触发器仅采样一个通道(您将执行此操作,con_run = 0),则以上仅为从触发到样品准备就绪的延迟,您的"采样率"实际上定义为您的触发率(从CPU计时器或其他方式)。

    但是,在CONT_RUN=1的情况下,ADC将尽快开始新的转换,这是在前一转换后的2个ADC时钟周期之后(我们在此充分利用ADC体系结构,而不是等待4ADC时钟进行完全转换)。  因此,在上述情况下,采集时间为1.28us + 2*(1/12.5MHz)=160ns或1.28us+160ns =1.44us或1/1.44us =694.44kSPS,这是我认为您在CONT_RUN=1中所获得的结果。

    希望这能让事情得到改善。

    最佳,

    Matthew

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

    尊敬的Matthew:

    非常感谢如此详细的解释。
    到目前为止,您已经详细回答了我有关ADC配置的所有问题。

    您现在可以关闭此线程。

    谨致问候,
    安杰特

    Vit,Vellore,India