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.

tms32f28033中的模拟比较器问题

Other Parts Discussed in Thread: CONTROLSUITE

各位大侠们:

       请问下:我在使用tms32f28033中的comp外设时, 输入的模拟信号一直在比较器时输入口感觉一直是0(用内部DAC基准不同值实验),实际我加了1.5V,我从AD口采样读取数据1600多,照理说应该电压时输入了~~有哪些地方会影响输入模拟口比较器电压?代码如下:

// Inilialize Comp:

////////////////////////////COMP1A FOR DC OCP//////////////////////////
EALLOW;
//GpioCtrlRegs.AIOMUX1.bit.AIO2 = 2; // Configure AIO2 for CMP1A (analog input) operation
GpioCtrlRegs.AIOMUX1.bit.AIO10 =2; // Configure AIO10 for CMP1B (analog input) operation
AdcRegs.COMPHYSTCTL.bit.COMP1_HYST_DISABLE = 1; //Hysteresisdisable
Comp1Regs.COMPCTL.bit.CMPINV=0;      //0: Output of comparator,1: Inverted
    Comp1Regs.COMPCTL.bit.COMPSOURCE=0;   //connected to internal DAC
Comp1Regs.COMPCTL.bit.SYNCSEL = 0;    //Asynchronous version of Comparator output
//COMP1Regs.COMPCTL.bit.QUALSEL = 0xF; // filter, no need
    Comp1Regs.COMPCTL.bit.COMPDACEN=1;    //for test
    //0-1023:0-3.3V, OCP:35A:35*0.010=0.35V,0.35*1023/3.3=109 
    // COMP1Regs.DACVAL.all= 200; //G3 50A
   
    //0-1023:0-3.3V, OCP:35A:35*0.0075=0.2625V,0.2625*1023/3.3=81
     Comp1Regs.DACVAL.all= 10;
 
    // Define an event (DCAEVT1) based on TZ1 and TZ2
    //选择COMP1_OUT作为输入:
    EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP1OUT;        // DCAH = Comparator 1 output
   // EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;        // DCAL = TZ2
   //DCAH高电平有效:
    EPwm1Regs.TZDCSEL.bit.DCBEVT1 = 0x02;               // DCBEVT1 =  DCAH high(will become active as Comparator output goes low) 
    EPwm1Regs.DCBCTL.bit.EVT1SRCSEL = 0x0;                // DCAEVT1 = DCAEVT1 (not filtered)
    EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = 0x1;       // Take async path    
    // Enable DCAEVT1 and DCBEVT1 are one shot trip sources
    // Note: DCxEVT1 events can be defined as one-shot. 
    // DCxEVT2 events can be defined as cycle-by-cycle.
    EPwm1Regs.TZSEL.bit.DCBEVT1 = 1; //EnableDCAEVT1asone-shot-tripsourcefor this ePWMmodule
    // DCAEVTx events can force EPWMxA
    // DCBEVTx events can force EPWMxB 
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;           // EPWM1A will go high
    EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;           // EPWM1A will go high
    // Enable TZ interrupt
    EPwm1Regs.TZCLR.all = 0x0007; //clear all TZFLAG
