wmj258034 发表于 2025-7-31 17:18

G32R501 COMP比较器使用笔记

本帖最后由 wmj258034 于 2025-8-2 15:15 编辑

**COMP简介:由模拟比较器与支持电路组成,可用于峰值电流模式控制、开关电源、功率因数校正、电压跳闸监测等应用**

* **COMP 的每个子系统构成:**
* ** 2 个模拟比较器**
* **1 个递减型斜坡发生器**
* **2 个数字滤波器**
* **2 个 12 位 DAC**

COMP的具体内容在G32R501用户手册上详细的说明,在此处就不赘述,以下主要详细记录一下我在EVAL板上实际编程使用COMP进行模拟量比较以及控制PWM跳闸的流程,笔者水平有限,文中如果错误或者有更好的见解,还望各位看官不吝赐教,谢谢。

## 配置流程

**根据手册选择COMP输入信号的多路复用器,例如可以选取模拟引脚A3配置为COMP1的高电平比较器正输入第三路**

```c
AS_selectCMPHPMux(AS_CMPHPMUX_SELECT_1, 3U);
```

**若需要同时对下限进行比较则可同时配置低电平比较器,只需微调第一个参数**

```c
AS_selectCMPHPMux(AS_CMPLPMUX_SELECT_1,3U);
```

**配置PWM XBAR将COMP信号路由至PWM DC模块,然后通过PWM内部DC比较子模块产生跳闸事件**

1. **配置信号来源:在用户手册中查看PWM XBAR信号多路复用配置,选择需要传输到PWM模块的信号,例如需要配置COMP1的高电平比较器输出刹车信号到PWM,根据表格应该选择COMP1.CTRIPH,也就是MUX0的第0项(若需要同时比较上下限则选择COMP1.CTRIPH_OR_CRTIPL)**
2. **配置信号输出:PWM X-BAR 一共由8个输出构成,也就是说配置传输到 PWM 模块的 TRIPx 信号可以从上述8个输出信号中任选其一,TRIP信号的具体名称可以从库函数定义中查看**

```c
typedef enum
{
    XBAR_TRIP4= 0,      //!< TRIP4 of the PWM X-BAR
    XBAR_TRIP5= 2,      //!< TRIP5 of the PWM X-BAR
    XBAR_TRIP7= 4,      //!< TRIP7 of the PWM X-BAR
    XBAR_TRIP8= 6,      //!< TRIP8 of the PWM X-BAR
    XBAR_TRIP9= 8,      //!< TRIP9 of the PWM X-BAR
    XBAR_TRIP10 = 10,       //!< TRIP10 of the PWM X-BAR
    XBAR_TRIP11 = 12,       //!< TRIP11 of the PWM X-BAR
    XBAR_TRIP12 = 14      //!< TRIP12 of the PWM X-BAR
} XBAR_TripNum;
```

**具体配置代码如下**

```c
XBAR_setPWMMuxConfig(XBAR_TRIP5, XBAR_PWM_MUX00_COMP1_CTRIPH);
XBAR_enablePWMMux(XBAR_TRIP5, XBAR_MUX00);
```

**前面的操作已将COMP的正输入信号配置成外部输入,这里需要配置负输入,COMP的负输入可以配置成来自于内部DAC或外部引脚,详细内容同样可见库函数头文件定义**

```c
//
// Comparator negative input source
//
//! Input driven by internal DAC
#define COMP_INSRC_DAC               0x0000U
//! Input driven by external pin
#define COMP_INSRC_PIN               0x0001U
```

**若配置成外部引脚,则需要根据数据手册参照步骤1使用AS\_selectCMPHPMux使能对应负输入模拟脚;这里配置连接至COMP内部DAC,参考代码如下**

```c
COMP_configHighComparator(COMP1_BASE,(COMP_INSRC_DAC));
```

**同理可以使能低电平比较器同时比较上下限**

```c
COMP_configLowComparator(myCOMP0_BASE,(COMP_INSRC_DAC));
```

**配置高(低)电平比较器阈值**

```c
COMP_setDACValueHigh(COMP7_BASE, 2048);
```

```c
COMP_setDACValueLow(COMP7_BASE, 100);
```

**配置COMP参考电压以及使能影子寄存器模式(对COMP值的修改先进入影子寄存器,可以配置延时更新实现滤波)**

```c
COMP_configDAC(COMP1_BASE,(COMP_DACVAL_SYSCLK | COMP_DACREF_VDDA | COMP_DACSRC_SHDW));
```

