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.

[参考译文] TMS320F28379D:当我尝试在 ADCSOC 转换中使用另一个 ADC 转换时、根本不调用 ADC ISR

Guru**** 2522770 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/794933/tms320f28379d-adc-isr-is-not-at-all-called-when-i-am-trying-to-use-another-adc-conversion-on-adcsoc-conversion

器件型号:TMS320F28379D

大家好、

我正在使用 ADC SOC ePWM 示例、我正在尝试再使用一个模拟引脚并将模拟读数转换为 Digial。  

我的代码如下所示:

//######################################################################################################################
//
//文件: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 支持库 v3.05.00.00 $
//$Release Date:Thu OCT 18 15:48:42 CDT 2018 $
//版权所有:
//版权所有(C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
//重新分发源代码必须保留上述版权
//注意、此条件列表和以下免责声明。
//
//二进制形式的重新分发必须复制上述版权
//注意、中的条件列表和以下免责声明
//随提供的文档和/或其他材料
//分布。
//
//德州仪器公司的名称和的名称都不是
//其贡献者可用于认可或推广衍生产品
//未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//$
//######################################################################################################################

//
//包含的文件
//
#include "F28x_Project.h"

//
//函数原型
//
void ConfigureADC (void);
void ConfigureEPWM (void);
void SetupADCepwm (uint16通道);
中断 void adca1_ISR (void);
中断 void adca2_ISR (void);

//
//定义
//
#define results_buffer_size 256

//
//全局
//
uint16 AdcaResults[results_buffer_size];
uint16结果索引;
易失性 uint16 bufferFull;

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.ADCA2_INT =&adca2_ISR;//针对 ADCA 中断2的函数
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;
bufferFull = 0;

//
//启用 PIE 中断
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
PieCtrlRegs.PIEIER1.bit.INTx2 = 1;
//
//同步 ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;

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

//
//启动 ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用 SOCA
EPwm2Regs.ETSEL.bit.SOCAEN = 1;//启用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 0;//取消冻结、并进入递增计数模式
EPwm2Regs.TBCTL.bit.CTRMODE = 0;//取消冻结、并进入递增计数模式


//
//等待、而 ePWM 导致 ADC 转换、然后导致中断、
//填充结果缓冲区,最终设置 bufferFull
//flag
//
while (!bufferFull);
bufferFull = 0;//清除缓冲区已满标志

//
//停止 ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器

EPwm2Regs.ETSEL.bit.SOCAEN = 0;//禁用 SOCA
EPwm2Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器


//
//此时,AdcaResults[]包含一系列转换
//从所选通道
//

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

} while (1);
asm (" ESTOP0");

//
// 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
EPwm2Regs.ETSEL.bit.SOCAEN = 0;//禁用组上的 SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4;//在递增计数时选择 SOC
EPwm2Regs.ETSEL.bit.SOCASEL = 4;//在递增计数时选择 SOC
EPwm1Regs.ETPS.bit.SOCAPRD = 1;//在发生第一个事件时生成脉冲
EPwm2Regs.ETPS.bit.SOCAPRD = 1;//在发生第一个事件时生成脉冲
EPwm1Regs.CMPA.bit.CMPA = 0x0800;//将比较 A 值设置为2048个计数
EPwm2Regs.CMPA.bit.CMPA = 0x0800;//将比较 A 值设置为2048个计数
EPwm1Regs.TBPRD = 0x1000;//将周期设置为4096个计数
EPwm2Regs.TBPRD = 0x1000;//将周期设置为4096个计数
EPwm1Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器
EPwm2Regs.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.ADCSOC1CTL.bit.CHSEL = 1;//SOC0将转换引脚 A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C 上的触发
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 7;// ePWM1 SOCA/C 上的触发
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 1;// SOC1结束将设置 INT2标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT2E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除
AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;//确保 INT1标志被清除
EDIS;

//
// adca1_ISR -在 ISR 中读取 ADC 缓冲器
//
中断 void adca1_ISR (void)

AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT0;
if (results_buffer_size <= resultsIndex)

resultsIndex = 0;
bufferFull = 1;

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;

中断 void adca2_ISR (void)

AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT1;
if (results_buffer_size <= resultsIndex)

resultsIndex = 0;
bufferFull = 1;

AdcaRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;//清除 INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;

//
//文件结束
//

请告诉我是否未正确配置 ADCSOC1。

我的代码根本不会进入 adca2_ISR。

谢谢、

Akshay Godase  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    代码成功进入 adca1_ISR。
    但我在 Adac2_ISR 中看不到任何入口
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Akshay、

    我将对此进行研究、并很快回来。

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

    我们正在等待… !!

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

    您好、Akshay、

    我认为问题是由于 ADCA2 ISR 中的以下行造成的。 ADCA2 int 映射到组10。 您可以使用器件 TRM 确认相同。 由于中断没有在 ISR 中得到确认、因此您不会看到进一步的中断。

    [引用]PieCtrlRegs.PIEACK.all = PIEACK_Group1;

    谢谢

    Vasudha

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在这种情况下,我应该怎么做?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Akshay、
    按如下所示更改上述行、查看问题是否已解决。

    PieCtrlRegs.PIEACX.ALL = PIEACK_group10;

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

    抱歉 Vasudha、

    这还没有解决问题、但增加了问题。 现在、代码在第一个实例后未命中 ADC_isr1。  ADC_isr2 根本不在图片中。  

    谢谢、

    Akshay Godase

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

    您好!

    此更改需要在 ADCA2 ISR 中完成、而不是在 ADCA1 ISR 中完成。

    谢谢

    Vasudha

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

    Vasudha、您好!

    我甚至尝试过、但对我来说不起作用。 代码根本没有进入 ADC_ISr2。

    谢谢、

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

    您好、Akshay、

    您是否能够解决此问题?

    此外、您为什么需要2个中断来读取 ADC 结果。 您可以在 SOC1末尾配置单个中断、并在同一 ISR 中读取 SOC0和 SOC 1的结果。

    谢谢
    Vasudha