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/TMS320F28335:我使用 ECAP 中断来触发 ADC、但 ISR 中的可采样索引不会添加并保持0。

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/681165/ccs-tms320f28335-i-use-ecap-interrupt-to-trigger-adc-but-the-index-to-the-sampletable-in-the-isr-does-not-add-and-maintain-0

器件型号:TMS320F28335

工具/软件:Code Composer Studio

以下是我的代码:

//######################################################################################################################
//描述:
//! 添加到组 F2833x_example_list
//!

ECAP 捕获 PWM (ECAP_CAPTURE_PWM)


//!
//! 以下示例将 ePWM3A 配置为:
//! -向上计数
//! -周期从2开始,最高1000
//! -在 PRD 上切换输出
//!
//! eCAP1被配置为捕捉上升之间的时间
//! 和 ePWM3A 输出的下降沿。
//!
//! b 外部连接\n
//! - eCAP1位于 GPIO24上
//! - ePWM3A 在 GPIO4上
//! -将 GPIO4连接到 GPIO24。
//!
//! b 监视\b 变量\n
//! - ECap1IntCount -成功捕获
//! - ECap1通过计数-中断计数
//
//######################################################################################################################
//$TI 发行版:F2833x/F2823x 头文件和外设示例 V140 $
//$Release Date:2015年3月4日$
//版权所有:版权所有(C) 2007-2015 Texas Instruments Incorporated -
// http://www.ti.com/ 保留所有权利$
//######################################################################################################################

#include "DSP28x_Project.h"//器件头文件和示例 include 文件

#define post_shift 1 //在整个采样表满后移位结果
#define inline_shift 0 //从结果寄存器获取数据时移位结果
#define NO_SHIFT 0 //不移动结果

// ADC 开始参数
#IF (CPU_FRQ_150MHz)//默认- 150MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0MHz
#endif
#IF (CPU_FRQ_100MHz)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)= 25.0MHz
#endif
#define ADC_CKPS 0x0 // ADC 模块时钟= HSPCLK/1 = 25.5MHz/(1)= 25.0MHz
#define ADC_SHCLK 0x1 //在 ADC 模块周期中的 S/H 宽度= 2个 ADC 周期
#define AVG 1000 //平均采样限制
define zOffset 0x00 //平均零偏移
#define BUF_SIZE 1024 //采样缓冲区大小
#define NR (x)(sizeof (x)/sizeof (x[0]))
#pragma DATA_SECTION ()
//此示例的全局变量
uint16 SampleTable[BUF_SIZE];
uint16 DataTable[BUF_SIZE];
uint16 j;
_interrupt void eCAP1_ISR (void);
void InitECapture (void);
失效失效(失效);

//此示例中使用的全局变量
UINT32 ECap1IntCount;
uint32 ECap1通过计数;
uint16 array_index = 0;
//跟踪计时器值的移动方式


void main (void)

静态 uint16 i;
静态 uint16 j;

InitSysCtrl();

EALLOW;
SysCtrlRegs.HISPCP。all = ADC_MODCLK;
EDIS;

EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;// GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;//输出
EDIS;


InitECap1Gpio();

//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;

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

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

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

InitAdc();

//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
EALLOW;//这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.ECAP1_INT =&eCAP1_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//步骤4. 初始化所有器件外设:
//此函数位于 DSP2833x_InitPeripherals.c 中
// InitPeripherals ();//此示例不需要

//初始化 GPIO 我不明白为什么这可以启用中断。
EALLOW;
GpioCtrlRegs.GPBMUX2.bit.GPIO60=0;
GpioCtrlRegs.GPBDIR.bit.GPIO60=0;
EDIS;

InitECapture();

//步骤5. 特定于用户的代码、启用中断:

//本示例的特定 ADC 设置:
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
/*顺序模式:采样率= 1/[(2+ACQ_PS)*以 ns 为单位的 ADC 时钟]
= 1/(3*40ns)= 8.3MHz (对于150MHz SYSCLKOUT)
= 1/(3*80ns)= 4.17MHz (对于100MHz SYSCLKOUT)
如果启用同步模式:采样率= 1/[(3+ACQ_PS)* ADC 时钟(以 ns 为单位)*/
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;// 1级联模式
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCTRL1.bit.CONT_RUN = 0;//启动/停止模式
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
AdcRegs.ADCCHSELSEQ1.ALL = 0x0001;//初始化所有 ADC 通道选择为 A0
AdcRegs.ADCCHSELSEQ2.ALL = 0x0;
AdcRegs.ADCCHSELSEQ3.ALL = 0x0;
AdcRegs.ADCCHSELSEQ4.ALL = 0x0;
AdcRegs.ADCMAXCONV.BIT.MAX_CONV1 = 0x1;
AdcRegs.ADCTRL2.all = 0x2000;