**这里参考电源使用内部VDDA模拟电源,若配置成VDAC则需要注意在 (B3/VDAC) 引脚上提供参考电压(使用VDAC会占用一个模拟脚B3)**

**配置滤波,COMP的外部输入可能会受到外部信号干扰而误动作,所以需要输入配置滤波**

```c
COMP_configFilterHigh(COMP7_BASE, 1, 2, 1);
```

*COMP\_configFilterHigh后三个参数分别是*采样预分频、采样窗口大小、有效信号阈值,这里是对外部输出采样,高电平为有效电平,上述函数配置采样预分频为1,为125Mhz,采样窗口为2,有效信号阈值为1表示2个采样周期内,采集到至少1个有效电平才会输出有效电平

**COMP输入滤波的一些其他配置**

```c
    COMP_initFilterHigh(COMP1_BASE);

    // CTRIPH, CTRIPOUTH output comes from digital filter
    COMP_configOutputsHigh(COMP1_BASE,
                            COMP_TRIP_FILTER |
                            COMP_TRIPOUT_FILTER);

    // 清楚滤波输出锁存信号
    COMP_clearFilterLatchHigh(COMP1_BASE);
```

**使能对应COMP模块**

```c
COMP_enableModule(COMP1_BASE);
```

**完整示例如下,配置B1引脚作为COMP7高低电平比较器的正输入,同时比较上下限是否超出设定值,配置A3作为COMP1 高电平比较器的正输入,只比较上限**

```c
#define COMP_DAC_REF_SRC      COMP_DACREF_VDDA         //内部:VDDA,外部:VDAC(需要在VDAC引脚外供电)
#define COMP_DAC_REF_VOLTAGE    (3.3f)                                // 参考电压值
#define COMP_RESOLUTION_MAX   (0x0FFF)                         // 4095

void COMP_init()
{
    int32_t dac_val_h, dac_val_l;

    /**********************************************************************************
    *********************************** B1 -> COMP7 ***********************************
    ***********************************************************************************/
    /*
   * Set upper and lower limits at the same time
   */
    const float32_t Vref_bias = 1.5f;
    const float32_t Vmax_V = 1.0f;// 0.5V - 2.5V

    dac_val_h = (Vref_bias + Vmax_V) / COMP_DAC_REF_VOLTAGE * COMP_RESOLUTION_MAX;
    dac_val_l = (Vref_bias - Vmax_V) / COMP_DAC_REF_VOLTAGE * COMP_RESOLUTION_MAX;

    dac_val_h = (dac_val_h > 4096) ? 4096 : dac_val_h;
    dac_val_l = (dac_val_l < 0)    ?    0 : dac_val_l;

    // Over-voltage protections
    AS_selectCMPHPMux(AS_CMPHPMUX_SELECT_7, 0);
    AS_selectCMPLPMux(AS_CMPLPMUX_SELECT_7, 0);

    // connect COMP output to PWM TZ via XBar
    XBAR_setPWMMuxConfig(XBAR_TRIP4, XBAR_PWM_MUX12_COMP7_CTRIPH_OR_L);
    XBAR_enablePWMMux(XBAR_TRIP4, XBAR_MUX12);

    // negative input connects to DAC
    COMP_configHighComparator(COMP7_BASE, COMP_INSRC_DAC);
    COMP_configLowComparator(COMP7_BASE, COMP_INSRC_DAC);

    // reference source is VDAC, DAC value load on SYSCLK, DAC value comes from shadow register
    COMP_configDAC(COMP7_BASE, COMP_DAC_REF_SRC | COMP_DACVAL_SYSCLK | COMP_DACSRC_SHDW);

    // Digital filter config
    // 3us window = 125MHz SYSCLK / 1 prescale / 3 sample
    COMP_configFilterHigh(COMP7_BASE, 1, 2, 1);
    COMP_configFilterLow(COMP7_BASE,1, 2, 1);

    COMP_initFilterHigh(COMP7_BASE);
    COMP_initFilterLow(COMP7_BASE);

    // CTRIPH, CTRIPOUTH output comes from digital filter
    COMP_configOutputsHigh(COMP7_BASE,
                            COMP_TRIP_FILTER |
                            COMP_TRIPOUT_FILTER);

    // CTRIPL, CTRIPOUTL output comes from digital filter, and inverted
    COMP_configOutputsLow(COMP7_BASE,
                           COMP_TRIP_FILTER |
                           COMP_TRIPOUT_FILTER |
                           COMP_INV_INVERTED);

    // Clear digital filter output latch
    COMP_clearFilterLatchHigh(COMP7_BASE);
    COMP_clearFilterLatchLow(COMP7_BASE);

    // ===== Over-current threshold value =====
    COMP_setDACValueHigh(COMP7_BASE, dac_val_h);
    COMP_setDACValueLow(COMP7_BASE, dac_val_l);

    // ===== Comp peripheral settings =====
    COMP_enableModule(COMP7_BASE);

    /**********************************************************************************
    *********************************** A3 -> COMP1 ***********************************
    ***********************************************************************************/
    dac_val_h = (Vref_bias + Vmax_V) / COMP_DAC_REF_VOLTAGE * COMP_RESOLUTION_MAX;

    // Select the value for COMP1_HP3.
    AS_selectCMPHPMux(AS_CMPHPMUX_SELECT_1, 3U);

    // Configure TRIP4 to be CTRIP1H using the PWM X-BAR
    XBAR_setPWMMuxConfig(XBAR_TRIP5, XBAR_PWM_MUX00_COMP1_CTRIPH);
    XBAR_enablePWMMux(XBAR_TRIP5, XBAR_MUX00);

    // negative input connects to DAC
    COMP_configHighComparator(COMP1_BASE, COMP_INSRC_DAC);

    COMP_configDAC(COMP1_BASE, COMP_DAC_REF_SRC | COMP_DACVAL_SYSCLK | COMP_DACSRC_SHDW);

    // COMP filter
    COMP_configFilterHigh(COMP1_BASE, 1, 2, 1);

    COMP_initFilterHigh(COMP1_BASE);

    // CTRIPH, CTRIPOUTH output comes from digital filter
    COMP_configOutputsHigh(COMP1_BASE,
                            COMP_TRIP_FILTER |
                            COMP_TRIPOUT_FILTER);

    // Clear digital filter output latch
    COMP_clearFilterLatchHigh(COMP1_BASE);

    COMP_setDACValueHigh(COMP1_BASE, dac_val_h);

    // ===== Comp peripheral settings =====
    COMP_enableModule(COMP1_BASE);

    DEVICE_DELAY_US(500);

    COMP_debugGpioConfig();
}
```

