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/TMS320F28379D:CCS

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/665140/ccs-tms320f28379d-ccs

器件型号:TMS320F28379D

工具/软件:Code Composer Studio

大家好、

       这是圣阿斯。 目前、我正在使用 TI DSP 实施相关算法。 我正在尝试标准化 ADC 输出、然后 使用函数实现我的相关性。 我在下面附上了我的代码。 我面临的问题是、当我加入交叉相关 函数时、采样率会自动降低。 实际上、我已将 ADC 配置 为44.1kHz 的采样率。 当我包含相关函数时、采样率变为5kHz。 有人能帮我解决 这个问题吗?  请找到下面随附的代码。 请注意,我的代码中相关函数的名称是 corr()

//######################################################################################################################
//
//文件: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);

float corr();

//
//定义
//

#define results_buffer_size 256

//
//全局
//

uint16 AdcaResults[results_buffer_size];

uint16结果索引;

易失性 uint16 bufferFull;

int bufferIndex = 0;

float normalized_array[results_buffer_size]={0};

浮动过滤器[400]={0.0163、0.0069、0101、083、0088、0109、0.0165、0.024、0.0091、094、0.0081、0114、000、000、000、0150、340、039、039、039、039、039、070、078、078、078、078、078、078、080、080、080、080、078、080、080、080、080、080、039、080、080、080、039、080、080、080、039、080、080、080、039、080、080、080、080、

浮点结果[256]={0};

浮点校正()

float out = 0;

int i = 0;

int 索引= 0;

对于(I = 0;I < 256;I++)


索引=((i +结果索引+ 1)% 256);

OUT = OUT +(归一化_array[index-1]* filter[i]);

退换货;

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的函数

EDIS;

//
//配置 ADC 并为其加电
//
ConfigureADC();

//
//配置 ePWM
//

ConfigureEPWM();

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

SetupADCepwm (0);

//
//启用全局中断和更高优先级的实时调试事件:
//
IER |= M_INT1;//启用组1中断

EINT;//启用全局中断 INTM

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

//
//初始化结果缓冲区
//
for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)

AdcaResults[resultsIndex]=0;

resultsIndex = 0;

bufferIndex = 0;

bufferFull = 0;

//
//启用 PIE 中断
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

//
//同步 ePWM
//

EALLOW;

CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;

//
//循环无限地进行转换
//
操作


//
//启动 ePWM
//

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

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

//
//等待、而 ePWM 导致 ADC 转换、然后导致中断、
//填充结果缓冲区,最终设置 bufferFull
//flag
//

while (!bufferFull);

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

//
//停止 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_12位、ADC_SIGNALMODE_SINGLE);

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

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 = 142;//将比较 A 值设置为2048个计数

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

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将转换引脚 A0

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;

归一化_array[结果索引]=(2.0*AdcaResults[resultsIndex])/4095.0)-1.0;

Result[resultsIndex]=corr();

结果索引++;

bufferIndex++;

if (results_buffer_size <= resultIndex && bufferIndex <= results_buffer_size)


resultsIndex = 0;

bufferFull = 1;

bufferIndex = 0;

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

PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;


//
//文件结束
//

谢谢你。

此致、

圣雷迪

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

    如果采样频率为44.1kHz、并以200MHz 运行器件、则每个样本大约有200/0.0441 = 4535个周期来处理数据。 您可能需要对 corr()函数实际所需的周期数进行基准测试、因为它位于主 ISR 中(并确保 MCU 以可能的最大速度运行)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、

              非常感谢您的回复。 我在这里面临的唯一问题是主 ISR 中的赋值语句、即、  

    Result[resultsIndex]=corr();

    如果我只是执行函数而不 将返回值分配给数组、一切都正常。

    但是、如果将值分配给数组、则采样率将自动降低。

    您能不能帮助我解决赋值语句给代码带来了什么差异的问题。

    谢谢你。

    此致、

    圣雷迪

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

    我认为在这两种情况下、可能都值得确定指令执行所需的时间。

    您可以通过以下方法来实现此目的:
    *前后切换 GPIO,并使用示波器来测量时间(非常粗略,但很简单,提供了一个很好的焊球)
    *在相关代码之前和之后设置断点。 在 CCS 的 Run->Clock 菜单中启用时钟。 观察断点之间的时间。
    *或参阅 processors.wiki.ti.com/.../Profiling_on_C28x_Targets

    您还可以查看反汇编以查看在未进行分配时是否调用该函数;可能是编译器看到您未使用结果、并且在这种情况下足够智能、可以完全跳过调用。