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:使用 CPU_timer0触发 ADC

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/638901/ccs-tms320f28379d-adc-triggering-using-cpu_timer0

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

大家好、

      这是圣阿斯。 我对 TI 微控制器系列比较陌生。 我正在使用来自信号发生器的不同模拟信号进行 ADC 转换。 有人能不能帮助我使用 CPU_timer0触发 ADC 转换。 控制套件中是否提供任何示例代码。 如果没有、有人可以帮助我处理使用 CPU 计时器而不是使用 ePWM 触发 ADC 的示例代码。

谢谢你。

此致、

圣雷迪

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

    您好、Saintath、

    是否有理由使用 CPU 计时器来触发 ADC 而不是 ePWM? 使用 ePWM 是更常见的做法、与使用 CPU 计时器相比、它具有一些优势。

    C2000ware 中没有使用 CPU 计时器触发 ADC 的示例程序、但有 ePWM、如果您真的需要、可以更改该程序以使用 CPU 计时器。

    C:\ti\c2000Ware_1_00_02_00\device_support\f2837xd\examples\cpu1\adc_soc_ePWM

    此外、TRM 第1397页上的代码段应该能帮助您: http://www.ti.com/lit/spruhm8

    最棒的
    Kevin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Kevin:
    非常感谢您的回复。 我正在使用计时器、因为我可能需要 PWM 用于其他一些应用。 我已经尝试将 ADC ePWM 代码修改为计时器。 代码未显示错误、但 ADC 无法读取值。

    我已随附以下代码。 您能否检查代码中是否存在任何缺陷。
    谢谢你。

    此致、

    圣雷迪




    //! 监控 GPIO34 LED 闪烁(持续500毫秒)和熄灭(持续500毫秒)
    //! F2837xD 控制卡。
    //!
    //
    //######################################################################################################################
    //$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);

    _interrupt void CPU_timer0_ISR (void);

    用于存储转换结果的//缓冲区
    #define results_buffer_size 256
    uint16 AdcaResults[results_buffer_size];
    uint16结果索引;
    易失性 uint16 bufferFull;
    uint16 input[results_buffer_size];
    uint16 index=0;


    void main (void)




    //初始化结果缓冲区

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

    AdcaResults[resultsIndex]=0;

    resultsIndex = 0;


    //步骤1. 初始化系统控制:
    // PLL、安全装置、启用外设时钟
    //此示例函数位于 F2837xD_SYSCTRL.c 文件中。
    //
    InitSysCtrl();

    //
    //步骤2. 初始化 GPIO:
    //此示例函数位于 F2837xD_GPIO.c 文件和中
    //说明了如何将 GPIO 设置为其默认状态。
    //
    // InitGpio();//针对此示例跳过

    //
    //步骤3. 清除所有_interrupts 并初始化 PIE 矢量表:
    //
    Dint;

    //
    //将 PIE 控制寄存器初始化为默认状态。
    //默认状态为禁用所有 PIE __interrupts 和标志
    //被清除。
    //此函数位于 F2837xD_PIECTRL.c 文件中。
    //
    InitPieCtrl();

    //
    //禁用 CPU __interrupts 并清除所有 CPU __interrupt 标志:
    //
    IER = 0x0000;
    IFR = 0x0000;


    InitPieVectTable();


    EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
    PieVectTable.TIMER0_INT =&CPU_timer0_ISR;
    EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的


    InitCpuTimer();//对于此示例,只初始化 CPU 计时器

    //每500毫秒将 CPU 定时器0配置为_interrupt:
    // 60MHz CPU 频率,50毫秒周期(以 uSeconds 为单位)
    //
    ConfigCpuTimer (&CpuTimer0、60、50000);

    //
    //为了确保精确的时序,请使用只写指令对整个进行写操作
    //寄存器。 因此、如果中的任何配置位发生更改
    // ConfigCpuTimer 和 InitCpuTimers (在 F2837xD_cputimervars.h 中)、如下所示
    //设置也必须更新。
    //
    CpuTimer0Regs.TCR.ALL = 0x4001;

    //
    //步骤5. 特定于用户的代码、启用_interrupts:
    //将 GPIO34配置为 GPIO 输出引脚
    //
    EALLOW;
    GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
    EDIS;

    //
    //启用连接到 CPU 定时器0的 CPU INT1:
    //
    IER |= M_INT1;

    //
    //在 PIE 中启用 TINT0:组1 __interrupt 7
    //
    PieCtrlRegs.PIEIER1.bit.INTx7=1;

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

    //
    //步骤6. 空闲循环。 只需坐下来循环(可选):
    //
    for (;;);


    //
    // cpu_timer0_isr -每500ms 切换一次 GPIO32的 CPU Timer0 ISR
    //
    _interrupt void CPU_timer0_ISR (void)

    CpuTimer0.InterruptCount++;

    AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT0;

    input[index++]= AdcaResults[resultsIndex-1];

    if (results_buffer_size <= resultsIndex)

    resultsIndex = 0;
    索引=0;
    bufferFull = 1;



    GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;

    //
    //确认此__interrupt 以从组1接收更多__interrupts
    //
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;




    空配置 ADC (空)

    EALLOW;

    //写入配置
    AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
    AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_differential);

    //将脉冲位置设置为晚期
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;

    //为 ADC 加电
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    //延迟1ms 以允许 ADC 加电时间
    DELAY_US (1000);

    EDIS;


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

    圣阿斯

    在代码中,您似乎从未在 main()中调用 ConfigureADC()函数,还需要将其配置为生成 SOC (转换开始)。

    您需要与我提到的 TRM 和 ePWM 示例程序中的内容类似的内容:

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 5;//SOC0将转换 ADCINA5
    AdcaRegs.ADCOC0CTL.bit.ACQPS = 23;//SOC0将使用24个 SYSCLK 周期的采样持续时间
    AdcRegs.ADCSO0CTL.bit.TRIGSEL = 23;// SOC0将开始转换计时器3 / SOC0 

    更改上述内容以匹配您要使用的任何通道/计时器、并与 ePWM 示例进行比较以确保不需要其他内容。

    仅供参考。 F28379D 有12个 ePWM 实例。 您可以让多个 EPWM 以不同的频率/配置运行。

    最棒的

    Kevin

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

    我稍微修改了我的代码、以便使用 cpu_timer0来触发 ADC。 请找到以下代码。

    /############################################################################################################
    //文件:adc_soc_ePWM_cpu01.c
    //标题:通过 ePWM 触发 F2837xD 的 ADC。
    //
    //! addtogroup cpu01_example_list
    //! 

    ADC ePWM 触发(ADC_SoC_ePWM)

    //! //! 此示例设置 EPWM 以定期触发 ADC。 //! //! 程序运行后、内存将包含:\n //! -\b 结果:一系列来自 //的模数转换样本! 引脚 A0。 采样之间的时间根据周期 //! PWM 计时器的功能。 // //########################################################################################################################## //$TI 发行版:F2837xD 支持库 v190 $ //$发行 日期:星期一2月1日16:51:57 CST 2016 $ //版权所有:(C) 2013-2016德州仪器(TI)公司- // http://www.ti.com/ 保留所有权利$ //############################################################################################################ #include "F28x_Project.h" //器件头文件和示例包括文件 void ConfigureADC (void); void ConfigureEPWM (void); void SetupADCepwm (uint16通道); __interrupt void CPU_timer0_ISR (void); //用于存储转换结果 的缓冲区#define Results_buffer_size 256 uint16 AdcResults [results_results_results_index; uint16_index ;volatile resultsize] uint16 var = 0; 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(); InitCpuTimer();//对于本示例,只初始化 CPU 计时器 //禁用 CPU 中断并清除所有 CPU 中断标志: IER = 0x0000; IFR = 0x0000; //使用指向 shell 中断 //服务例程(ISR )的指针初始化 PIE 矢量表。 //这将填充整个表,即使在 本示例中未使用中断//也是如此。 这对于调试很有用。 //可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程 //此函数可在 F2837xD_PieVect.c 中找到 InitPieVectTable(); //Map ISR 函数 EALLOW; EDIS; //配置 ADC 并为其加电 ConfigureADC(); //配置 ePWM ConfigureEPWM (); //在通道0上设置用于 ePWM 触发转换的 ADC SetupADCepwm (0); PieVectTable.ADCA1_INT =&CPU_timer0_ISR;// ADCA 中断1 的函数 PieVectTable.TIMER2_INT =&CPU_timer0_ISR; //确保 只使用整个 寄存器的精确时序/写入指令。 因此、如果 // ConfigCpuTimer 和 InitCpuTimers (在 F2837xD_cputimervars.h 中)中的任何配置位发生更改、则还 必须更新以下//设置。 // CpuTimer2Regs.TCR.All = 0x4001; //启用全局中断和更高优先级的实时调试事件: IER |= M_INT1;//启用组1中断 EINT;//启用全局中断 INTM ERTM;//启用全局实时中断 DBGM //初始化结果缓冲区 ConfigCpuTimer (&CpuTimer0、190、22.67); //启用 PIE 中断 PieCtrlRegs.PIEIER1.bit.INTx7=1; PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //同步 ePWM EALLOW; //循环无限地进行转换 操作 { //启动 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); } //写入 ADC 配置,并为 ADC A 和 ADC B 的 ADC 加电 void ConfigureADC (void) { 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; } void ConfigureEPWM (void) { EALLOW; //假设 ePWM 时钟已启用 EPwm1Regs.ETSEL.bit.SOCAEN = 0; //禁用组上的 SOC EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在向上计数时选择 SOC EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲 EPwm1Regs.CMPA.bit.CMPA = 0x0800; //将比较 A 值设置为2048个计数 EPwm1Regs.TBPRD = 0x1000; //将周期设置为4096个计数 EPwm1Regs.TBCTL.bit.CTRMODE = 3; //冻结计数器 EDIS; } void SetupADCepwm (uint16通道) { uint16 acqps; //根据分辨率确定最小采集窗口(在 SYSCLKS 中) if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution) { acqps = 23;//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标志 } 中断 void CPU_timer0_ISR (void) { CpuTimer0.InterruptCount++; GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT0; input[index++]= AdcaResults[resultsIndex-1]; if (results_buffer_size <= resultsIndex) { resultsIndex = 0; 索引=0; } if (var=0) { VAR = 1; } 其他 { VAR = 0; } AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志 PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; }




    我现在面临的问题是 ADC 输出值显示正确、但不是以我配置 CPU_timer0的速率显示。 您能否检查代码中是否需要更改任何内容以使计时器周期正确。 (为了更加精确、CPU_TIMER 已设置为44.1kHz、即22.67uS)。

    谢谢你。

    此致、

    圣雷迪

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

    您好、Saintath、

    如果您尝试使用 CPU 定时器触发 ADC、则看起来您的 TRIGSEL 寄存器是为 EPWM1设置的。

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

    对于 CPU1定时器0、该值应为 AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1。

    我看到的另一件事是、您为以190MHz 运行的器件配置了 CPU 计时器。

    // ConfigCpuTimer -此函数将所选计时器初始化为周期
    // 由"Freq"和"Period"参数指定。 "Freq"
    // 输入为"MHz"、周期以"uSeconds "为单位。 计时器
    // 在配置后保持在已停止状态。
    
    ConfigCpuTimer (&CpuTimer0、190、22.67); 

    您是否以190MHz 而非最大200MHz 运行器件? 只是需要检查的东西、如果是、可能需要将中间参数更改为200。

    希望这对您有所帮助、

    Kevin