**至此,基本的COMP这一端的基本配置已经完成,接下来进行PWM端跳闸信号部分的配置,为了程序结构清晰,这里单独提取了一个函数配置各个PWM的跳闸信号,PWM的其他配置不是本文重点,完整驱动代码将作为附件形式贴在文末**

```c
void PWM_Fault_Trip_Config(void)
{
    uint32_t pwm_bases = {PWM1_BASE, PWM2_BASE, PWM3_BASE};

    for (int i = 0; i < sizeof(pwm_bases) / sizeof(uint32_t); i++) {
      uint32_t pwm_base = pwm_bases;

      // 配置跳闸后TZ的动作信号
      PWM_setTripZoneAction(pwm_base, PWM_TZ_ACTION_EVENT_TZA, PWM_TZ_ACTION_LOW);
      PWM_setTripZoneAction(pwm_base, PWM_TZ_ACTION_EVENT_TZB, PWM_TZ_ACTION_LOW);
      PWM_enableTripZoneSignals(pwm_base, PWM_TZ_SIGNAL_OSHT2);   // oneshot trip

      ////////////////////////////////////////////// Trip4 //////////////////////////////////////////////
       // TripIn signal -> DCAH signal
       PWM_enableDigitalCompareTripCombinationInput(pwm_base, PWM_DC_COMBINATIONAL_TRIPIN4, PWM_DC_TYPE_DCAH);
   
       // DCAH signal -> DCAEVT1 event
       PWM_setTripZoneDigitalCompareEventCondition(pwm_base, PWM_TZ_DC_OUTPUT_A1, PWM_TZ_EVENT_DCXH_HIGH);

       // un-filtered DCAEVT1 -> output
       PWM_setDigitalCompareEventSource(pwm_base, PWM_DC_MODULE_A, PWM_DC_EVENT_1, PWM_DC_EVENT_SOURCE_ORIG_SIGNAL);

       PWM_enableTripZoneSignals(pwm_base, PWM_TZ_SIGNAL_DCAEVT1);   

      ////////////////////////////////////////////// Trip5 //////////////////////////////////////////////
      // TripIn signal -> DCBH signal
      PWM_enableDigitalCompareTripCombinationInput(pwm_base, PWM_DC_COMBINATIONAL_TRIPIN5, PWM_DC_TYPE_DCBH);

      // DCBH signal -> DCBEVT2 event
      PWM_setTripZoneDigitalCompareEventCondition(pwm_base, PWM_TZ_DC_OUTPUT_B2, PWM_TZ_EVENT_DCXH_HIGH);

      // un-filtered DCBEVT2 -> output
      PWM_setDigitalCompareEventSource(pwm_base, PWM_DC_MODULE_B, PWM_DC_EVENT_2, PWM_DC_EVENT_SOURCE_ORIG_SIGNAL);

      PWM_enableTripZoneSignals(pwm_base, PWM_TZ_SIGNAL_DCBEVT2);
    }
}
```

