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.
工具/软件:Code Composer Studio
您好!
最近、我们遇到了 F2806x ADC 的一个问题。
我们的目标是设置具有高优先级的 SOC0~SOC5、 使用 ADC 中断1设置40KHz 等 PWM 触发频率;设置 SOC6~SOC15循环、 使用 ADC 中断2设置另一个 PWM 触发频率、如20kHz。
无论我们如何配置、我们都发现 两个 ADC 中断频率 是相同的。 有一个例外、 就是像 EOC7 或 EOC6那样设置 ADC 中断2的 EOC。
您能帮 您看看 吗? 提前感谢。
代码:使用 ADC 中断4。
//######################################################################################################################
//描述:
//! addtogroup f2806x_example_list
//!
//!
//! 此 ADC 示例使用 ePWM1来生成周期性 ADC SOC - ADCINT1。
//! 两个通道被转换、ADCINA4和 ADCINA2。
//!
//! b 监视\b 变量\n
//! - Voltage1[10] -最后10个 ADCRESULT0值
//! - Voltage2[10] -最后10个 ADCRESULT1值
//! -转换计数-当前结果编号0-9
//! -循环计数 -空闲循环计数器
//
//
//######################################################################################################################
//$TI 版本:F2806x C/C++头文件和外设示例 V151 $
//$Release Date: 2016年2月2日$
//版权所有:版权所有(C) 2011-2016德州仪器(TI)公司-
// http://www.ti.com/ 保留所有权利$
//######################################################################################################################
#include "DSP28x_Project.h" //器件头文件和示例 include 文件
//此文件中找到的函数的原型语句。
_interrupt void ADC_ISR (void);
_interrupt void adc_isr2 (void);
void ADC_Config (void);
#define hoFault_LED () 0//GpioDataRegs.GPBSET.bit.GPIO43 = 1.
#define LOFault_LED() 0//GpioDataRegs.GPBCLEAR.bit.GPIO43=1
#define hofault_LED1 () GpioDataRegs.GPBSET.bit.GPIO43 = 1.
#define LOFault_LED1 () GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1.
#define hoComM_LED () 0//GpioDataRegs.GPASET.bit.GPIO0 = 1
#define loComM_LED () 0//GpioDataRegs.GPACLEAR.bit.GPIO0 = 1
#define hoComM_LED1 () GpioDataRegs.GPASET.bit.GPIO0 = 1
#define loComM_LED1 () GpioDataRegs.GPACLEAR.bit.GPIO0 = 1
//此示例中使用的全局变量:
uint16环计数;
UINT16转换计数;
uint16 Voltage1[10];
uint16 Voltage2[10];
int32 user_max_speed、user_min_speed、temp_speed、num_isr1、num_isr2;
uint16 ain_speed、flag_need、flag_start_command;
#define MIN_AIN 250
uint16 Flag1 =0;
uint16 Flag2 =0;
MAIN ()
{
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2806x_SYSCTRL.c 文件中。
////////
InitSysCtrl();
////////////
//步骤2. 初始化 GPIO:
//此示例函数位于 F2806x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
// InitGpio(); //针对此示例跳过
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
Dint;
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2806x_PIECTRL.c 文件中。
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
IER = 0x0000;
IFR = 0x0000;
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; //通信 LED
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;//默认关闭
GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 0; //故障 LED
GpioCtrlRegs.GPBDIR.bit.GPIO43 = 1;
GpioCtrlRegs.GPBPUD.bit.GPIO43 = 0;
GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1; //默认关闭
EDIS;
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2806x_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2806x_PieVect.c 中找到
InitPieVectTable();
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
EALLOW; //这是写入 EALLOW 受保护寄存器所必需的
PieVectTable.ADCINT1 =&ADC_ISR;
// PieVectTable.ADCINT2 =&ADC_isr2;
PieVectTable.ADCINT4 =&ADC_isr2;
EDIS; //这是禁止写入 EALLOW 受保护寄存器所必需的
//步骤4. 初始化所有器件外设:
//此函数可在 F2806x_InitPeripherals.c 中找到
// InitPeripherals ();//此示例不需要
InitAdc (); //对于此示例,初始化 ADC
AdcOffsetSelfCal();
//步骤5. 特定于用户的代码、启用中断:
//在 PIE 中启用 ADCINT1
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //在 PIE 中启用 INT 1.1
PieCtrlRegs.PIEIER10.bit.INTx4 = 1; //在 PIE 中启用 INT 10.2
// PieCtrlRegs.PIEIER10.bit.INTx4 = 1;
IER |= M_INT1; //启用 CPU 中断1
IER |= M_INT10;
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM
LoopCount = 0;
ConversionCount = 0;
num_isr1=0;
num_isr2=0;
//配置 ADC
EALLOW;
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 0; //启用非重叠模式
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADCINT1在 AdcResults 锁存后跳闸
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0x05;
AdcRegs.INTSEL1N2.bit.INT1E = 1; //启用 ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // 0禁用 ADCINT1连续模式
AdcRegs.INTSEL1N2.bit.INT1SEL = 4; //设置 EOC1以触发 ADCINT1触发
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; //将 SOC0通道选择设置为 ADCINA4
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //将 SOC1通道选择设置为 ADCINA2
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; //将 SOC1通道选择设置为 ADCINA2
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; //将 SOC1通道选择设置为 ADCINA2
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4; //将 SOC1通道选择设置为 ADCINA2
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //设置 SOC0在 EPWM1A 上启动触发器,因为轮询 SOC0先转换,然后 SOC1
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //设置 EPWM1A 上的 SOC1启动触发器,因为 SOC0先转换,然后 SOC1
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //设置 EPWM1A 上的 SOC1启动触发器,因为 SOC0先转换,然后 SOC1
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 5; //设置 EPWM1A 上的 SOC1启动触发器,因为 SOC0先转换,然后 SOC1
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 5; //设置 EPWM1A 上的 SOC1启动触发器,因为 SOC0先转换,然后 SOC1
AdcRegs.ADCSOC0CTL.bit.ACQPS = 8; //将 SOC0 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 8; //将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 8; //将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 8; //将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 8; //将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
// AdcRegs.INTSEL1N2.bit.INT2E = 1; //启用 ADCINT2
// AdcRegs.INTSEL1N2.bit.INT2CONT = 0; //禁用 ADCINT2连续模式
// AdcRegs.INTSEL1N2.bit.INT2SEL = 4; //设置 EOC4以触发 ADCINT2触发
AdcRegs.INTSEL3N4.bit.INT4E = 1; //启用 ADCINT4
AdcRegs.INTSEL3N4.bit.INT4CONT = 0; // 0禁用 ADCINT4连续模式
AdcRegs.INTSEL3N4.bit.INT4SEL =0xF; //7; //设置 EOC4以触发 ADCINT4触发
AdcRegs.ADCSOC5CTL.bit.CHSEL = 5; //将 SOC2通道选择设置为 ADCINA4
AdcRegs.ADCSOC6CTL.bit.CHSEL = 6; //将 SOC3通道选择设置为 ADCINA2
AdcRegs.ADCSOC7CTL.bit.CHSEL = 7; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC8CTL.bit.CHSEL = 8; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC9CTL.bit.CHSEL = 9; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC10CTL.bit.CHSEL = 10; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC11CTL.bit.CHSEL = 11; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC12CTL.bit.CHSEL = 12; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC13CTL.bit.CHSEL = 13; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC14CTL.bit.CHSEL = 14; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC15CTL.bit.CHSEL = 15; //将 SOC4通道选择设置为 ADCINA2
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC2启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC3启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC4起始触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC2启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC3启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC4起始触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC2启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC3启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC4起始触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC2启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 8; //设置 EPWM2B 上的 SOC3启动触发器、因为轮询 SOC0先转换、然后 SOC1
AdcRegs.ADCSOC5CTL.bit.ACQPS = 8; //将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC6CTL.bit.ACQPS = 8; //将 SOC3 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC7CTL.bit.ACQPS = 8; //将 SOC4 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC8CTL.bit.ACQPS = 8; //将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC9CTL.bit.ACQPS = 8; //将 SOC3 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC10CTL.bit.ACQPS = 8; //将 SOC4 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC11CTL.bit.ACQPS = 8; //将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC12CTL.bit.ACQPS = 8; //将 SOC3 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC13CTL.bit.ACQPS = 8; //将 SOC4 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC14CTL.bit.ACQPS = 8; //将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
AdcRegs.ADCSOC15CTL.bit.ACQPS = 8; //将 SOC3 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
EDIS;
//假设 ePWM1时钟已在 InitSysCtrl()中启用;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; //启用组上的 SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在递增计数时从 CMPA 中选择 SOC
EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲
EPwm1Regs.CMPA.half.CMPA = 0x10; //设置比较 A 值
EPwm1Regs.TBPRD = 0x8000; //为 ePWM1设置周期
EPwm1Regs.TBCTL.bit.CTRMODE = 0; //向上计数并启动
//假设 ePWM2时钟已在 InitSysCtrl()中启用;
// EPwm2Regs.ETSEL.bit.SOCAEN = 1; //在 B 组上启用 SOC
// EPwm2Regs.ETSEL.bit.SOCASEL = 4; //在递增计数时从 CMPB 中选择 SOC
// EPwm2Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲
// EPwm2Regs.CMPA.half.CMPA = 10; //设置比较 B 值
// EPwm2Regs.TBPRD = 2250; //设置 ePWM1的周期
// EPwm2Regs.TBCTL.bit.CTRMODE = 0; //向上计数并启动
EPwm2Regs.ETSEL.bit.SOCBEN = 1; //在 B 组上启用 SOC
EPwm2Regs.ETSEL.bit.SOCBSEL = 6; //在递增计数时从 CMPB 中选择 SOC
EPwm2Regs.ETPS.bit.SOCBPRD = 1; //在发生第一个事件时生成脉冲
EPwm2Regs.CMPB = 0x2020; //设置比较 B 值
EPwm2Regs.TBPRD = 0xFFF0; //为 ePWM1设置周期
EPwm2Regs.TBCTL.bit.CTRMODE = 0; //向上计数并启动
//等待 ADC 中断
//等待 ADC 中断
//等待 ADC 中断
//等待 ADC 中断
for (;;)
{
LoopCount++;
if (flag_need=1)
{
//从 AIN 获取的速度、3.3V~0.2V=max_speed~min_speedRPM
temp_speed = USER_MAX_SPED/4095;
temp_speed *= ain_speed;
//如果 AIN 低于0.2V、设置为0RPM
if (temp_speed > USER_MIN_SPEED)
{
flag_start_command=0x00;
}
其他
{ //_IQ (1)=16777216~1000RPM、16777~1rpm
//temp_speed *= 16777;
flag_start_command=0x01;
}
flag_need=0;
}
}
}
_interrupt void ADC_ISR (void)
{
hoFault_LED1 ();
/*
if (Flag1 = 0)
{
hoFault_LED1 ();
Flag1 = 1;
}
其他
{
loFault_LED1 ();
Flag1 = 0;
}
*
Voltage1[ConversionCount]= AdcResult.ADCRESULT0;
Voltage2[ConversionCount]= AdcResult.ADCRESULT1;
num_isr1++;
//如果记录了20次转换,则重新开始
if (ConversionCount = 9)
{
ConversionCount = 0;
}
else ConversionCount++;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清除 ADCINT1标志为下一个 SOC 重新初始化
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; //确认 PIE 中断
// PieCtrlRegs.PIEACK.bit.ACK1=1;
// lofault_LED1();
返回;
}
_interrupt void adc_isr2 (void)
{
hoComm_LED1();
/*
if (Flag2 = 0)
{
hoComm_LED1();
Flag2 = 1;
}
其他
{
loComM_LED1 ();
Flag2 = 0;
}
*
Voltage1[ConversionCount]= AdcResult.ADCRESULT2;
Voltage2[ConversionCount]= AdcResult.ADCRESULT3;
Voltage2[ConversionCount]= AdcResult.ADCRESULT4;
num_isr2++;
//如果记录了20次转换,则重新开始
if (ConversionCount = 9)
{
ConversionCount = 0;
}
else ConversionCount++;
AdcRegs.ADCINTFLGCLR.bit.ADCINT4 = 1; //清除 ADCINT1标志为下一个 SOC 重新初始化
// PieCtrlRegs.PIEACK.all = PIEACK_group10; //确认 PIE 中断
// PieCtrlRegs.PIEACK.bit.ACK1 = 1;
// AdcRegs.ADCINTFLGCLR.bit.ADCINT4 = 1; //清除 ADCINT1标志为下一个 SOC 重新初始化
PieCtrlRegs.PIEACK.all = PIEACK_group10; //确认 PIE 中断
// loComM_LED1();
返回;
}