for (i=0;<BUF_SIZE; i++)

SampleTable[i]= 0;

//初始化计数器:
ECap1IntCount = 0;
ECap1PassCount = 0;

//启用连接到 ECAP1-4 INT 的 CPU INT4:
IER |= M_INT4;

//在 PIE 中启用 eCAP INTn:组3中断1-6
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;

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

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

while (<BUF_SIZE){
J = BUF_SIZE;
DataTable[j]=(SampleTable[0]);
J-;



空 InitECapture()

ECap1Regs.ECEINT.ALL = 0x0000;//禁用所有捕捉中断
ECap1Regs.ECCLR.ALL = 0xFFFF;//清除所有 CAP 中断标志
ECap1Regs.ECCTL1.bit.CAPLDEN = 0;//禁用 CAP1-CAP4寄存器加载
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;//确保计数器被停止

//配置外设寄存器
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0;//连续
ECap1Regs.ECCTL2.bit.STOP_Wrap = 3;//在4个事件时停止
ECap1Regs.ECCTL1.bit.CAP1POL = 1;//下降边沿
ECap1Regs.ECCTL1.bit.CAP2POL = 0;//上升边沿
ECap1Regs.ECCTL1.bit.CAP3POL = 1;//下降边沿
ECap1Regs.ECCTL1.bit.CAP4POL = 0;//上升边沿
ECap1Regs.ECCTL1.bit.CTRRST1 = 0;// STM 运算
ECap1Regs.ECCTL1.bit.CTRST2 = 0;// STM 运算
ECap1Regs.ECCTL1.bit.CTRST3 = 0;// STM 运算
ECap1Regs.ECCTL1.bit.CTRRST4 = 0;// STM 运算
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;//启用同步输入
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;//直通
ECap1Regs.ECCTL1.bit.CAPLDEN = 1;//启用捕捉单元


ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;//起始计数器
ECap1Regs.ECCTL2.bit.rearm = 0;// ARM 单次触发
ECap1Regs.ECCTL1.bit.CAPLDEN = 1;//启用 CAP1-CAP4寄存器加载
ECap1Regs.ECEINT.BIT.CEVT4 = 1;// 4个事件=中断


_interrupt void eCAP1_ISR (void)

volatile uint16 array_index;
易失性 uint16 i;

//可变以监视旋转信号是否触发中断。
ECap1IntCount++;

ECap1PassCount++;

array_index = 0;

//等待 INT1
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
GpioDataRegs.GPBSET.BIO34 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;

#if inline_shift

SampleTable[array_index+]=(AdcRegs.ADCRESULT0)>>4);

#endif

#if no_shift || post_shift

SampleTable[array_index++]=((AdcRegs.ADCRESULT0));

#endif //-- no_shift || post_shift

#if post_shift
//对于后移,移动 ADC 结果
//在 SampleTable 缓冲区中,缓冲区已满。
(i=0;<BUF_SIZE; i++)

SampleTable[i]=((SampleTable[i])>>4);

#endif //-- post_shift

GpioDataRegs.GPBCLEAR.bit.GPIO34 = 0;//清除 GPIO34以进行监控-可选

// AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;

ECap1Regs.ECCLR.bit.CEVT4 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
ECap1Regs.ECCTL2.bit.rearm = 0;

//确认此中断以接收来自组4的更多中断
PieCtrlRegs.PIEACX.ALL = PIEACK_group4;

void fail()(空失败())

_asm (" ESTOP0");


//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
//不再需要。
//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

 该变量'array_index'应该添加一个、但它保持为0、原因是什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    那么问题是 array_index 没有被包含 array_index++的行递增? 您是否在 ISR 开始处放置了一个断点并逐行单步执行代码行以确保运行 array_index++行? 由于它们位于 #IFS 内部、我希望确保在中编译代码。

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

    您是否能够解决此问题?

    惠特尼