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/TMS320F28069:两个 PWM 触发两个 SOC、并以不同的频率产生 ADC1和 ADC2中断

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/566346/ccs-tms320f28069-two-pwms-trigger-two-soc-and-result-adc1-and-adc2-interrupt-with-different-frequency

器件型号:TMS320F28069

工具/软件: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 转换开始(ADC_SoC)

//!

//! 此 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();

 返回;

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

    运行 AdcOffsetSelfCal()函数后,可能需要将 ADCINTSOCSEL1和 ADCINTSOCSEL2寄存器清零。 此函数用于配置这些寄存器、但不会在初始化中重新配置它们。