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/LAUNCHXL-F28379D:ADC EOC 中断问题

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/639694/ccs-launchxl-f28379d-problem-with-adc-eoc-interrupt

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

您好!

我尝试开发一个示例应用、从 ADC 读取模拟输入并将其直接写入 DAC。 我使用 EPWM 模块执行循环转换、并使用 ADC EOC 中断、因此在中断服务例程中设置 DAC 输出。 但是、似乎从未调用中断服务例程。 我参考了 C2000ware 中的 TI 示例。

我随附了我用于您参考的代码:

非常感谢您的帮助。

Sebastian

#include "F28x_Project.h"


//计时器周期设置采样时间
#define TIMER_PERIOD 0x1388 // 1 equals 10ns period => 10000 = 100us period = 10ksps


// ADC 转换时钟预分频
器#define ADC_PRESALE_1 0x0
#define ADC_PRESALE_2 0x2
#ADC_PRESALE_5_define

0x4 #define ADC_PRALE_#define
0x5_5 #define ADC_4 #define 0x4 #define ADC_4 #define
0x4 #define ADC_PRALE_5 #define #define #define ADC_5 #define ADC_ADC_PRALE_5 #define #define 0x4
ADC_PRESALE_5 0x8
#define ADC_PREPALE_5_5 0x9
#define ADC_PREPALE_6 0xA
#define ADC_PREPALE_6_5 0xB
#define ADC_PREPALE_7 0xC
#define ADC_PREPALE_7_5 0xD
#define ADC_UNDALE_8 0xE #define ADC_PREPALE_7 0x5


0xC #define ADC_BIT
0x12位分辨
率0x5 0xF_8 #define ADC_ADC_ADC_ADC_ADC_RESPLE_ADC_ALE_8 #define ADC_BIT 0x5 0x5 0x 0x0040

#define ADC_INPUT_SINGLEEND0x0

#define ADC_POWER 0x1 // ADC 加电

#define ADC_PULSEPOS_EOC 0x1 //转换结束时触发的中断

#define EPWMCLKDIV_1 0x0
#define EPWMCLKDIV_2 0x1 //

EPWPWM 输入时钟预分频器0x4


#define HSPLPCHSIV#define
0x4 #define 0xKHSPIV_0x4 #define 0x4 #define 0xKHSPDIV_define 0x4 #define 0xKHSPLPCKLPDIV#define 0x4 #define 0x4 #define 0xTHS1#define 0xKHSPLPCLPCK4 #define 0x4 #define 0xK


#define HSPCLKDIV_12 0x6
#define HSPCLKDIV_14 0x7

中断空 adca1_conversion (void);

int main (void)
{

//初始化系统控制
// PLL、安全装置、启用外设时钟
InitSysCtrl();
EALLOW;
//设置时钟分频器、SYSCLOCKOUT 为200MHz (使用 CPU_RATE 定义)
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = EPWMCLKDIV_2;//将 PLLSYSCLK 除以2
//CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
EDIS;

//清除中断并初始化 PIE 表
Dint;
InitPieCtrl();
//禁用 CPU 中断并清除中断标志
IER = 0x0000;
IFR = 0x0000;

//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable();


//映射 ISR 函数
EALLOW;
PieVectTable.ADCA1_INT =&adca1_conversion;// ADCA 中断1的函数
EDIS;

//初始化和配置 ADC 模块
EALLOW;
AdcaRegs.ADCCTL2.bit.prescale = ADC_prescale_4;//将 ADCCLK 分频器设置为/4
AdcaRegs.ADCCTL2.bit.resolution = ADC_resolution_12位;// 12位分辨率
AdcaRegs.ADCCTL2.bit.SGNALMODE = ADC_INPUT_SINGLEENDED; //单端通道转换(仅12位模式)
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = ADC_PULSEPOS_EOC; //将脉冲位置设置为晚期

AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0将转换引脚 A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14; //采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 7; //在 ePWM2 SOCA/C 上触发
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //确保清除 INT1标志

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

DELAY_US (1000);

//初始化和配置 ePWM 模块
//该模块用于生成循环中断以触发 ADC 转换
EALLOW;
EPwm2Regs.TBCTL.bit.CTRMODE = 3; //冻结计数器模式
EPwm2Regs.TBCTR = 0x0000;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = HSPCLKDIV_1;// TBCLK 预分频器=/1
EPwm2Regs.TBPRD =定时器_PERIOD; //设置周期
EPwm2Regs.ETSEL.bit.SOCAEN = 0; //禁用组上的 SOC
EPwm2Regs.ETSEL.bit.SOCASEL = 2; //在期间匹配时选择 SOCA
EPwm2Regs.ETSEL.bit.SOCAEN = 1; //启用 SOCA
EPwm2Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲(后分频器)

EPwm2Regs.ETCLR.bit.SOCA = 1; //清除 SoC 标志

EDIS;

//初始化和配置 DAC 模块
EALLOW;
DacbRegs.DACCTL.bit.DACREFSEL = 1; //使用 ADC 基准
DacbRegs.DACCTL.bit.LOADMODE = 0; //加载下一个 SYSCLK
DacbRegs.DACVALS.ALL = 0x0800; //设置中程
DacbRegs.DACOUTEN.bit.DACOUTEN = 1; //启用 DAC
EDIS;

//初始化 GPIO (用于调试)
InitGpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;
EDIS;
GpioDataRegs.GPADAT.bit.GPIO31 = 1;

//启用全局中断和更高优先级的实时调试事件:
IER |= M_INT1;//启用组1中断(用于 ePWM)
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

//同步 ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;

//启动 ePWM
EPwm2Regs.TBCTL.bit.CTRMODE = 0; //取消冻结并进入向上计数模式

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清除 ADC INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; //确认 PIE 组1以启用进一步的中断

GpioDataRegs.GPADAT.bit.GPIO31 = 1;
while (1)
{
IF (AdcaRegs.ADCINTFlG.bit.ADCINT1 = 1)
{
GpioDataRegs.GPADAT.bit.GPIO31 = 0;
}
其他
GpioDataRegs.GPADAT.bit.GPIO31 = 1;
}

//返回0;
}

__interrupt void adca1_conversion (void)
{
DacbRegs.DACVALS.ALL = AdcaResultRegs.ADCRESULT0;//将 DAC 输出设置为 ADC 输入(TEST)

AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清除 ADC INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; //确认 PIE 组1以启用进一步的中断
}

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

    如果您在"Expressions"窗口中选中"AdcaResultRegs.ADCRESULT0"、它中是否有非零值? 它是否发生变化并正确对应于施加到 ADC 输入 A0的电压? 如果是、则 ePWM 工作且 ADC 被触发、但您的中断不会将其发送到 CPU。 在这里、您需要调试 ADC 中断配置和 PIE 设置、以确保启用所有功能。 粗略看一下您的代码后、可能缺少"PieCtrlRegs.PIEIER1.bit.INTx1 = 1;"?

    如果 ADC 未更新、您可能需要配置 ePWM 时基在周期匹配(生成触发的同时)上切换引脚。 如果您看不到引脚切换、那么 ePWM 可能实际上不在计数。 如果它确实发生切换、请检查 ePWM 侧和 ADC 侧的触发器配置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Devin、
    设置"PieCtrlRegs.PIEIER1.bit.INTx1=1;"可以解决问题。 ADC 中断现在可以按我的需要正常工作。

    非常感谢。

    Sebastian