//Enable Interrupt generation;
// a one-shot trip event will cause a EPWMx_TZINT PIE interrupt
    EPwm1Regs.TZEINT.bit.OST = 0;   //OST中断
    EDIS;
  • 你的DAC的reference现在设置的不是1.5V,你是怎么判断现在有问题的?

    以下是一个根据controlsuite例程改的使用内部DAC 设置为1.65V 比较点,然后通过触发比较器可以触发EPWM4 oneshot事件,并且在EPWM4周期中断清标志的例子,你可以参考下。

    #include "DSP28x_Project.h" // Device Headerfile and Examples Include File

    // Prototype statements for functions found within this file.
    void InitEPwm4Example(void);
    void InitComp2(void);
    __interrupt void epwm4_tzint_isr(void);

    // Global variables used in this example
    uint32_t EPwm4TZIntCount;
    uint32_t EPwm2TZIntCount;

    void main(void)
    {

    // WARNING: Always ensure you call memcpy before running any functions from RAM
    // InitSysCtrl includes a call to a RAM based function and without a call to
    // memcpy first, the processor will go "into the weeds"
    #ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the f2802x_SysCtrl.c file.
    InitSysCtrl();

    // Step 2. Initalize GPIO:
    // This example function is found in the f2802x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio(); // Skipped for this example

    // For this case just init GPIO pins for ePWM1, ePWM2, and TZ pins
    InitEPwm4Gpio();
    InitComp2();
    EALLOW;

    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0; // Configure GPIO6 as EPWM4A
    GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;
    GpioDataRegs.GPBCLEAR.bit.GPIO33 = 1;

    EDIS;
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    DINT;

    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the f2802x_PieCtrl.c file.
    InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in f2802x_DefaultIsr.c.
    // This function is found in f2802x_PieVect.c.
    InitPieVectTable();

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM4_TZINT = &epwm4_tzint_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    // Step 4. Initialize all the Device Peripherals:
    // This function is found in f2802x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example


    //------------------------------------------------------------------
    //////////////////////////////////////////////////////////////////////////////////////////////
    EDIS;
    //------------------------------------------------------------------
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    InitEPwm4Example();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    // Step 5. User specific code, enable interrupts
    // Initalize counters:
    EPwm4TZIntCount = 0;

    // Enable CPU INT3 which is connected to EPWM1-3 INT:
    IER |= M_INT2;

    // Enable EPWM INTn in the PIE: Group 2 interrupt 1-3
    PieCtrlRegs.PIEIER2.bit.INTx4 = 1;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    // Step 6. IDLE loop. Just sit and loop forever (optional):
    for(;;)
    {
    __asm(" NOP");
    }

    }

    __interrupt void epwm4_tzint_isr(void)
    {
    EPwm4TZIntCount++;

    // Leave these flags set so we only take this
    // interrupt once
    //
    EALLOW;
    // EPwm4Regs.TZCLR.bit.OST = 1;
    // EPwm4Regs.TZCLR.bit.INT = 1;
    EPwm4Regs.TZCLR.bit.DCAEVT1 = 1;
    EPwm4Regs.TZCLR.bit.INT = 1;
    EPwm4Regs.TZCLR.bit.OST = 1;
    GpioDataRegs.GPBDAT.bit.GPIO33 = EPwm4Regs.TZFLG.bit.OST;

    EDIS;

    // Acknowledge this interrupt to receive more interrupts from group 2
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;

    }


    void InitEPwm4Example()
    {

    EALLOW;
    EPwm4Regs.TBPRD = 6000; // Set timer period
    EPwm4Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm4Regs.TBCTR = 0x0000;

    // Setup TBCLK
    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
    EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT
    EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV4;

    EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
    EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Setup compare
    EPwm4Regs.CMPA.half.CMPA = 3000;

    // Set actions
    EPwm4Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    // EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
    EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR;


    EPwm4Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
    EPwm4Regs.AQCTLB.bit.CAD = AQ_SET;

    // Define an event (DCAEVT1) based on TZ1 and TZ2
    EPwm4Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP2OUT; // DCAH = Comparator 2 output
    // EPwm4Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_COMP2OUT; // DCAL = TZ2
    EPwm4Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI; // DCAEVT1 = DCAH high(will become active as Comparator output goes low)
    EPwm4Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1; // DCAEVT1 = DCAEVT1 (not filtered)
    EPwm4Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC; // Take async path

    // Define an event (DCBEVT1) based on TZ1 and TZ2
    // EPwm4Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP2OUT; // DCBH = Comparator 2 output
    // EPwm4Regs.DCTRIPSEL.bit.DCBLCOMPSEL = DC_TZ2; // DCAL = TZ2
    // EPwm4Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_LOW; // DCBEVT1 = (will become active as Comparator output goes low)
    // EPwm4Regs.DCBCTL.bit.EVT1SRCSEL = DC_EVT1; // DCBEVT1 = DCBEVT1 (not filtered)
    // EPwm4Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC; // Take async path

    // Enable DCAEVT1 and DCBEVT1 are one shot trip sources
    // Note: DCxEVT1 events can be defined as one-shot.
    // DCxEVT2 events can be defined as cycle-by-cycle.
    EPwm4Regs.TZSEL.bit.DCAEVT1 = 1;
    // EPwm4Regs.TZSEL.bit.DCBEVT1 = 1;

    // What do we want the DCAEVT1 and DCBEVT1 events to do?
    // DCAEVTx events can force EPWMxA
    // DCBEVTx events can force EPWMxB
    EPwm4Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWM4A will go high
    // EPwm4Regs.TZCTL.bit.TZA = TZ_NO_CHANGE; // EPWM4A will go high
    EPwm4Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWM4B will go low

    // Enable TZ interrupt
    // EPwm4Regs.TZEINT.bit.OST = 1;
    // EPwm2Regs.TZSEL.bit.DCAEVT1 = 1;
    EPwm4Regs.TZEINT.bit.DCAEVT1 = 1;
    EDIS;


    }

    void InitComp2(void)
    {
    EALLOW;
    /* Configure AIO4 for CMP2A (analog input) operation*/

    GpioCtrlRegs.AIOMUX1.bit.AIO4 = 2;
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; // Disable pull-up for GPIO3 (CMP2OUT)
    /* Configure Comp pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be Comp functional pins.
    // Comment out other unwanted lines.
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 3; // Configure GPIO3 for CMP2OUT operation
    /* Comparator shares the internal BG reference of the ADC,
    * must be powered even if ADC is unused.*/
    AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;

    Comp2Regs.COMPCTL.bit.SYNCSEL = 1; /* asynchronous output */
    Comp2Regs.COMPCTL.bit.QUALSEL = 0x000F;

    /* Power up Comparator 2 locally */
    Comp2Regs.COMPCTL.bit.COMPDACEN = 1;
    /* Connect the inverting input to the internal DAC */
    Comp2Regs.COMPCTL.bit.COMPSOURCE = 0;
    /* Set CMP2 protection threshold */
    Comp2Regs.DACVAL.bit.DACVAL = 0x200; //0x200=512


    EDIS;

    }

  • 谢谢你的回复,我现在设置的是10/1023*3.3,设置成数字量10后,比较器输出还是低电平,那样说明我输入的值比10还小,当我反一下,当DCBEVT1低电平有效时,后我的TZFLAG.DCABVT1标志位会置位的,而我实际输入模拟信号时1.5V,从ADC结果寄存器中是可以读取数据的1600多,所以我判断是我的模拟比较器输入出现了状况。

    您下面的代码和我配置应该是一样的,除了你下面的GPIO3和配置成CMP2OUT是什么意思?前面你输入的模拟信号时AIO4 对吧?

    还有请问下,DCBH和DCAH在寄存器DCTRIPSEL中选择是怎么选择的,还有AH和AL也是随意选择的吗?

  • 如果是高触发,一般选择AH,如果是低触发,一般选择AL。你可以先看一下,COMPSTS寄存器,比较器是否真的被触发翻转了,如果触发了,说明外部输入电压和DAC没问题。COMP2OUT只是用来把比较器的结果输出到GPIO观测。

  • 您好:

         COMPSTS寄存器确实没有触发,寄存器显示为0,很奇怪,从AD结果寄存器看应该是有电压进去了,实际这个比较器确实没有触发,我的配置我对了好些遍也没发现有错误地方~~AH和BH有区别吗?两个都可以用吧?

  • 您好:

            我还和你一样把compout1的GPIO20口引出来,电平一直是低电平~~

  • 你现在是往哪个口输入电压,用的是哪个比较器?

  • 您好:

        我是用ADCINB2/COMP1B/AIO10引脚作为模拟比较器输入,比较器用的comp1

  • 如果使用内部DAC作为COMP负端输入,那就只能从COMP1A输入外部电压,B端就被内部DAC占用了,你看一下USER GUIDE   SPRUGE5F 44页的框图。COMPSOURCE寄存器用来选B端输入时内部DAC还是外部输入。所以你这样从B端输入电压一定不会触发比较器

  • 您好:

         您说的应该是对的,我把ADCIN2B/COMP1B/AIO10当做了COMP1比较器1的输入1A是有问题的,COMP1比较器1的1A应该只能用ADCIN2ACOMP1A/AIO2去复用。

          应该使这个问题,我这边代码把引脚ADCIN2B/COMP1B/AIO10复用成AIO2是有问题的,理解不到位。

  • 您好:

         您说的应该是对的,我把ADCIN2B/COMP1B/AIO10的引脚复用成了AIO10作为了COMP1比较器的1A输入,这样的想法是错误的,正确的应该把ADCIN2A/COMP1A/AIO2引脚复用成COMP1A作为COMP1比较器的1A输入。