5.2 COMP Guide
This chapter describes the file layout and the 18 public functions of the COMP driver in the N32G033 standard peripheral library, together with the 2 examples (COMP_OUT and CompBrake). Read the “COMP” chapter of the user manual for the input selection, hysteresis, filter, and output blanking, and the errata sheet for known chip issues.
5.2.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32g033_std_periph_driver/inc/n32g033_comp.h |
Defines the COMP_InitType structure and the macros for clock selection, operation mode, lock, output polarity, inverting and non-inverting input selection, filter prescaler, blanking, and hysteresis, and declares 18 public functions in one contiguous block |
firmware/n32g033_std_periph_driver/src/n32g033_comp.c |
Implements those 18 functions: COMP reset and initialization, input and hysteresis configuration, filter configuration, output blanking, and flag and interrupt handling |
projects/n32g033_EVAL/examples/COMP/ |
COMP example root directory, with 2 examples: COMP_OUT and CompBrake |
projects/n32g033_EVAL/examples/COMP/COMP_OUT/ |
Project layout of this example: MDK-ARM/, EWARM/, inc/, src/, and readme.txt |
projects/n32g033_EVAL/bsp/ |
Board support files shared by the examples: the SysTick millisecond delay in delay.h |
5.2.2 API reference
The following 18 public functions are listed in the declaration order of n32g033_comp.h in 1 group; each entry gives a summary and the original comment above the function in n32g033_comp.c.
Reset, initialization, and run configuration
COMP_DeInit, COMP_StructInit, COMP_Init, COMP_SetFilterControl, COMP_SetFilterPrescaler, COMP_SetHyst, COMP_OutputPolarityConfig, COMP_SetInpSel, COMP_SetInmSel, COMP_Enable, COMP_SetIntEn, COMP_GetIntStatus, COMP_GetOutStatus, COMP_IntStatusClear, COMP_SetLock, COMP_SetRefScl, COMP_SetBlking, COMP_VREF_Enable
void COMP_DeInit(void)Reset the COMP registers.
name COMP_DeInit.
fun Reset the COMP registers.
return none
void COMP_StructInit(COMP_InitType* COMP_InitStruct)Fills all COMP_initstruct member with default value.
name COMP_StructInit.
fun Fills all COMP_initstruct member with default value.
param COMP_initstruct :
- ClockSelect
- LowPoweMode
- Blking
- Hyst
- PolRev
- InpSel
- InmSel
- FilterEn
- SampWindow
- Threshold
- ClkPsc
- En
return none
void COMP_Init( COMP_InitType* COMP_InitStruct)Initializes the COMP peripheral according to the specified parameters in the COMP_InitStruct
name COMP_Init.
fun Initializes the COMP peripheral according to the specified parameters in the COMP_InitStruct
param COMP_initstruct :
param Clksel :
- COMP_CLKSEL_SYSTEMCLK
- COMP_CLKSEL_LSX
param Pwrmd :
- COMP_CTRL_PWRMD_NORMAL
- COMP_CTRL_PWRMD_LOWPWR
param Blking :
- COMP_BLANKING_NO
- COMP_BLANKING_TIM1_OC5
param Hyst :
- COMP_CTRL_HYST_NO
- COMP_CTRL_HYST_LOW
- COMP_CTRL_HYST_MID
- COMP_CTRL_HYST_HIGH
param PolRev :
- COMP_OUTPOL_REV
- COMP_OUTPOL_NREV
param InpSel :
- COMP_INPSEL_PA1
- COMP_INPSEL_PA3
- COMP_INPSEL_PA7
- COMP_INPSEL_PA8
- COMP_INPSEL_PA9
- COMP_INPSEL_PA10
- COMP_INPSEL_PA12
- COMP_INPSEL_OPAMP1
- COMP_INPSEL_OPAMP2
- COMP_INPSEL_OPAMP3
param InmSel :
- COMP
- COMP_INMSEL_PA0
- COMP_INMSEL_PA4
- COMP_INMSEL_PA5
- COMP_INMSEL_PA11
- COMP_INMSEL_VREF_DAC
param ClkPsc:
Value can be set from 0 to 65535.
param FilterEn:
- ENABLE
- DISABLE
param Threshold:
- this value must be greater than SAMPW / 2 .
param SampWindow:
- from 0 to 31.
param En
- ENABLE
- DISABLE
return none
void COMP_SetFilterControl(uint8_t FilEn, uint8_t TheresNum, uint8_t SampPW)Configure the COMP filter value.
name COMP_SetFilterControl.
fun Configure the COMP filter value.
param FilEn:
- ENABLE.
- DISABLE.
param TheresNum:
- this value must be greater than SAMPW / 2 .
param SampPW:
- from 0 to 31.
return none
void COMP_SetFilterPrescaler(uint16_t FilPreVal)Configure The COMP low filter prescale.
name COMP_Filter_Clock_Prescale_Config.
fun Configure The COMP low filter prescale.
param FilPreVal:
Value can be set from 0 to 65535.
return none
Use note: Line 161 of n32g033_comp.h declares COMP_SetFilterPrescaler, while the comment above it gives the name as COMP_Filter_Clock_Prescale_Config., which differs from the function name.
void COMP_SetHyst(uint32_t HYST)Configure COMP hysteresis level.
name COMP_SetHyst.
fun Configure COMP hysteresis level.
param HYST :
- COMP_CTRL_HYST_NO
- COMP_CTRL_HYST_LOW
- COMP_CTRL_HYST_MID
- COMP_CTRL_HYST_HIGH
return none
void COMP_OutputPolarityConfig(uint32_t POL)Configures COMP output signal polarity overturn or not.
name COMP_OutputPolarityConfig.
fun Configures COMP output signal polarity overturn or not.
param POL :
- COMP_OUTPOL_REV
- COMP_OUTPOL_NREV
return none
void COMP_SetInpSel(uint32_t VpSel)Configures COMP inpsel input selection.
name COMP_SetInpSel.
fun Configures COMP inpsel input selection.
param vpsel :
- COMP_INPSEL_OPAMP1
- COMP_INPSEL_OPAMP2
- COMP_INPSEL_OPAMP3
- COMP_INPSEL_PA1
- COMP_INPSEL_PA3
- COMP_INPSEL_PA7
- COMP_INPSEL_PA8
- COMP_INPSEL_PA9
- COMP_INPSEL_PA10
- COMP_INPSEL_PA12
return none
void COMP_SetInmSel(uint32_t VmSel)Configures COMP inmsel input selection..
name COMP_SetInmSel.
fun Configures COMP inmsel input selection..
param VmSel :
- COMP_INMSEL_VREF_DAC
- COMP_INMSEL_PA0
- COMP_INMSEL_PA4
- COMP_INMSEL_PA5
- COMP_INMSEL_PA11
return none
void COMP_Enable(FunctionalState Cmd)Enable or disable COMP peripheral.
name COMP_Enable.
fun Enable or disable COMP peripheral.
param Cmd new state of the COMP peripheral.
-ENABLE
-DISABLE
return none
void COMP_SetIntEn(FunctionalState Cmd)Enable or disable COMP interrupt .
name COMP_SetIntEn.
fun Enable or disable COMP interrupt .
param Cmd new state of the COMP peripheral.
-ENABLE
-DISABLE
return none
FlagStatus COMP_GetIntStatus(void)Get COMPx interrupt flag .
name COMP_GetIntStatus.
fun Get COMPx interrupt flag .
return FlagStatus:
- SET
- RESET
FlagStatus COMP_GetOutStatus(void)Get COMP result Status.
name COMP_GetOutStatus.
fun Get COMP result Status.
return FlagStatus:
- SET
- RESET
void COMP_IntStatusClear(void)Clear COMP interrupt flag.
name COMP_IntStatusClear.
fun Clear COMP interrupt flag.
return none
void COMP_SetLock(void)Enable COMP Lock .
name COMP_SetIntEn.
fun Enable COMP Lock .
return none
Use note: Line 171 of n32g033_comp.h declares COMP_SetLock, while the comment above it gives the name as COMP_SetIntEn., which differs from the function name.
void COMP_SetRefScl(uint8_t Vv1Trim, bool Vv1En)Set Reference Volatge Scale of Vv1 .
name COMP_SetRefScl.
fun Set Reference Volatge Scale of Vv1 .
param Vv1Trim :
- this data range of 0-0xff
param Vv1En :
- false
- true
return none
void COMP_SetBlking(uint32_t blking_mode)Configures TIM1 output signal to control COMP Blking.
name COMP_SetBlking.
fun Configures TIM1 output signal to control COMP Blking.
param blking_mode :
- COMP_BLANKING_NO
- COMP_BLANKING_TIM1_OC5
return none
void COMP_VREF_Enable(FunctionalState Cmd)Enable or disable COMP internal voltage dac.
name COMP_VREF_Enable.
fun Enable or disable COMP internal voltage dac.
param Cmd new state of the COMP peripheral.
-ENABLE
-DISABLE
return none
5.2.3 Demo descriptions
This section describes the 2 COMP examples: COMP_OUT toggles the comparator inputs with two GPIOs and watches the output flip, and CompBrake feeds the comparator output into the TIM1 break input to stop a complementary PWM.
5.2.3.1 COMP_OUT Comparator output toggle
Example directory: projects/n32g033_EVAL/examples/COMP/COMP_OUT/
Enable the GPIO, COMP, and filter clocks→Configure PA0 and PA1 as analog inputs and PB0 and PB1 as push-pull outputs→Initialize the comparator and enable its filter and interrupt→Toggle PB0 and PB1 in the main loop to change the differential input→Trigger the line interrupt when the output flips
| Item | Source analysis |
|---|---|
| Function | Drives PB0 and PB1 high and low in turn and feeds them over jumper wires to the inverting and non-inverting inputs, then watches the output flip through the comparator interrupt on EXTI line 8. |
| Source files | src/main.c holds ChangeVmVp, COMP_Configuration, RCC_Configuration, GPIO_Configuration, EXTI_Configuration, and NVIC_Configuration;COMP_IRQHandler in src/n32g033_it.c and inc/n32g033_it.h clears the interrupt flags;inc/main.h and readme.txt give the declarations and test steps;the project files are in MDK-ARM/ and EWARM/. |
| Key configuration | Pins: PA0 as the inverting input, PA1 as the non-inverting input, and PA6 as the comparator output alternate function; PB0 and PB1 as push-pull outputs; Comparator: sample window 31, threshold 18, filter enabled, low hysteresis; Interrupt: EXTI line 8 on a rising edge with COMP_IRQn at priority 0. |
| Program and data path | main -> RCC_Configuration enables the GPIO, COMP, and filter clocks -> NVIC_Configuration enables the COMP interrupt -> GPIO_Configuration configures the three pins -> EXTI_Configuration sets EXTI line 8 as a rising-edge interrupt -> COMP_Configuration initializes and enables the comparator -> the main loop calls ChangeVmVp to toggle PB0 and PB1 every 50 ms -> COMP_IRQHandler clears the flags when the output flips. |
| Main APIs | COMP_StructInit, COMP_Init, COMP_SetIntEn, COMP_Enable, COMP_IntStatusClear |
| Verification | Connect PA0 to PB0 and PA1 to PB1 with jumper wires and watch PA6 with an oscilloscope or logic analyzer; as the main loop toggles the input every 50 ms, PA6 goes high when the non-inverting input is above the inverting input and low otherwise. |
| Use note | The development environment is KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1 on the N32G033K8Q7-1_STB V1.0 evaluation board; the system clock is 64 MHz. |
Core-code walkthrough and porting
The example drives the comparator differential inputs from two GPIOs and takes an interrupt on EXTI line 8 when the output flips.
Data path: RCC_Configuration enables the GPIO, COMP, and filter clocks → GPIO_Configuration configures PA0, PA1, PB0, and PB1 → COMP_Configuration calls COMP_StructInit and COMP_Init → ChangeVmVp toggles PB0 and PB1 to change the differential input → the output flip sets the interrupt on EXTI line 8 → COMP_IRQHandler calls COMP_IntStatusClear to clear the flag
1. Enable the comparator, the filter, and the GPIO clocks together. The comparator, the sampling filter, and the pins sit on different peripheral clock bits, so all of them must be enabled before configuration.
void RCC_Configuration(void)
{
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable GPIO COMP clocks */
RCC_EnableAPBPeriphClk(RCC_APB_PERIPH_GPIO | RCC_APB_PERIPH_COMP | RCC_APB_PERIPH_COMPFILT, ENABLE);
}
Missing the filter clock leaves the later filter setting without effect; when you move to another port, confirm that the matching GPIO clock bit is on.
2. Give the inputs, hysteresis, and filter in a single structure. InpSel and InmSel pick the differential input pins, while SampWindow and Threshold set the operating point of the sampling filter.
COMP_InitType COMP_Initial;
/*Initial comp*/
COMP_StructInit(&COMP_Initial);
COMP_Initial.InpSel = COMP_INPSEL_PA1;
COMP_Initial.InmSel = COMP_INMSEL_PA0;
COMP_Initial.SampWindow = 31; //(0~31)
COMP_Initial.Threshold = 18; //(0~31)
COMP_Initial.FilterEn = ENABLE;
COMP_Initial.Hyst = COMP_CTRL_HYST_LOW;
COMP_Init(&COMP_Initial);
Threshold must be greater than half of SampWindow; keep that constraint when you change the sampling parameters.
3. The output pin must be configured as alternate-function push-pull. The comparator result goes to PA6 through its alternate function, whereas the two input pins are analog inputs.
GPIO_InitStruct(&GPIO_InitStructure);
/* Configure INP INM PA0 PA1 as analog input -----------------------*/
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_ANALOG;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* Configure PB0 PB1 as analog input -----------------------*/
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
/* OutSel */
GPIO_InitStructure.Pin = GPIO_PIN_6;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.GPIO_Alternate = GPIO_AF8;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
The comparator inputs use analog channels and the output uses an alternate-function channel, so the two pin types are not configured the same way.
4. In the handler, clear the EXTI pending bit before the comparator flag. The output flip raises the interrupt on EXTI line 8, and both flags must be cleared or the interrupt re-enters.
void COMP_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_LINE8))
{
EXTI_ClrITPendBit(EXTI_LINE8);
COMP_IntStatusClear();
}
}
When you move to another EXTI line, change the line number here together with the setting in EXTI_Configuration.
Corresponding source files: src/main.c, src/n32g033_it.c, firmware/n32g033_std_periph_driver/inc/n32g033_comp.h
5.2.3.2 CompBrake Comparator brakes TIM1
Example directory: projects/n32g033_EVAL/examples/COMP/CompBrake/
Enable the GPIO, COMP, TIM1, and filter clocks→Configure the differential inputs and the TIM1 complementary output pins→Initialize the comparator and tie it to the TIM1 break source→Toggle the differential input in the main loop→The comparator output trips the break and the PWM stops
| Item | Source analysis |
|---|---|
| Function | Adds a TIM1 complementary PWM to the COMP_OUT differential input and wires the comparator output into the TIM1 break input; when the non-inverting input rises above the inverting input the PWM stops and the comparator output PA6 is high. |
| Source files | src/main.c holds ChangeVmVp, COMP_Configuration, TIM_Configuration, RCC_Configuration, GPIO_Configuration, EXTI_Configuration, and NVIC_Configuration;COMP_IRQHandler in src/n32g033_it.c and inc/n32g033_it.h clears the interrupt flags;inc/main.h and readme.txt give the declarations and test steps;the project files are in MDK-ARM/ and EWARM/. |
| Key configuration | Pins: PA0 as the inverting input, PA1 as the non-inverting input, and PA6 as the comparator output alternate function; PB0 and PB1 as push-pull outputs, PB3 as the TIM1_CH1 alternate function and PB4 as the TIM1_CH1N alternate function; TIM1: up-counting, period 1600, pulse 800, dead time 11, main and complementary outputs enabled, break input taken from COMP1; Comparator: sample window 31, threshold 18, filter enabled, low hysteresis. |
| Program and data path | main -> RCC_Configuration enables the GPIO, COMP, TIM1, and filter clocks -> GPIO_Configuration configures the input, output, and complementary PWM pins -> COMP_Configuration initializes the comparator -> TIM_Configuration sets up the time base, PWM, and break -> the main output and the counter are enabled -> the main loop calls ChangeVmVp to toggle the differential input every 10 ms -> the comparator output trips the break. |
| Main APIs | COMP_StructInit, COMP_Init, COMP_SetIntEn, COMP_Enable, COMP_IntStatusClear |
| Verification | Connect PA0 to PB0 and PA1 to PB1 with jumper wires and watch PA6, PB3, and PB4 with an oscilloscope; when the non-inverting input is above the inverting input the TIM1 waveform disappears and PA6 is high, and otherwise the waveform returns and PA6 is low. |
| Use note | The development environment is KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1 on the N32G033K8Q7-1_STB V1.0 evaluation board; the TIM1 break input is controlled by both the main output enable and the break configuration. |
Core-code walkthrough and porting
On top of the comparator, the example adds a TIM1 complementary PWM and wires the comparator output into the break input.
Data path: RCC_Configuration enables the GPIO, COMP, TIM1, and filter clocks → TIM_Configuration sets up the time base and complementary PWM and points the break source at COMP1 → TIM_EnableCtrlPwmOutputs enables the main output → ChangeVmVp toggles the differential input → the comparator output trips the break and the PWM stops → COMP_IRQHandler clears the comparator flag
1. Set up the time base and the complementary PWM in one go. The core clock is first divided down to 16 MHz and then folded by a period of 1600 into the PWM frequency; channel 1 enables both the normal and the complementary output, and the pulse value sets the duty cycle.
PrescalerValue = (uint32_t)(SystemCoreClock / 16000000) - 1;
/* Time base configuration */
TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.Period = 1600;
TIM_TimeBaseStructure.Prescaler = PrescalerValue;
TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
TIM_TimeBaseStructure.CounterMode = TIM_CNT_MODE_UP;
TIM_InitTimeBase(TIM1, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_InitOcStruct(&TIM_OCInitStructure);
TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1;
TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
TIM_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_ENABLE;
TIM_OCInitStructure.Pulse = Channel1Pulse;
TIM_OCInitStructure.OCPolarity = TIM_OC_POLARITY_HIGH;
TIM_OCInitStructure.OCNPolarity = TIM_OC_POLARITY_HIGH;
TIM_InitOc1(TIM1, &TIM_OCInitStructure);
TIM_ConfigOc1Preload(TIM1, TIM_OC_PRE_LOAD_ENABLE);
When you change the PWM frequency, adjust PrescalerValue and Period together; the complementary output must be enabled for the break feature to be usable.
2. Both the break feature and the break source go into the BDTR setup. Enable the break, choose its active polarity, turn on automatic output, and then point the break input source at comparator 1.
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_InitBkdtStruct(&TIM_BDTRInitStructure);
TIM_BDTRInitStructure.OSSRState = TIM_OSSR_STATE_ENABLE;
TIM_BDTRInitStructure.OSSIState = TIM_OSSI_STATE_ENABLE;
TIM_BDTRInitStructure.LOCKLevel = TIM_LOCK_LEVEL_OFF;
TIM_BDTRInitStructure.DeadTime = 11;
TIM_BDTRInitStructure.Break = TIM_BREAK_IN_ENABLE;
TIM_BDTRInitStructure.BreakPolarity = TIM_BREAK_POLARITY_HIGH;
TIM_BDTRInitStructure.AutomaticOutput = TIM_AUTO_OUTPUT_ENABLE;
TIM_ConfigBkdt(TIM1, &TIM_BDTRInitStructure);
TIM_BreakInputSourceEnable(TIM1,TIM_BREAK_COMP1,TIM_BREAK_IOM_COMP_POLARITY_NONINVERT,ENABLE);
The break input source maps one-to-one to a comparator instance, so switch the break source enumeration when you use a different comparator.
3. Enable the main output and the counter after power-up. A complementary PWM needs the main-output enable signal, which a plain timer does not.
/* TIM1 Main Output Enable */
TIM_EnableCtrlPwmOutputs(TIM1, ENABLE);
/* TIM1 counter enable */
TIM_Enable(TIM1, ENABLE);
Enable the main output before starting the counter so that no uncontrolled narrow pulse appears at start-up.
4. The comparator handler clears the flags. When the comparator output flips, the interrupt is raised on EXTI line 8, and the handler clears the EXTI pending bit and the comparator interrupt flag.
void COMP_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_LINE8))
{
EXTI_ClrITPendBit(EXTI_LINE8);
COMP_IntStatusClear();
}
}
The handler is the same as in COMP_OUT; when you attach the comparator to another timer, the changes stay in the break configuration and do not touch this code.
Corresponding source files: src/main.c, src/n32g033_it.c, firmware/n32g033_std_periph_driver/inc/n32g033_comp.h
5.2.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| Sampling filter threshold | The COMP chapter of the user manual states that the threshold must be greater than half of the sample window, otherwise the filter result is unreliable; keep that constraint when you change Threshold and SampWindow. |
User manual |
| Output blanking source | The COMP chapter of the user manual states that blanking is driven by the output compare event of TIM1; confirm that the timer channel matches the blanking source. |
User manual |
| STOP and low-power modes | The COMP chapter of the user manual states that the comparator clock can switch to the system clock or LSX in low-power run; choose the clock source as needed before entering low power and confirm the wake-up path. |
User manual |
| Alternate-function output pin | The COMP chapter of the user manual states that the comparator output reaches the pin through a fixed alternate-function channel; set the matching alternate-function number from the mapping table when you change the pin. |
User manual |
Errata sheet V1.0.0 (2025.9.25) covers revision A silicon and lists no COMP entries.