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.

[参考译文] TMS320F28027:ADC 中断问题

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/666197/tms320f28027-adc-interrupt-problem

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

我正在使用 GPIO6检查我的 ADCinit1是否由以下代码触发、

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#include "DSP28x_Project.h"
#include "F2802x_common/include/adc.h"
#include "F2802x_common/include/clk.h"
#include "F2802x_common/include/flash.h"
#include "F2802x_common/include/gpio.h"
#include "F2802x_common/include/PIE.h"
#include "F2802x_common/include/PLL.h"
#include "F2802x_common/include/wdog.h"
中断空 ADC_ISR (空);
int a=0;

adc_handle myAdc;
clk_handle myClk;
Flash_handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
PWM_Handle myPwm;

void main (void)

cpu_handle myCpu;
pll_handle myPll;
WDOG_Handle myWDog;


myAdc = ADC_init ((void *) ADC_base_ADDR、sizeof (ADC_Obj));
myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj));
myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj));
myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj));
myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj));
myPie = PI_init ((void *) PIE_BASE_ADDR、sizeof (PIE_Obj));
myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj));
myPwm = PWM_init ((void *) PWM_ePWM1_base_ADDR、sizeof (PWM_Obj));
myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj));

//执行基本系统初始化
WDOG_DISABLE (myWDog);
CLK_enableAdcClock (myClk);
(*Device_cal)();

//选择内部振荡器1作为时钟源
CLK_setOscSrc (myClk、CLK_OscSrc_Internal);

//将 PLL 设置为 x10 /2、这将产生50MHz = 10MHz * 10/2
PLL_setup (myPll、PLL_Multiplier_10、PLL_DivideSelect_CLKIN_BY_2);

//禁用 PIE 和所有中断
PIE_DISABLE (myPie);
PI_DisableAllInts (myPie);
CPU_disableGlobalInts (myCpu);
CPU_clearIntFlags (myCpu);

//如果从闪存运行,则只将 RAM 复制到 RAM
#ifdef _flash
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif

//设置调试矢量表并启用 PIE
PI_setDebugIntVectorTable (myPie);
PIE_ENABLE (myPie);

//在 PIE 矢量表中注册中断处理程序

PI_registerPieIntHandler (myPie、PI_GroupNumber_10、PI_SubGroupNumber_1、(intVec_t)&ADC_ISR);


//初始化 ADC
adc_enableBandGap (myAdc);
ADC_enableRefBuffers (myAdc);
ADC_POWERUP (myAdc);
ADC_ENABLE (myAdc);
ADC_setVoltRefSrc (myAdc、ADC_VoltageRefSrc_Int);

//在 PIE 中启用 ADCINT1
PIE_enableAdcInt (myPie、ADC_IntNumber_1);
//启用 CPU 中断1
CPU_enableInt (myCpu、CPU_IntNumber_10);
//启用全局中断 INTM
cpu_enableGlobalInts (myCpu);
//启用全局实时中断 DBGM
CPU_enableDebugInt (myCpu);

GPIO_setPullUp (myGpio、GPIO_Number_6、GPIO_PULLUP_Enable);
GPIO_setHigh (myGpio、GPIO_Number_6);
GPIO_setMode (myGpio、GPIO_Number_6、GPIO_6_Mode_generalpurpose);
GPIO_setDirection (myGpio、GPIO_Number_6、GPIO_Direction_Output);


ADC_setIntPulseGenMode (myAdc、ADC_IntPulseGenMode_During);
ADC_enableInt (myAdc、ADC_IntNumber_1);
ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_ClearFlag);
ADC_setIntSrc (myAdc、ADC_IntNumber_1、ADC_IntSrc_EOC0);
ADC_setSockChanNumber (myAdc、ADC_SockNumber_0、ADC_SockChanNumber_A4);
ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_SW);
ADC_setSockSampleWindow (myAdc、ADC_SockNumber_0、ADC_SockSampleWindow_7_cycles);
//启用 PWM 时钟
CLK_enablePwmClock (myClk、PWM_NUMBER_1);

//设置 PWM
PWM_enableSockpulse (myPwm);
PWM_setSockAPulseSrc (myPwm、PWM_SockPulseSrc_CounterEqualZero);
PWM_setSockAPeriod (myPwm、PWM_SockPeriod_FirstEvent);
PWM_setCmpA (myPwm、0x0080);
PWM_setPeriod (myPwm、0xFFFF);
PWM_setCounterMode (myPwm、PWM_CounterMode_Up);