**所有配置完成后就可以搭配示波器和直流数字电源上进行测试了**

**附:PWM可选择配置的跳闸事件如下,其中Cycle By Cycle表示逐周期的信号,触发跳闸的事件消失后PWM将在下一个周期立刻恢复,而One-shot则需要清除标志位才能恢复PWM输出**

```c
//*****************************************************************************
//
// Values that can be passed to PWM_enableTripZoneSignals() and
// PWM_disableTripZoneSignals() as the tzSignal parameter.
//
//*****************************************************************************
//! TZ1 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC1          0x1U
//! TZ2 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC2          0x2U
//! TZ3 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC3          0x4U
//! TZ4 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC4          0x8U
//! TZ5 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC5          0x10U
//! TZ6 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_CBC6          0x20U
//! DCAEVT2 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_DCAEVT2       0x40U
//! DCBEVT2 Cycle By Cycle
//!
#define PWM_TZ_SIGNAL_DCBEVT2       0x80U
//! One-shot TZ1
//!
#define PWM_TZ_SIGNAL_OSHT1         0x100U
//! One-shot TZ2
//!
#define PWM_TZ_SIGNAL_OSHT2         0x200U
//! One-shot TZ3
//!
#define PWM_TZ_SIGNAL_OSHT3         0x400U
//! One-shot TZ4
//!
#define PWM_TZ_SIGNAL_OSHT4         0x800U
//! One-shot TZ5
//!
#define PWM_TZ_SIGNAL_OSHT5         0x1000U
//! One-shot TZ6
//!
#define PWM_TZ_SIGNAL_OSHT6         0x2000U
//! One-shot DCAEVT1
//!
#define PWM_TZ_SIGNAL_DCAEVT1       0x4000U
//! One-shot DCBEVT1
//!
#define PWM_TZ_SIGNAL_DCBEVT1       0x8000U
```

## COMP常见应用场景

### 1. 峰值电流模式控制

**作用**:在峰值电流模式控制中,DSP比较器用于监测和限制开关电源中的峰值电流,以确保系统在安全范围内运行,并提高效率。

**原理:DSP比较器通过实时采样电流信号,并将其与预设的峰值电流阈值进行比较。当检测到电流超过该阈值时,DSP会立即发出控制信号,调整开关器件的占空比,从而限制电流继续上升,防止过流损坏。**

### 2. 开关电源

**作用**:在开关电源中,DSP比较器用于实现精确的电压和电流控制,确保输出电压稳定,并提高电源的响应速度和效率。

**原理**:DSP比较器通过采样输出电压和电流信号,与参考值进行比较。根据比较结果,DSP调整PWM(脉宽调制)信号的占空比,控制开关器件的导通和关断时间,从而稳定输出电压。

### 3. 电压跳闸监测

**作用**:在电压跳闸监测中,DSP比较器用于实时监测系统电压,并在电压异常时迅速切断电源,保护设备和系统安全。

**原理:DSP比较器通过采样系统电压信号,与预设的电压阈值进行比较。当检测到电压超过或低于安全范围时,DSP立即发出跳闸信号,切断电源,防止设备损坏。**

[!(/source/plugin/zhanmishu_markdown/template/editor/images/upload.svg) 附件:driver.zip](forum.html?mod=attachment&aid=2430426 "attachment")

wmj258034 发表于 2025-8-2 15:13

@21小跑堂

wmj258034 发表于 2025-8-2 15:26

@21小跑堂

wangwu1976@ 发表于 2025-9-18 13:34

支持原创

cooldog123pp 发表于 2025-9-27 09:04

wangwu1976@ 发表于 2025-9-18 13:34
支持原创

原创确实不易,需要把过程总结出来呈现给大家,其实很耗费时间。
页: [1]
查看完整版本: G32R501 COMP比较器使用笔记