//等待 ADC 中断
for (;;)

AdcRegs.ADCSOCFRC1.bit.SOC0=1;


中断空 ADC_ISR (空)

a = ADC_readResult (myAdc、ADC_ResultNumber_1);

如果(a<100)

GPIO_setLow (myGpio、GPIO_Number_6);

其他

GPIO_setHigh (myGpio、GPIO_Number_6);


//清除 ADCINT1标志为下一个 SOC 重新初始化
ADC_clearIntFlag (myAdc、ADC_IntNumber_1);
//确认 PIE 中断
PI_clearInt (myPie、PI_GroupNumber_10);

返回;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

未触发 ADC 中断。 我找不到原因。 有人可以帮帮我吗?

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

    Ashwin、
    感谢您联系 E2E、有几种方法可以让这种方法发挥作用、下面的第一种方法我认为与终端应用用例最相关:

    1) ADC 中断源未设置为 PWM、此时将生成 SOC。

    请更改  

    ADC_setSockTrigSrc ();对以下内容的函数调用(假设 ePWM1是正在使用的 PWM)

    ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_EPWM1_ADCSOCA);

    我在代码的稍后部分看到、您手动使用 SOC 强制位来触发 ADC、如有上述更改、请删除该行:

    for (;;)


    AdcRegs.ADCSOCFRC1.bit.SOC0=1;  //删除此内容

    2)将 ADC 触发源保留为 SW Force 位、在这种情况下、您无需设置 PWM。  由于已经存在 这种情况、您可能仍有一个问题、即为什么您从未获得 ADC 中断。  由于强制位于 for ()循环内部、因此它会持续执行。  这将导致无限个 ADC SOC、这将挂起、我相信您应该得到一个 ADC 中断、但不会再出现中断。  由于生成的 SOC 的频率、我认为我们进入了未定义状态、因为 ADC ISR 无法在重新启用中断之前继续清除标志。

    替代 Soln 是将 ADC 触发保持在 SW 力、但在设置强制位之间插入一些时间延迟。  另一种方法是将 ADC 中断设置为连续 模式、以便即使该标志仍然置1、也会生成中断信号、  

    ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_EOC);

    这不是我的首选、因为我认为在系统中、您不会在一个通道上连续触发 ADC 等  但它会使您的 ISR 正常工作。

     

    此致、
    Matthew

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matthew Pate 真诚地感谢解决我的问题 根据您的建议,我考虑使用 PWM 来生成源,但即使在将源触发器设置为 pwm1并删除强制中断后,也不会生成中断.... 实际上,我在这方面工作了大约两天,我已经尝试了所有可能的触发源组合,但在任何情况下都不会产生中断..... 您能不能猜到这个问题还有什么呢? 我没有检查不同的中断我只检查了 ADC 的 INT1…
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Ashwin、

    您是否也可以检查 ADCINTOVF 标志? 如果任何 ADCINTOVF 标志被置位、中断也许不能正常工作。

    Tommy
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Tommy
    我已检查、ADCINTOVF.INT1始终为0。 还有其他想法吗? :(
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Ashwin、
    您能在此处的 C2000 Ware 中尝试以下示例:C:\ti\c2000Ware_1_00_03_00\device_support\f2802x\examples\drivers\adc_soc\。 这也使用 ADC 中断、因此我希望确保这正常工作、并且我们可以从这里返回到您的代码的增量。

    Matt
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    根据您的请求使用了该示例。 除了它、我还使用 GPIO7引脚来查看中断是否发生。 但中断没有发生。 编码如下。

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    //########################################################################################################################
    //
    //文件:F2802x_examples ccsv4/adc_soc / example_F2802x_Adc.c
    //
    //标题:F2802x ADC 转换开始(SOC)示例程序。
    //
    //组: C2000
    //目标器件:TMS320F2802x
    //
    //! \addtogroup example_list
    //!

    ADC 转换开始(SOC)


    //!
    //! 中断被启用并且 ePWM1被设置为生成一个周期
    //! ADC SOC - ADCINT1。 两个通道被转换、ADCINA4和 ADCINA2。
    //!
    //! 监视变量:
    //!
    //! - Voltage1[10]-最后10个 ADCRESULT0值
    //! - Voltage2[10]-最后10个 ADCRESULT1值
    //! -转换计数-当前结果编号0-9
    //! -循环计数-空闲循环计数器
    //
    //(C)版权所有2012、Texas Instruments、Inc.
    //########################################################################################################################
    //$TI 版本:Launchpad F2802x 支持库 V100 $
    //$Release Date: Wed Jul 2510:45:39 CDT 2012 $
    //########################################################################################################################

    #include "DSP28x_Project.h" //设备头文件和示例包括文件

    #include "F2802x_common/include/adc.h"
    #include "F2802x_common/include/clk.h"
    #include "F2802x_common/include/flash.h"
    #include "F2802x_common/include/gpio.h"
    #include "F2802x_common/include/PIE.h"
    #include "F2802x_common/include/PLL.h"
    #include "F2802x_common/include/wdog.h"

    //此文件中找到的函数的原型语句。
    中断空 ADC_ISR (空);
    void ADC_Config (void);

    //此示例中使用的全局变量:
    uint16_t LoopCount;
    uint16_t 转换计数;
    uint16_t Voltage1[10];
    uint16_t Voltage2[10];

    adc_handle myAdc;
    clk_handle myClk;
    Flash_handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    PWM_Handle myPwm;

    void main (void)


    cpu_handle myCpu;
    pll_handle myPll;
    WDOG_Handle myWDog;

    //初始化此应用程序所需的所有句柄
    myAdc = ADC_init ((void *) ADC_base_ADDR、sizeof (ADC_Obj));
    myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj));
    myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj));
    myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj));
    myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj));
    myPie = PI_init ((void *) PIE_BASE_ADDR、sizeof (PIE_Obj));
    myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj));
    myPwm = PWM_init ((void *) PWM_ePWM1_base_ADDR、sizeof (PWM_Obj));
    myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj));

    //执行基本系统初始化
    WDOG_DISABLE (myWDog);
    CLK_enableAdcClock (myClk);
    (*Device_cal)();

    //选择内部振荡器1作为时钟源
    CLK_setOscSrc (myClk、CLK_OscSrc_Internal);

    //将 PLL 设置为 x10 /2、这将产生50MHz = 10MHz * 10/2
    PLL_setup (myPll、PLL_Multiplier_10、PLL_DivideSelect_CLKIN_BY_2);

    //禁用 PIE 和所有中断
    PIE_DISABLE (myPie);
    PI_DisableAllInts (myPie);
    CPU_disableGlobalInts (myCpu);
    CPU_clearIntFlags (myCpu);

    //如果从闪存运行,则只将 RAM 复制到 RAM
    #ifdef _flash
    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
    #endif

    //设置调试矢量表并启用 PIE
    PI_setDebugIntVectorTable (myPie);
    PIE_ENABLE (myPie);

    //在 PIE 矢量表中注册中断处理程序
    PI_registerPieIntHandler (myPie、PI_GroupNumber_10、PI_SubGroupNumber_1、(intVec_t)&ADC_ISR);

    //初始化 ADC
    adc_enableBandGap (myAdc);
    ADC_enableRefBuffers (myAdc);
    ADC_POWERUP (myAdc);
    ADC_ENABLE (myAdc);
    ADC_setVoltRefSrc (myAdc、ADC_VoltageRefSrc_Int);

    //在 PIE 中启用 ADCINT1
    PIE_enableAdcInt (myPie、ADC_IntNumber_1);
    //启用 CPU 中断1
    CPU_enableInt (myCpu、CPU_IntNumber_10);
    //启用全局中断 INTM
    cpu_enableGlobalInts (myCpu);
    //启用全局实时中断 DBGM
    CPU_enableDebugInt (myCpu);

    LoopCount = 0;
    ConversionCount = 0;

    //配置 ADC
    //注意:通道 ADCINA4将被双采样以解决修订版0器件勘误表中的 ADC 第一个采样问题
    ADC_setIntPulseGenMode (myAdc、ADC_IntPulseGenMode_Prior); //ADCINT1在 AdcResults 锁存后跳闸
    ADC_enableInt (myAdc、ADC_IntNumber_1); //启用 ADCINT1
    ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_ClearFlag); //禁用 ADCINT1连续模式
    ADC_setIntSrc (myAdc、ADC_IntNumber_1、ADC_IntSrc_EoC2); //设置 EOC2以触发 ADCINT1触发
    ADC_setSockChanNumber (myAdc、ADC_SockNumber_0、ADC_SockChanNumber_A4);//将 SOC0通道选择设置为 ADCINA4
    ADC_setSockChanNumber (myAdc、ADC_SockNumber_1、ADC_SockChanNumber_A4);//将 SOC1通道选择设置为 ADCINA4
    ADC_setSockChanNumber (myAdc、ADC_SockNumber_2、ADC_SockChanNumber_A2);//将 SOC2通道选择设置为 ADCINA2
    ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_EPWM1_ADCSOCA);//设置 EPWM1A 上的 SOC0启动触发器、由于轮询 SOC0先转换、然后 SOC1
    ADC_setSockTrigSrc (myAdc、ADC_SockNumber_1、ADC_SockTrigSrc_EPWM1_ADCSOCA);//设置 EPWM1A 上的 SOC1启动触发器,由于轮询 SOC0先转换,然后 SOC1
    ADC_setSockTrigSrc (myAdc、ADC_SockNumber_2、ADC_SockTrigSrc_EPWM1_ADCSOCA);//设置 SOC2在 EPWM1A 上启动触发、因为轮询 SOC0先转换 SOC1、然后转换 SOC2
    ADC_setSockSampleWindow (myAdc、ADC_SockNumber_0、ADC_SockSampleWindow_7_cycles);//将 SOC0 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
    ADC_setSockSampleWindow (myAdc、ADC_SockNumber_1、ADC_SockSampleWindow_7_cycles);//将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
    ADC_setSockSampleWindow (myAdc、ADC_SockNumber_2、ADC_SockSampleWindow_7_cycles);//将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)

    //启用 PWM 时钟
    CLK_enablePwmClock (myClk、PWM_NUMBER_1);

    //设置 PWM
    PWM_enableSockpulse (myPwm); //在组上启用 SOC
    PWM_setSockAPulseSrc (myPwm、PWM_SockPulseSrc_CounterEqualCmpAcincr); //从 incr 上的 CPMA 中选择 SOC
    PWM_setSockAPeriod (myPwm、PWM_SockPeriod_FirstEvent); //在发生第一个事件时生成脉冲
    PWM_setCmpA (myPwm、0x0080); //设置比较 A 值
    PWM_setPeriod (myPwm、0xFFFF); //为 ePWM1设置周期
    PWM_setCounterMode (myPwm、PWM_CounterMode_Up); //向上计数并启动

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    GPIO_setPullUp (myGpio、GPIO_Number_7、GPIO_PULLUP_Enable);
    GPIO_setHigh (myGpio、GPIO_Number_7);
    GPIO_setMode (myGpio、GPIO_Number_7、GPIO_7_Mode_generalpurpose);
    GPIO_setDirection (myGpio、GPIO_Number_7、GPIO_Direction_Output);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    //等待 ADC 中断
    for (;;)

    LoopCount++;





    中断空 ADC_ISR (空)


    GPIO_setLow (myGpio、GPIO_Number_7);
    //将 ADCRESULT0作为修订版0第一个样本勘误表权变措施的一部分丢弃
    Voltage1[ConversionCount]= ADC_readResult (myAdc、ADC_ResultNumber_1);
    Voltage2[ConversionCount]= ADC_readResult (myAdc、ADC_ResultNumber_2);

    //如果记录了10次转换,则重新开始
    if (ConversionCount = 9)

    ConversionCount = 0;

    else ConversionCount++;

    //清除 ADCINT1标志为下一个 SOC 重新初始化
    ADC_clearIntFlag (myAdc、ADC_IntNumber_1);
    //确认 PIE 中断
    PI_clearInt (myPie、PI_GroupNumber_10);

    返回;


    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    请帮助!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 MatthewRate 和 Tommy。
    实际上、示例文件中缺少行 CLK_enableTbClockSync (myClk);。 我添加了它、现在它正在工作。 非常感谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ashwin、

    很高兴我们发现了这个问题。 您能否提供您正在使用的 C2000Ware 版本、但缺少时钟启用功能?  我认为这在我的 V 1_00_03_00中是固定的、但我想确保没有一些我不知道的错误封装。

    谢谢、
    Matthew