5.1 ADC Guide

This chapter describes the file composition and the 44 public functions of the ADC driver in the N32G41x standard peripheral library: reset and initialization, regular-channel and injected-channel conversion control, software and external trigger configuration, multi-ADC cooperation, the analog watchdog, the temperature sensor and internal reference, oversampling, offset compensation, interrupt and flag management and the ADC clock configuration; it also describes 9 example projects. Read the register bit definitions, the dual-ADC modes and the sampling timing together with the “Analog/digital converter (ADC)” chapter of the user manual, and take the errata sheet as the authority on known chip issues.

5.1.1 Related files

Relative path Purpose
firmware/n32g41x_std_periph_driver/inc/n32g41x_adc.h Defines the ADC_InitType and ADC_OffsetType structures and the configuration macros for work mode, channels, sample times, trigger sources, the analog watchdog, oversampling and offset, and declares the 44 public functions of the API reference in eleven sections
firmware/n32g41x_std_periph_driver/src/n32g41x_adc.c Implements those 44 functions: power-up and ready polling, sequencer length and channel rank writes, software and external trigger starts, analog watchdog threshold and channel configuration, oversampling and offset register configuration, and flag and interrupt management
projects/n32g41x_EVAL/examples/ADC/ ADC example root directory, holding the 9 examples ADC_Offset, ADC_SingleRead, ADC_TEMP, ADC1_DMA, ADC1_Oversampling, AnalogWatchdog, ExtLinesTrigger, RegSimul_DualMode and TIMTrigger_AutoInjection
projects/n32g41x_EVAL/examples/ADC/ADC1_DMA/ Layout of that example: MDK-ARM/, EWARM/, inc/, src/, readme.txt
projects/n32g41x_EVAL/bsp/ Board support files shared by the examples: evaluation-board LED and key definitions, a millisecond delay function and a UART logging interface

5.1.2 API reference

Search API44 functions

The following 44 public functions are listed in the declaration order of n32g41x_adc.h in 11 groups; each entry gives a summary and the original comment above the function in n32g41x_adc.c.

Reset and initialization

ADC_DeInit, ADC_Init, ADC_InitStruct, ADC_Enable, ADC_EnableDMA

Regular conversion control

ADC_EnableSoftwareStartConv, ADC_GetSoftwareStartConvStatus, ADC_StopRegularConv, ADC_ConfigRegularChannel, ADC_GetDat, ADC_GetMutiModeConversionDat, ADC_ConfigDiscModeChannelCount, ADC_EnableDiscMode

Injected conversion control

ADC_EnableSoftwareStartInjectedConv, ADC_GetSoftwareStartInjectedConvCmdStatus, ADC_StopInjectedConv, ADC_ConfigInjectedChannel, ADC_ConfigInjectedSequencerLength, ADC_GetInjectedConversionDat, ADC_EnableAutoInjectedConv, ADC_EnableInjectedDiscMode

Trigger configuration

ADC_SetRegularTriggerEdge, ADC_SetInjectTriggerEdge, ADC_ConfigExternalTrigInjectedConv, ADC_ConfigExternalTrigRegularConv, ADC_ConfigRegularExtLineTrigSource, ADC_ConfigInjectedExtLineTrigSource

Multi-mode configuration

ADC_SetMultiTwoSamplingDelay

Analog watchdog

ADC_ConfigAnalogWatchdogWorkChannelType, ADC_ConfigAnalogWatchdogThresholds, ADC_ConfigAnalogWatchdogSingleChannel

Temperature sensor and internal reference

ADC_EnableTempSensorVrefint, Reference_VoltageSelect

Oversampling

ADC_ConfigOverSamplingRatioAndShift, ADC_SetOverSamplingScope, ADC_EnableOverSamplingDiscont

Offset

ADC_SetOffsetConfig, ADC_GetOffsetConfig

Interrupt and flag management

ADC_GetFlagStatus, ADC_ClearFlag, ADC_ConfigInt, ADC_GetIntStatus, ADC_ClearIntPendingBit

Clock configuration

ADC_ClockModeConfig

void ADC_DeInit(const ADC_Module *ADCx)Reset the ADC registers.
Source comment
name    ADC_DeInit.
fun     Reset the ADC registers.
param   ADCx :
          - ADC1
          - ADC2
return  none
void ADC_Init(ADC_Module *ADCx, const ADC_InitType *ADC_InitParam)Initializes the ADCx peripheral according to the specified parameters in the ADC_InitParam.
Source comment
name    ADC_Init.
fun     Initializes the ADCx peripheral according to the specified parameters in the ADC_InitParam.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_InitParam :
          - WorkMode
             - ADC_WORKMODE_INDEPENDENT
             - ADC_WORKMODE_DUAL_REG_INJECT_SIMULT
             - ADC_WORKMODE_DUAL_INJ_SIMULT
             - ADC_WORKMODE_DUAL_REG_SIMULT
             - ADC_WORKMODE_DUAL_INTERL
             - ADC_WORKMODE_DUAL_ALTER_TRIG
          - MultiChEn
             - ENABLE
             - DISABLE
          - ContinueConvEn
             - ENABLE
             - DISABLE
          - ExtTrigSelect
             - ADC_EXT_TRIG_REG_CONV_ATIM1_TRGO
             - ADC_EXT_TRIG_REG_CONV_ATIM1_TRGO2
             - ADC_EXT_TRIG_REG_CONV_ATIM1_CC1
             - ADC_EXT_TRIG_REG_CONV_ATIM1_CC2
             - ADC_EXT_TRIG_REG_CONV_ATIM1_CC3
             - ADC_EXT_TRIG_REG_CONV_ATIM1_CC4
             - ADC_EXT_TRIG_REG_CONV_ATIM2_TRGO
             - ADC_EXT_TRIG_REG_CONV_ATIM2_CC1
             - ADC_EXT_TRIG_REG_CONV_ATIM2_CC4
             - ADC_EXT_TRIG_REG_CONV_GTIM1_TRGO
             - ADC_EXT_TRIG_REG_CONV_GTIM1_CC2
             - ADC_EXT_TRIG_REG_CONV_GTIM1_CC4
             - ADC_EXT_TRIG_REG_CONV_GTIM2_TRGO
             - ADC_EXT_TRIG_REG_CONV_GTIM2_CC1
             - ADC_EXT_TRIG_REG_CONV_GTIM2_CC4
             - ADC_EXT_TRIG_REG_CONV_GTIM3_TRGO
             - ADC_EXT_TRIG_REG_CONV_GTIM3_CC1
             - ADC_EXT_TRIG_REG_CONV_GTIM3_CC2
             - ADC_EXT_TRIG_REG_CONV_GTIM3_CC4
             - ADC_EXT_TRIG_REG_CONV_GTIM4_TRGO
             - ADC_EXT_TRIG_REG_CONV_GTIM4_CC1
             - ADC_EXT_TRIG_REG_CONV_GTIM4_CC2
             - ADC_EXT_TRIG_REG_CONV_GTIM4_CC4
             - ADC_EXT_TRIG_REG_CONV_BTIM1_TRGO
             - ADC_EXT_TRIG_REG_CONV_EXT_INT0_15
             - ADC_EXT_TRIG_REG_CONV_SOFTWARE
          - DatAlign
             - ADC_DAT_ALIGN_R
             - ADC_DAT_ALIGN_L
          - ChsNumber: This parameter must be between 1 to 16.
return  none
void ADC_InitStruct(ADC_InitType *ADC_InitStructure)Fills all ADC_InitStructure member with default value.
Source comment
name    ADC_InitStruct.
fun     Fills all ADC_InitStructure member with default value.
param   ADC_InitStructure :
          - WorkMode
          - MultiChEn
          - ContinueConvEn
          - ExtTrigSelect
          - DatAlign
          - ChsNumber
return  none
void ADC_Enable(ADC_Module *ADCx, FunctionalState Cmd)Configures the specified ADC enable or disable.
Source comment
name    ADC_Enable.
fun     Configures the specified ADC enable or disable.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_EnableDMA(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the specified ADC DMA request.
Source comment
name    ADC_EnableDMA.
fun     Enables or disables the specified ADC DMA request.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_EnableSoftwareStartConv(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the selected ADC software start conversion.
Source comment
name    ADC_EnableSoftwareStartConv.
fun     Enables or disables the selected ADC software start conversion.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
FlagStatus ADC_GetSoftwareStartConvStatus(const ADC_Module *ADCx)Gets the selected ADC Software start conversion Status.
Source comment
name    ADC_GetSoftwareStartConvStatus.
fun     Gets the selected ADC Software start conversion Status.
param   ADCx :
          - ADC1
          - ADC2
return The new state of ADC software start conversion (SET or RESET).
void ADC_StopRegularConv(ADC_Module *ADCx)Stop ADC group regular channels conversion.
Source comment
name    ADC_StopRegularConv.
fun     Stop ADC group regular channels conversion.
param   ADCx :
          - ADC1
          - ADC2
return  none
void ADC_ConfigRegularChannel(ADC_Module *ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)Configures for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
Source comment
name    ADC_ConfigRegularChannel.
fun     Configures for the selected ADC regular channel its corresponding
        rank in the sequencer and its sample time.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_Channel :
          - ADC_CH_0 : ADC Channel0 selected
          - ADC_CH_1 : ADC Channel1 selected
          - ADC_CH_2 : ADC Channel2 selected
          - ADC_CH_3 : ADC Channel3 selected
          - ADC_CH_4 : ADC Channel4 selected
          - ADC_CH_5 : ADC Channel5 selected
          - ADC_CH_6 : ADC Channel6 selected
          - ADC_CH_7 : ADC Channel7 selected
          - ADC_CH_8 : ADC Channel8 selected
          - ADC_CH_9 : ADC Channel9 selected
          - ADC_CH_10 : ADC Channel10 selected
          - ADC_CH_11 : ADC Channel11 selected
          - ADC_CH_12 : ADC Channel12 selected
          - ADC_CH_13 : ADC Channel13 selected
          - ADC_CH_14 : ADC Channel14 selected
          - ADC_CH_15 : ADC Channel15 selected
          - ADC_CH_16 : ADC Channel16 selected
          - ADC_CH_17 : ADC Channel17 selected
param   Rank : The rank in the regular group sequencer. This parameter must be between 1 to 16.
param   ADC_SampleTime : The sample time value to be set for the selected channel.
          - ADC_SAMP_TIME_CYCLES_4
          - ADC_SAMP_TIME_CYCLES_6
          - ADC_SAMP_TIME_CYCLES_8
          - ADC_SAMP_TIME_CYCLES_14
          - ADC_SAMP_TIME_CYCLES_29
          - ADC_SAMP_TIME_CYCLES_42
          - ADC_SAMP_TIME_CYCLES_56
          - ADC_SAMP_TIME_CYCLES_72
          - ADC_SAMP_TIME_CYCLES_88
          - ADC_SAMP_TIME_CYCLES_120
          - ADC_SAMP_TIME_CYCLES_182
          - ADC_SAMP_TIME_CYCLES_240
          - ADC_SAMP_TIME_CYCLES_300
          - ADC_SAMP_TIME_CYCLES_400
          - ADC_SAMP_TIME_CYCLES_480
          - ADC_SAMP_TIME_CYCLES_600
return  none
uint16_t ADC_GetDat(const ADC_Module *ADCx)Get the last ADCx conversion result data for regular channel
Source comment
name    ADC_GetDat.
fun     Get the last ADCx conversion result data for regular channel
param   ADCx :
          - ADC1
          - ADC2
return  The Data conversion value.
uint32_t ADC_GetMutiModeConversionDat(void)Get the last ADC conversion result data in dual-ADC mode.
Source comment
name    ADC_GetMutiModeConversionDat.
fun     Get the last ADC conversion result data in dual-ADC mode.
return  The Data conversion value in dual-ADC mode.
void ADC_ConfigDiscModeChannelCount(ADC_Module *ADCx, uint8_t Number)Configures the discontinuous numbers for the selected ADC regular group channels.
Source comment
name    ADC_ConfigDiscModeChannelCount.
fun     Configures the discontinuous numbers for the selected ADC regular
        group channels.
param   ADCx :
          - ADC1
          - ADC2
param   Number : specifies the discontinuous mode regular channel
        count value. This number must be range from 1 to 8.
return  none
void ADC_EnableDiscMode(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the discontinuous mode on regular group channel for the specified ADC.
Source comment
name    ADC_EnableDiscMode.
fun     Enables or disables the discontinuous mode on regular group
        channel for the specified ADC.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_EnableSoftwareStartInjectedConv(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the selected ADC start of the injected channels conversion.
Source comment
name    ADC_EnableSoftwareStartInjectedConv.
fun    Enables or disables the selected ADC start of the injected channels conversion.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(const ADC_Module *ADCx)Gets the selected ADC Software start injected conversion Status.
Source comment
name    ADC_GetSoftwareStartInjectedConvCmdStatus.
fun     Gets the selected ADC Software start injected conversion Status.
param   ADCx :
          - ADC1
          - ADC2
return The new state of ADC software start injected conversion (SET or RESET).
void ADC_StopInjectedConv(ADC_Module *ADCx)Stop ADC group injected channels conversion.
Source comment
name    ADC_StopInjectedConv.
fun     Stop ADC group injected channels conversion.
param   ADCx :
          - ADC1
          - ADC2
return  none
void ADC_ConfigInjectedChannel(ADC_Module *ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time.
Source comment
name    ADC_ConfigInjectedChannel.
fun     Configures for the selected ADC injected channel its corresponding
        rank in the sequencer and its sample time.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_Channel :
          - ADC_CH_0 : ADC Channel0 selected
          - ADC_CH_1 : ADC Channel1 selected
          - ADC_CH_2 : ADC Channel2 selected
          - ADC_CH_3 : ADC Channel3 selected
          - ADC_CH_4 : ADC Channel4 selected
          - ADC_CH_5 : ADC Channel5 selected
          - ADC_CH_6 : ADC Channel6 selected
          - ADC_CH_7 : ADC Channel7 selected
          - ADC_CH_8 : ADC Channel8 selected
          - ADC_CH_9 : ADC Channel9 selected
          - ADC_CH_10 : ADC Channel10 selected
          - ADC_CH_11 : ADC Channel11 selected
          - ADC_CH_12 : ADC Channel12 selected
          - ADC_CH_13 : ADC Channel13 selected
          - ADC_CH_14 : ADC Channel14 selected
          - ADC_CH_15 : ADC Channel15 selected
          - ADC_CH_16 : ADC Channel16 selected
          - ADC_CH_17 : ADC Channel17 selected
param   Rank : The rank in the injected group sequencer. This parameter must be between 1 to 4.
param   ADC_SampleTime : The sample time value to be set for the selected channel.
          - ADC_SAMP_TIME_CYCLES_4
          - ADC_SAMP_TIME_CYCLES_6
          - ADC_SAMP_TIME_CYCLES_8
          - ADC_SAMP_TIME_CYCLES_14
          - ADC_SAMP_TIME_CYCLES_29
          - ADC_SAMP_TIME_CYCLES_42
          - ADC_SAMP_TIME_CYCLES_56
          - ADC_SAMP_TIME_CYCLES_72
          - ADC_SAMP_TIME_CYCLES_88
          - ADC_SAMP_TIME_CYCLES_120
          - ADC_SAMP_TIME_CYCLES_182
          - ADC_SAMP_TIME_CYCLES_240
          - ADC_SAMP_TIME_CYCLES_300
          - ADC_SAMP_TIME_CYCLES_400
          - ADC_SAMP_TIME_CYCLES_480
          - ADC_SAMP_TIME_CYCLES_600
return  none
void ADC_ConfigInjectedSequencerLength(ADC_Module *ADCx, uint8_t Length)Configures the sequencer length for injected channels
Source comment
name    ADC_ConfigInjectedSequencerLength.
fun     Configures the sequencer length for injected channels
param   ADCx :
          - ADC1
          - ADC2
param   Length : The sequencer length. This parameter must be a number between 1 to 4.
return  none
uint16_t ADC_GetInjectedConversionDat(const ADC_Module *ADCx, uint8_t ADC_InjectedChannelOffset)Get the ADC injected channel conversion result.
Source comment
name    ADC_GetInjectedConversionDat.
fun     Get the ADC injected channel conversion result.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_InjectedChannelOffset :
          - ADC_INJECT_DATA_OFFSET_1
          - ADC_INJECT_DATA_OFFSET_2
          - ADC_INJECT_DATA_OFFSET_3
          - ADC_INJECT_DATA_OFFSET_4
return  The data conversion value. this data is range 0 - 0xFFFF.
void ADC_EnableAutoInjectedConv(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the selected ADC automatic injected group conversion after regular one
Source comment
name    ADC_EnableAutoInjectedConv.
fun     Enables or disables the selected ADC automatic injected group
        conversion after regular one
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_EnableInjectedDiscMode(ADC_Module *ADCx, FunctionalState Cmd)Enables or disables the discontinuous mode on injected group channel for the specified ADC.
Source comment
name    ADC_EnableInjectedDiscMode.
fun     Enables or disables the discontinuous mode on injected group
        channel for the specified ADC.
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_SetRegularTriggerEdge(ADC_Module *ADCx, uint32_t ExternalRegularTriggerEdge)Set ADCx group regular conversion trigger polarity.
Source comment
name    ADC_SetRegularTriggerEdge.
fun     Set ADCx group regular conversion trigger polarity.
param   ADCx :
          - ADC1
          - ADC2
param   ExternalRegularTriggerEdge :
          - ADC_REG_TRIG_EXT_SOFTWARE
          - ADC_REG_TRIG_EXT_RISING
          - ADC_REG_TRIG_EXT_FALLING
          - ADC_REG_TRIG_EXT_RISINGFALLING
return  none
void ADC_SetInjectTriggerEdge(ADC_Module *ADCx, uint32_t ExternalInjectTriggerEdge)Set ADCx group injected conversion trigger polarity.
Source comment
name    ADC_SetInjectTriggerEdge.
fun     Set ADCx group injected conversion trigger polarity.
param   ADCx :
          - ADC1
          - ADC2
param   ExternalInjectTriggerEdge :
          - ADC_INJ_TRIG_EXT_SOFTWARE
          - ADC_INJ_TRIG_EXT_RISING
          - ADC_INJ_TRIG_EXT_FALLING
          - ADC_INJ_TRIG_EXT_RISINGFALLING
return  none
void ADC_ConfigExternalTrigInjectedConv(ADC_Module *ADCx, uint32_t ADC_ExternalTrigInjecConv)Configures the ADCx external trigger source for injected channels conversion.
Source comment
name    ADC_ConfigExternalTrigInjectedConv.
fun     Configures the ADCx external trigger source for injected channels conversion.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_ExternalTrigInjecConv :
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_TRGO
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_TRGO2
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_CC1
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_CC2
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_CC3
          - ADC_EXT_TRIG_INJ_CONV_ATIM1_CC4
          - ADC_EXT_TRIG_INJ_CONV_ATIM2_TRGO
          - ADC_EXT_TRIG_INJ_CONV_ATIM2_CC1
          - ADC_EXT_TRIG_INJ_CONV_ATIM2_CC4
          - ADC_EXT_TRIG_INJ_CONV_GTIM1_TRGO
          - ADC_EXT_TRIG_INJ_CONV_GTIM1_CC2
          - ADC_EXT_TRIG_INJ_CONV_GTIM1_CC4
          - ADC_EXT_TRIG_INJ_CONV_GTIM2_TRGO
          - ADC_EXT_TRIG_INJ_CONV_GTIM2_CC1
          - ADC_EXT_TRIG_INJ_CONV_GTIM2_CC4
          - ADC_EXT_TRIG_INJ_CONV_GTIM3_TRGO
          - ADC_EXT_TRIG_INJ_CONV_GTIM3_CC1
          - ADC_EXT_TRIG_INJ_CONV_GTIM3_CC2
          - ADC_EXT_TRIG_INJ_CONV_GTIM3_CC4
          - ADC_EXT_TRIG_INJ_CONV_GTIM4_TRGO
          - ADC_EXT_TRIG_INJ_CONV_GTIM4_CC1
          - ADC_EXT_TRIG_INJ_CONV_GTIM4_CC2
          - ADC_EXT_TRIG_INJ_CONV_GTIM4_CC4
          - ADC_EXT_TRIG_INJ_CONV_BTIM1_TRGO
          - ADC_EXT_TRIG_INJ_CONV_EXT_INT0_15
          - ADC_EXT_TRIG_INJ_CONV_SOFTWARE
return  none
void ADC_ConfigExternalTrigRegularConv(ADC_Module *ADCx, uint32_t ADC_ExternalTrigRegularConv)Configures the ADCx external trigger source for regular channels conversion.
Source comment
name    ADC_ConfigExternalTrigRegularConv.
fun     Configures the ADCx external trigger source for regular channels conversion.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_ExternalTrigRegularConv :
          - ADC_EXT_TRIG_REG_CONV_ATIM1_TRGO
          - ADC_EXT_TRIG_REG_CONV_ATIM1_TRGO2
          - ADC_EXT_TRIG_REG_CONV_ATIM1_CC1
          - ADC_EXT_TRIG_REG_CONV_ATIM1_CC2
          - ADC_EXT_TRIG_REG_CONV_ATIM1_CC3
          - ADC_EXT_TRIG_REG_CONV_ATIM1_CC4
          - ADC_EXT_TRIG_REG_CONV_ATIM2_TRGO
          - ADC_EXT_TRIG_REG_CONV_ATIM2_CC1
          - ADC_EXT_TRIG_REG_CONV_ATIM2_CC4
          - ADC_EXT_TRIG_REG_CONV_GTIM1_TRGO
          - ADC_EXT_TRIG_REG_CONV_GTIM1_CC2
          - ADC_EXT_TRIG_REG_CONV_GTIM1_CC4
          - ADC_EXT_TRIG_REG_CONV_GTIM2_TRGO
          - ADC_EXT_TRIG_REG_CONV_GTIM2_CC1
          - ADC_EXT_TRIG_REG_CONV_GTIM2_CC4
          - ADC_EXT_TRIG_REG_CONV_GTIM3_TRGO
          - ADC_EXT_TRIG_REG_CONV_GTIM3_CC1
          - ADC_EXT_TRIG_REG_CONV_GTIM3_CC2
          - ADC_EXT_TRIG_REG_CONV_GTIM3_CC4
          - ADC_EXT_TRIG_REG_CONV_GTIM4_TRGO
          - ADC_EXT_TRIG_REG_CONV_GTIM4_CC1
          - ADC_EXT_TRIG_REG_CONV_GTIM4_CC2
          - ADC_EXT_TRIG_REG_CONV_GTIM4_CC4
          - ADC_EXT_TRIG_REG_CONV_BTIM1_TRGO
          - ADC_EXT_TRIG_REG_CONV_EXT_INT0_15
          - ADC_EXT_TRIG_REG_CONV_SOFTWARE
return  none
void ADC_ConfigRegularExtLineTrigSource(ADC_Module *ADCx, uint32_t ADC_trigger)Configure ADC external line trigger source for regular channel.
Source comment
name   ADC_ConfigRegularExtLineTrigSource.
fun    Configure ADC external line trigger source for regular channel.
param   ADCx :
          - ADC1
          - ADC2
param  ADC_trigger :
          specifies the external line trigger source be configured.
          - ADC_TRIG_EXTI_0
          - ADC_TRIG_EXTI_1
          - ADC_TRIG_EXTI_2
          - ADC_TRIG_EXTI_3
          - ADC_TRIG_EXTI_4
          - ADC_TRIG_EXTI_5
          - ADC_TRIG_EXTI_6
          - ADC_TRIG_EXTI_7
          - ADC_TRIG_EXTI_8
          - ADC_TRIG_EXTI_9
          - ADC_TRIG_EXTI_10
          - ADC_TRIG_EXTI_11
          - ADC_TRIG_EXTI_12
          - ADC_TRIG_EXTI_13
          - ADC_TRIG_EXTI_14
          - ADC_TRIG_EXTI_15
return none
void ADC_ConfigInjectedExtLineTrigSource(ADC_Module *ADCx, uint32_t ADC_trigger)Configure ADC external line trigger source for injected channel.
Source comment
name   ADC_ConfigInjectedExtLineTrigSource.
fun    Configure ADC external line trigger source for injected channel.
param   ADCx :
          - ADC1
          - ADC2
param  ADC_trigger :
          specifies the external line trigger source be configured.
          - ADC_TRIG_EXTI_0
          - ADC_TRIG_EXTI_1
          - ADC_TRIG_EXTI_2
          - ADC_TRIG_EXTI_3
          - ADC_TRIG_EXTI_4
          - ADC_TRIG_EXTI_5
          - ADC_TRIG_EXTI_6
          - ADC_TRIG_EXTI_7
          - ADC_TRIG_EXTI_8
          - ADC_TRIG_EXTI_9
          - ADC_TRIG_EXTI_10
          - ADC_TRIG_EXTI_11
          - ADC_TRIG_EXTI_12
          - ADC_TRIG_EXTI_13
          - ADC_TRIG_EXTI_14
          - ADC_TRIG_EXTI_15
return none
void ADC_SetMultiTwoSamplingDelay(ADC_Module *ADCx, uint32_t MultiTwoSamplingDelay)Set ADC multimode delay between 2 sampling phases.
Source comment
name    ADC_SetMultiTwoSamplingDelay.
fun     Set ADC multimode delay between 2 sampling phases.
param   ADCx :
          - ADC1
          - ADC2
param   MultiTwoSamplingDelay
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_1
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_2
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_3
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_4
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_5
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_6
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_7
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_8
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_9
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_10
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_11
          - ADC_ADC_MULTI_TWOSMP_DELAY_CYCLE_12
return  none
void ADC_ConfigAnalogWatchdogWorkChannelType(ADC_Module *ADCx, uint32_t ADC_AnalogWatchdog)Enables or disables the analog watchdog on single/all regular or injected channels.
Source comment
name    ADC_ConfigAnalogWatchdogWorkChannelType.
fun     Enables or disables the analog watchdog on single/all regular or injected channels.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_AnalogWatchdog :
          - ADC_ANALOG_WTDG_NONE
          - ADC_ANALOG_WTDG_SINGLEREG_ENABLE
          - ADC_ANALOG_WTDG_SINGLEINJEC_ENABLE
          - ADC_ANALOG_WTDG_SINGLEREG_OR_INJEC_ENABLE
          - ADC_ANALOG_WTDG_ALLREG_ENABLE
          - ADC_ANALOG_WTDG_ALLINJEC_ENABLE
          - ADC_ANALOG_WTDG_ALLREG_ALLINJEC_ENABLE
return  none.
void ADC_ConfigAnalogWatchdogThresholds(ADC_Module *ADCx, uint16_t HighThreshold, uint16_t LowThreshold)Configures the high and low thresholds of the analog watchdog .
Source comment
name    ADC_ConfigAnalogWatchdogThresholds.
fun     Configures the high and low thresholds of the analog watchdog .
param   ADCx :
          - ADC1
          - ADC2
param   HighThreshold : the ADC analog watchdog high threshold value.
          - This parameter must be a 12bit value.
param   LowThreshold : the ADC analog watchdog low threshold value.
          - This parameter must be a 12bit value.
return  none
void ADC_ConfigAnalogWatchdogSingleChannel(ADC_Module *ADCx, uint8_t ADC_Channel)Configures the analog watchdog guarded on single channel.
Source comment
name    ADC_ConfigAnalogWatchdogSingleChannel.
fun     Configures the analog watchdog guarded on single channel.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_Channel :
          - ADC_CH_0 : ADC Channel0 selected
          - ADC_CH_1 : ADC Channel1 selected
          - ADC_CH_2 : ADC Channel2 selected
          - ADC_CH_3 : ADC Channel3 selected
          - ADC_CH_4 : ADC Channel4 selected
          - ADC_CH_5 : ADC Channel5 selected
          - ADC_CH_6 : ADC Channel6 selected
          - ADC_CH_7 : ADC Channel7 selected
          - ADC_CH_8 : ADC Channel8 selected
          - ADC_CH_9 : ADC Channel9 selected
          - ADC_CH_10 : ADC Channel10 selected
          - ADC_CH_11 : ADC Channel11 selected
          - ADC_CH_12 : ADC Channel12 selected
          - ADC_CH_13 : ADC Channel13 selected
          - ADC_CH_14 : ADC Channel14 selected
          - ADC_CH_15 : ADC Channel15 selected
          - ADC_CH_16 : ADC Channel16 selected
          - ADC_CH_17 : ADC Channel17 selected
return  none.
void ADC_EnableTempSensorVrefint(FunctionalState Cmd)Enables or disables the temperature sensor and Vrefint channel of ADC1
Source comment
name    ADC_EnableTempSensorVrefint.
fun     Enables or disables the temperature sensor and Vrefint channel of ADC1
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void Reference_VoltageSelect(uint32_t Ref_Type)Selects the reference voltage.
Source comment
name    Reference_VoltageSelect
fun     Selects the reference voltage.
param   Ref_Type:  Select reference voltage of ADC.
         - ADC_VREFSEL_VDDA            Select VDDA as reference voltage
         - ADC_VREFSEL_VREFP           Select VREF+ as reference voltage
         - ADC_VREFSEL_VREFBUFF_2_4V   Select VREFBUFF_2.4V as reference voltage
         - ADC_VREFSEL_OFF             All three switching transistors of VREFP are turned off
return  none
void ADC_ConfigOverSamplingRatioAndShift(ADC_Module *ADCx, uint32_t Ratio, uint32_t Shift)Set ADC oversampling rate times and shift bit.
Source comment
name    ADC_ConfigOverSamplingRatioAndShift.
fun     Set ADC oversampling rate times and shift bit.
param   ADCx :
          - ADC1
          - ADC2
param   Ratio : ADC oversampling ratio times
          - ADC_OVERSAMPE_RATE_TIMES_1
          - ADC_OVERSAMPE_RATE_TIMES_2
          - ADC_OVERSAMPE_RATE_TIMES_4
          - ADC_OVERSAMPE_RATE_TIMES_8
          - ADC_OVERSAMPE_RATE_TIMES_16
          - ADC_OVERSAMPE_RATE_TIMES_32
          - ADC_OVERSAMPE_RATE_TIMES_64
          - ADC_OVERSAMPE_RATE_TIMES_128
          - ADC_OVERSAMPE_RATE_TIMES_256
param   Shift : ADC oversampling data right shift
          - ADC_OVERSAMPE_DATA_SHIFT_0
          - ADC_OVERSAMPE_DATA_SHIFT_1
          - ADC_OVERSAMPE_DATA_SHIFT_2
          - ADC_OVERSAMPE_DATA_SHIFT_3
          - ADC_OVERSAMPE_DATA_SHIFT_4
          - ADC_OVERSAMPE_DATA_SHIFT_5
          - ADC_OVERSAMPE_DATA_SHIFT_6
          - ADC_OVERSAMPE_DATA_SHIFT_7
          - ADC_OVERSAMPE_DATA_SHIFT_8
return  none
void ADC_SetOverSamplingScope(ADC_Module *ADCx, uint32_t OversampleScope)Set ADC oversampling scope.
Source comment
name    ADC_SetOverSamplingScope.
fun     Set ADC oversampling scope.
param   ADCx :
          - ADC1
          - ADC2
param   OversampleScope :This parameter can be one of the following values
          - ADC_OVERSAMPE_DISABLE
          - ADC_OVERSAMPE_REGULAR_CONTINUED
          - ADC_OVERSAMPE_REGULAR_RESUMED
          - ADC_OVERSAMPE_INJECTED
          - ADC_OVERSAMPE_REGULAR_INJECTED
return  none
void ADC_EnableOverSamplingDiscont(ADC_Module *ADCx, FunctionalState Cmd)Set ADC oversampling discontinuous mode (triggered mode).
Source comment
name    ADC_EnableOverSamplingDiscont.
fun     Set ADC oversampling discontinuous mode (triggered mode).
param   ADCx :
          - ADC1
          - ADC2
param   Cmd :
          - ENABLE
          - DISABLE
return  none
void ADC_SetOffsetConfig(ADC_Module *ADCx, uint8_t ADC_Offset, const ADC_OffsetType *ADC_OffsetStruct)Set the specified channel conversion offset configuration.
Source comment
name    ADC_SetOffsetConfig.
fun     Set the specified channel conversion offset configuration.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_Offset :
          - ADC_REGESTER_OFFSET_1
          - ADC_REGESTER_OFFSET_2
          - ADC_REGESTER_OFFSET_3
          - ADC_REGESTER_OFFSET_4
param   ADC_OffsetStruct :
          - OffsetData : Set the selected channel data offset .This parameter must be range from 0 to 0xfff.
          - OffsetChannel : Set the selected channel .This parameter must be range from 0 to 0x11. means CH0 - CH17.
          - OffsetDirPositiveEn : Enable or disable the selected channel offset positive direction.
             - ENABLE
             - DISABLE
          - OffsetSatenEn : Enable or disable the selected channel offset saturation .
             - ENABLE
             - DISABLE
          - OffsetEn : Enable or disable the selected channel offset.
             - ENABLE
             - DISABLE
return  none
void ADC_GetOffsetConfig(const ADC_Module *ADCx, uint8_t ADC_Offset, ADC_OffsetType *ADC_OffsetStruct)Get the specified channel conversion offset configuration.
Source comment
name    ADC_GetOffsetConfig.
fun     Get the specified channel conversion offset configuration.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_Offset :
          - ADC_REGESTER_OFFSET_1
          - ADC_REGESTER_OFFSET_2
          - ADC_REGESTER_OFFSET_3
          - ADC_REGESTER_OFFSET_4
param   ADC_OffsetStruct :
          - OffsetData : Set the selected channel data offset .This parameter must be range from 0 to 0xfff.
          - OffsetChannel : Set the selected channel .This parameter must be range from 0 to 0x11. means CH0 - CH17.
          - OffsetDirPositiveEn : Enable or disable the selected channel offset positive direction.
             - ENABLE
             - DISABLE
          - OffsetSatenEn : Enable or disable the selected channel offset saturation .
             - ENABLE
             - DISABLE
          - OffsetEn : Enable or disable the selected channel offset.
             - ENABLE
             - DISABLE
return  none
FlagStatus ADC_GetFlagStatus(const ADC_Module *ADCx, uint16_t ADC_FLAG)Checks whether the specified ADC flag is set or not.
Source comment
name    ADC_GetFlagStatus.
fun     Checks whether the specified ADC flag is set or not.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_FLAG :
          - ADC_FLAG_ENDC
          - ADC_FLAG_EOC_ANY
          - ADC_FLAG_JENDC
          - ADC_FLAG_JEOC_ANY
          - ADC_FLAG_AWDG
          - ADC_FLAG_OVERRUN
          - ADC_FLAG_RDY
          - ADC_FLAG_PDRDY
          - ADC_FLAG_EOSAMP
          - ADC_FLAG_TCFLAG
          - ADC_FLAG_STR
          - ADC_FLAG_JSTR
          - ADC_FLAG_VREFRDY
return    The new state of ADC_FLAG (SET or RESET).
void ADC_ClearFlag(ADC_Module *ADCx, uint16_t ADC_FLAG)Clears pending flags of the specified ADC.
Source comment
name    ADC_ClearFlag.
fun     Clears pending flags of the specified ADC.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_FLAG :
          - ADC_FLAG_ENDC
          - ADC_FLAG_EOC_ANY
          - ADC_FLAG_JENDC
          - ADC_FLAG_JEOC_ANY
          - ADC_FLAG_AWDG
          - ADC_FLAG_OVERRUN
          - ADC_FLAG_RDY
          - ADC_FLAG_PDRDY
          - ADC_FLAG_EOSAMP
          - ADC_FLAG_TCFLAG
          - ADC_FLAG_STR
          - ADC_FLAG_JSTR
return    none.
void ADC_ConfigInt(ADC_Module *ADCx, uint16_t ADC_IT, FunctionalState Cmd)Enables or disables the specified ADC interrupts.
Source comment
name    ADC_ConfigInt.
fun     Enables or disables the specified ADC interrupts.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_IT :
          - ADC_INT_ENDC
          - ADC_INT_ENDCA
          - ADC_INT_JENDC
          - ADC_INT_JENDCA
          - ADC_INT_AWDG
          - ADC_INT_OVERRUN
          - ADC_INT_RDY
          - ADC_INT_PDRDY
          - ADC_INT_EOSAMP

param   Cmd :
          - ENABLE
          - DISABLE
return    none.
INTStatus ADC_GetIntStatus(const ADC_Module *ADCx, uint16_t ADC_IT)Checks whether the specified ADC interrupt has occurred or not.
Source comment
name    ADC_GetIntStatus.
fun     Checks whether the specified ADC interrupt has occurred or not.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_IT : specifies the ADC interrupt source to check.
          - ADC_INT_ENDC
          - ADC_INT_ENDCA
          - ADC_INT_JENDC
          - ADC_INT_JENDCA
          - ADC_INT_AWDG
          - ADC_INT_RDY
          - ADC_INT_PDRDY
          - ADC_INT_EOSAMP
          - ADC_INT_OVERRUN
return    The new state of ADC_IT (SET or RESET).
void ADC_ClearIntPendingBit(ADC_Module *ADCx, uint16_t ADC_IT)Clears interrupt pending bits of the specified ADC.
Source comment
name    ADC_ClearIntPendingBit.
fun     Clears  interrupt pending bits of the specified ADC.
param   ADCx :
          - ADC1
          - ADC2
param   ADC_IT :
          - ADC_INT_ENDC
          - ADC_INT_ENDCA
          - ADC_INT_JENDC
          - ADC_INT_JENDCA
          - ADC_INT_AWDG
          - ADC_INT_OVERRUN
          - ADC_INT_RDY
          - ADC_INT_PDRDY
          - ADC_INT_EOSAMP
return    none.
void ADC_ClockModeConfig(uint32_t RCC_ADCCLKprescaler)Configures the ADCCLK prescaler.
Source comment
name    ADC_ClockModeConfig
fun     Configures the ADCCLK prescaler.
param   RCC_ADCCLKprescaler:
         - RCC_ADCSYSCLK_DIV1     ADC clock = SYSCLK
         - RCC_ADCSYSCLK_DIV2     ADC clock = SYSCLK/2
         - RCC_ADCSYSCLK_DIV3     ADC clock = SYSCLK/3
         - RCC_ADCSYSCLK_DIV4     ADC clock = SYSCLK/4
         - RCC_ADCSYSCLK_DIV5     ADC clock = SYSCLK/5
         - RCC_ADCSYSCLK_DIV6     ADC clock = SYSCLK/6
         - RCC_ADCSYSCLK_DIV8     ADC clock = SYSCLK/8
         - RCC_ADCSYSCLK_DIV10    ADC clock = SYSCLK/10
         - RCC_ADCSYSCLK_DIV12    ADC clock = SYSCLK/12
         - RCC_ADCSYSCLK_DIV16    ADC clock = SYSCLK/16
         - RCC_ADCSYSCLK_DIV32    ADC clock = SYSCLK/32
         - RCC_ADCSYSCLK_DIV64    ADC clock = SYSCLK/64
return  none

5.1.3 Demo descriptions

This section describes the 9 ADC examples in alphabetical order of their directory names, covering single-channel reading, DMA acquisition, the internal temperature sensor, oversampling, the analog watchdog, external line triggering, dual-ADC simultaneous mode and timer automatic injection.

5.1.3.1 ADC_Offset Offset compensation

Example directory: projects/n32g41x_EVAL/examples/ADC/ADC_Offset/

PB1 analog input→ADC1 regular channel 9 continuous conversion→offset register 1 adds 0x400 to the result→result saturated to 0x000 to 0xFFF→DMA moves the value to memory in a loop

Item Source analysis
Function Adds a positive offset of 0x400 to the conversion result of ADC1 regular channel 9 (PB1) with saturation enabled, showing how the offset compensation register is used.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration and DMA_Config;
inc/main.h: channel, port and pin macros;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Single channel, continuous conversion, software trigger, sample time ADC_SAMP_TIME_CYCLES_240;
offset register ADC_REGESTER_OFFSET_1 with OffsetData set to OFFSET_VALUE (0x400) and both OffsetDirPositiveEn and OffsetSatenEn enabled;
DMA channel 1 in circular mode, half-word transfers, buffer size 1.
Program and data path main calls RCC_Configuration, GPIO_Configuration, DMA_Config and ADC_Initial in turn, then starts continuous conversion with ADC_EnableSoftwareStartConv;
the result is written to ADC1->DAT and moved by DMA into the memory variable ADCConvertedValue, whose value is the raw result plus 0x400.
Main APIs ADC_InitStruct, ADC_Init, ADC_ConfigRegularChannel, ADC_SetOffsetConfig, ADC_Enable, ADC_GetFlagStatus, ADC_EnableDMA, ADC_EnableSoftwareStartConv
Verification Apply a known voltage to PB1 and inspect ADCConvertedValue in the Keil or IAR watch window;
it should equal the raw sample plus 0x400, and values above the 12-bit range are saturated to 0xFFF.
Use note The offset registers have no effect while oversampling is enabled and the OFFSCHxEN bits are ignored;
a positive offset adds to the result while a negative offset (OffsetDirPositiveEn set to DISABLE) subtracts.
Core-code walkthrough and porting

The example lets the voltage on PB1 be converted continuously on ADC1 channel 9 and adds a fixed offset to the result through offset register 1.

Data path: PB1 voltage -> ADC_ConfigRegularChannel selects channel 9 -> ADC_SetOffsetConfig writes offset register 1 -> each result is increased by 0x400 and saturated -> DMA writes it into ADCConvertedValue in a loop

1. Initializing single-channel continuous conversion. ADC_Initial first fills the structure with defaults, then sets independent mode, one channel, continuous conversion and software trigger.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = DISABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 regular channel configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_CH_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);

2. Writing the compensation parameters of offset register 1. An offset register binds a channel, an offset value, a direction and a saturation flag, all written in one call.

src/main.csrc/main.c · ADC_Initial
    /* ADC1 channel offset compensation configuration
     * Offset register 1 monitors ADC_CH_CHANNEL (PB1)
     * Positive direction offset: result = ADC_raw + OFFSET_VALUE
     * Saturation enabled: clamp result to 0x000~0xFFF range
     */
    ADC_OffsetStructure.OffsetChannel      = ADC_CH_CHANNEL;
    ADC_OffsetStructure.OffsetData         = OFFSET_VALUE;
    ADC_OffsetStructure.OffsetDirPositiveEn = ENABLE;
    ADC_OffsetStructure.OffsetSatenEn      = ENABLE;
    ADC_OffsetStructure.OffsetEn           = ENABLE;
    ADC_SetOffsetConfig(ADC1, ADC_REGESTER_OFFSET_1, &ADC_OffsetStructure);

The four offset registers (ADC_REGESTER_OFFSET_1 to ADC_REGESTER_OFFSET_4) map to ADC_OFFSET1 to ADC_OFFSET4, and each register can bind only one channel.

3. Enabling the ADC, waiting for ready and then opening the DMA request. The DMA request is enabled only after power-up and the ready check, so the peripheral is prepared when conversion data is moved.

src/main.csrc/main.c · ADC_Initial
    /* Enable ADC1 */
    ADC_Enable(ADC1, ENABLE);
    /* Check ADC Ready */
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY) == RESET)
        ;
    /* Enable ADC1 DMA */
    ADC_EnableDMA(ADC1, ENABLE);

4. Starting continuous conversion. After initialization main issues one software start, and in continuous mode the ADC keeps converting the same channel.

src/main.csrc/main.c · main
    /* Start ADC1 Software Conversion */
    ADC_EnableSoftwareStartConv(ADC1, ENABLE);

Corresponding source files: src/main.c

5.1.3.2 ADC_SingleRead Single-channel reading

Example directory: projects/n32g41x_EVAL/examples/ADC/ADC_SingleRead/

PA0 and PA1 analog inputs→main loop switches between ADC1 regular channel 0 and channel 1→software start and ENDC polling→DAT read into an array

Item Source analysis
Function Reads voltages channel by channel in polling mode without DMA, storing the results of channel 0 (PA0) and channel 1 (PA1) in an array.
Source files src/main.c: ADC_Initial, ADC_GetData, main, RCC_Configuration and GPIO_Configuration;
inc/main.h: channel, port and pin macros;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Single channel, single conversion (ContinueConvEn is DISABLE), software trigger, sample time ADC_SAMP_TIME_CYCLES_240;
ADC_GetData reconfigures the channel before each read, so scan mode is not needed.
Program and data path main calls ADC_Initial(ADC1) and then reads channel 0 and channel 1 in while(1) through ADC_GetData, storing the results in ADC1ConvertedValue[0] and ADC1ConvertedValue[1];
ADC_GetData configures the channel, starts the conversion, polls ADC_FLAG_ENDC, clears ENDC and STR and reads ADC_GetDat.
Main APIs ADC_InitStruct, ADC_Init, ADC_Enable, ADC_GetFlagStatus, ADC_ConfigRegularChannel, ADC_EnableSoftwareStartConv, ADC_ClearFlag, ADC_GetDat
Verification Apply different voltages to PA0 and PA1 and inspect the two elements of ADC1ConvertedValue in the watch window;
they should correspond to the two voltages, with right-aligned data.
Use note In single conversion mode a new channel must be configured and started again for every read;
clearing ADC_FLAG_STR before reading avoids the previous state affecting the check.
Core-code walkthrough and porting

The example reads voltages channel by channel in polling mode without DMA, refreshing the two results in the main loop.

Data path: PA0 and PA1 voltages -> ADC_ConfigRegularChannel switches the channel -> ADC_EnableSoftwareStartConv starts it -> polling ADC_FLAG_ENDC -> ADC_GetDat reads it back -> stored in ADC1ConvertedValue

1. Initializing single conversion mode. Compared with the continuous example, ContinueConvEn is DISABLE here, so each start performs one conversion.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADCx configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = DISABLE;
    ADC_InitStructure.ContinueConvEn = DISABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADCx, &ADC_InitStructure);

    /* Enable ADCx */
    ADC_Enable(ADCx, ENABLE);
    /* Check ADC Ready */
    while(ADC_GetFlagStatus(ADCx, ADC_FLAG_RDY) == RESET)
        ;

2. Reconfiguring the channel and waiting for the end of conversion on each read. ADC_GetData chains configuration, start, polling and reading together, completing one channel per call.

src/main.csrc/main.c · ADC_GetData
    ADC_ConfigRegularChannel(ADCx, ADC_Channel, 1, ADC_SAMP_TIME_CYCLES_240);
    /* Start ADC Software Conversion */
    ADC_EnableSoftwareStartConv(ADCx, ENABLE);
    while(ADC_GetFlagStatus(ADCx, ADC_FLAG_ENDC) == 0){
    }
    ADC_ClearFlag(ADCx, ADC_FLAG_ENDC);
    ADC_ClearFlag(ADCx, ADC_FLAG_STR);
    dat = ADC_GetDat(ADCx);
    return dat;

3. Reading the two channels in turn in the main loop. Both channels share the same initialization and differ only in the channel argument of ADC_GetData.

src/main.csrc/main.c · main
    while (1)
    {
        ADC1ConvertedValue[0] = ADC_GetData(ADC1, ADC_CH0_CHANNEL);
        ADC1ConvertedValue[1] = ADC_GetData(ADC1, ADC_CH1_CHANNEL);
    }

Corresponding source files: src/main.c

5.1.3.3 ADC_TEMP Internal temperature sensor

Example directory: projects/n32g41x_EVAL/examples/ADC/ADC_TEMP/

Enable the internal temperature sensor channel→ADC1 channel 17 samples with 600 cycles→DMA moves the conversion value→temperature computed from the factory calibration value→printed on the serial port

Item Source analysis
Function Samples the on-chip temperature sensor, converts it using the factory calibration value and prints the temperature, showing the internal channel and a longer sample time.
Source files src/main.c: ADC_Initial, TempratureCalculate, main, RCC_Configuration and DMA_Config;
inc/main.h: pin and log configuration macros;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Single channel, continuous conversion, channel ADC1_Channel_17_Temperture_Sensor, sample time ADC_SAMP_TIME_CYCLES_600;
ADC_EnableTempSensorVrefint(ENABLE) before the conversion;
reference voltage VREF_VALUE defaults to 3.3, and is changed to 4.7 with a different VTS_ADDR when VDDA on the board is 5 V;
DMA in circular mode with buffer size 1.
Program and data path main initializes clocks, logging, DMA and the ADC, starts the conversion and waits for ENDC, then passes ADCConvertedValue to TempratureCalculate in while(1) and prints the temperature through log_debug.
Main APIs ADC_ConfigRegularChannel, ADC_EnableTempSensorVrefint, ADC_EnableDMA, ADC_Enable, ADC_GetFlagStatus, ADC_EnableSoftwareStartConv
Verification With logging on PA9 at 115200, 8 data bits, no parity and 1 stop bit, the port periodically prints a temperature such as Temperature = 25.0 C;
the value changes with the ambient temperature.
Use note The ideal sample time of the temperature sensor is at least 17.1 us and the example uses 600 cycles;
the conversion needs the calibration value written at production, and the reading is stable only when the sample time is long enough.
Core-code walkthrough and porting

The example samples the on-chip temperature sensor and converts it with the factory calibration value and the temperature slope.

Data path: temperature sensor -> ADC1 channel 17 -> ADC_EnableTempSensorVrefint enables it -> DMA moves the value into ADCConvertedValue -> TempratureCalculate uses VTS_ADDR and AVG_SLOPE -> serial output

1. Selecting the internal temperature sensor channel and increasing the sample time. The internal channel is on ADC1 channel 17, and the sample time is set to 600 cycles so that it settles fully.

src/main.csrc/main.c · ADC_Initial
    /* ADC1 regular channel16 configuration (internal temperature sensor) */
    ADC_ConfigRegularChannel(ADC1, ADC1_Channel_17_Temperture_Sensor, 1, ADC_SAMP_TIME_CYCLES_600);
    /* Enable Temperature Sensor */
    ADC_EnableTempSensorVrefint(ENABLE);
    /* Enable ADC1 DMA */
    ADC_EnableDMA(ADC1, ENABLE);
    /* Enable ADC1 */
    ADC_Enable(ADC1, ENABLE);

2. Converting the sample value into a voltage and a temperature. The 12-bit sample is first turned into a voltage, then the factory calibration value is read and the temperature is computed from the slope.

src/main.csrc/main.c · TempratureCalculate
    float Temperate,tempValue,VTS;
    uint32_t TSValue;

    /* Voltage value of temperature sensor */
    tempValue=TempAdVal*(VREF_VALUE/4095);

    TSValue= (((*(uint32_t*)(VTS_ADDR)) & 0x0000FFFF));

    VTS =  TSValue /1000.0f;

    /* Get the temperature inside the chip */
    Temperate= ((VTS - tempValue)/AVG_SLOPE) + 25;

AVG_SLOPE is 0.0041, the voltage change per degree Celsius; the calibration value is the voltage of the temperature sensor at 25 degrees Celsius, in millivolts.

3. Converting and printing in the main loop. The conversion is moved continuously by DMA, so the main loop only reads the latest value and outputs it.

src/main.csrc/main.c · main
    while (1)
    {
        TempValue = TempratureCalculate(ADCConvertedValue);

        log_debug("\r\n Temperature = %.1f C\r\n", TempValue);

        SysTick_Delay_Ms(1);
    }

Corresponding source files: src/main.c

5.1.3.4 ADC1_DMA Circular acquisition

Example directory: projects/n32g41x_EVAL/examples/ADC/ADC1_DMA/

PB1 analog input→ADC1 channel 9 continuous conversion→DMA channel 1 circular transfer→memory variable refreshed continuously

Item Source analysis
Function Lets ADC1 convert continuously and have DMA move each result to memory, with no CPU involvement in the transfer.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration and DMA_Config;
inc/main.h: channel, port and pin macros;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Single channel, continuous conversion, software trigger, sample time ADC_SAMP_TIME_CYCLES_240;
DMA channel 1 in circular mode, peripheral to memory, half-word transfers, buffer size 1, memory increment disabled.
Program and data path main initializes clocks, GPIO, DMA and the ADC, then starts continuous conversion with ADC_EnableSoftwareStartConv;
afterwards every conversion issues a DMA request that writes ADC1->DAT into ADCConvertedValue.
Main APIs ADC_InitStruct, ADC_Init, ADC_ConfigRegularChannel, ADC_Enable, ADC_GetFlagStatus, ADC_EnableDMA, ADC_EnableSoftwareStartConv
Verification Apply a voltage that varies over time to PB1 and inspect ADCConvertedValue in the watch window;
it should follow the input continuously without any CPU read.
Use note Enable the order is ADC_Enable with a wait for ADC_FLAG_RDY first and ADC_EnableDMA afterwards;
circular mode reloads the DMA buffer after each transfer, which suits continuous acquisition.
Core-code walkthrough and porting

The example lets ADC1 convert continuously and uses DMA to move the result into a memory variable without CPU intervention.

Data path: PB1 voltage -> ADC_ConfigRegularChannel selects channel 9 -> ADC_EnableSoftwareStartConv starts it -> each end of conversion triggers DMA -> ADCConvertedValue is updated

1. Initializing continuous conversion mode. The scan bit is cleared and the continuous bit set, so the conversion continues on its own after a software start.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = DISABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel9 configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_CH_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);

2. Enabling the ADC, waiting for ready and then opening DMA. The DMA request is enabled once the ADC is ready, so the transfer does not start before data is available.

src/main.csrc/main.c · ADC_Initial
    /* Enable ADC1 */
    ADC_Enable(ADC1, ENABLE);
    /* Check ADC Ready */
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY) == RESET)
        ;
    /* Enable ADC1 DMA */
    ADC_EnableDMA(ADC1, ENABLE);

3. DMA channel 1 moving half-words in a loop. The peripheral address is fixed at ADC1->DAT and the memory address at a single variable, and the buffer reloads automatically in circular mode.

src/main.csrc/main.c · DMA_Config
    DMA_DeInit(DMA_CH1);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)&ADCConvertedValue;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 1;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_DISABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(DMA_CH1, &DMA_InitStructure);

    DMA_RequestRemap(DMA_REMAP_ADC1, DMA, DMA_CH1, ENABLE);

    /* Enable DMA channel1 */
    DMA_EnableChannel(DMA_CH1, ENABLE);

Corresponding source files: src/main.c

5.1.3.5 ADC1_Oversampling Oversampling

Example directory: projects/n32g41x_EVAL/examples/ADC/ADC1_Oversampling/

PB0 and PB1 analog inputs→ADC1 channel 8 and channel 9 scanned→results oversampled by 2 with no shift→DMA writes 10 half-words in a loop

Item Source analysis
Function Enables 2x oversampling on two regular channels and uses DMA to observe the oversampled data.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration and DMA_Config;
inc/main.h: channel, port and pin macros;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Multi-channel scan, continuous conversion, ChsNumber set to 2;
oversampling ratio ADC_OVERSAMPE_RATE_TIMES_2, no shift (ADC_OVERSAMPE_DATA_SHIFT_0) and scope ADC_OVERSAMPE_REGULAR_CONTINUED;
DMA channel 1 in circular mode with memory increment and buffer size 10.
Program and data path main initializes clocks, GPIO, DMA and the ADC, and after the start the oversampled results of the two channels are written continuously by DMA into ADCConvertedValue[10].
Main APIs ADC_ConfigRegularChannel, ADC_ConfigOverSamplingRatioAndShift, ADC_SetOverSamplingScope, ADC_Enable, ADC_GetFlagStatus, ADC_EnableDMA, ADC_EnableSoftwareStartConv
Verification Apply voltages to PB0 and PB1 and inspect ADCConvertedValue in the watch window;
the values equal the corresponding voltages as 12-bit results from 2x oversampling with no shift.
Use note With no shift the oversampled result can exceed 12 bits and must be scaled back by the ratio;
offset compensation has no effect while oversampling is enabled, and data alignment is not supported either.
Core-code walkthrough and porting

The example enables 2x oversampling on two regular channels and uses DMA to observe the oversampled data continuously.

Data path: PB0 and PB1 voltages -> a two-channel regular sequence -> ADC_ConfigOverSamplingRatioAndShift sets 2x -> ADC_SetOverSamplingScope applies it to continuous regular conversions -> DMA writes into ADCConvertedValue[10]

1. Initializing multi-channel scan mode. The scan bit is set and the channel count is 2, with the two channels in sequence positions 1 and 2.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 2;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_CH1_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);
    ADC_ConfigRegularChannel(ADC1, ADC_CH2_CHANNEL, 2, ADC_SAMP_TIME_CYCLES_240);

2. Setting the oversampling ratio, shift and scope. Oversampling is 2x with no shift and applies to continuous regular conversions.

src/main.csrc/main.c · ADC_Initial
    /* Enable ADC1 oversampling, x2 and no shift */
    ADC_ConfigOverSamplingRatioAndShift(ADC1, ADC_OVERSAMPE_RATE_TIMES_2, ADC_OVERSAMPE_DATA_SHIFT_0);
    /* Config ADC1 oversampling scope */
    ADC_SetOverSamplingScope(ADC1, ADC_OVERSAMPE_REGULAR_CONTINUED);

3. Having DMA move 10 half-words with address increment. The buffer is larger than the channel count, which shows the variation of successive oversampled results.

src/main.csrc/main.c · DMA_Config
    DMA_DeInit(DMA_CH1);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)ADCConvertedValue;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 10;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(DMA_CH1, &DMA_InitStructure);

Corresponding source files: src/main.c

5.1.3.6 AnalogWatchdog Analog watchdog

Example directory: projects/n32g41x_EVAL/examples/ADC/AnalogWatchdog/

PB1 analog input→ADC1 channel 9 conversion→result compared with the high and low thresholds→an out-of-range result raises the AWD interrupt→the handler increments a counter

Item Source analysis
Function Uses the analog watchdog to guard a single regular channel and counts the interrupts raised when the conversion result leaves the threshold window.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration and NVIC_Configuration;
inc/main.h: channel, port and pin macros;
src/n32g41x_it.c: ADC1_IRQHandler and the gCntAwdg definition;
inc/n32g41x_it.h: interrupt declarations;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration Single channel, continuous conversion, sample time ADC_SAMP_TIME_CYCLES_240;
high threshold 0x0B00 and low threshold 0x0300 with watch type ADC_ANALOG_WTDG_SINGLEREG_ENABLE;
interrupt ADC_INT_AWDG enabled;
NVIC priority group 2 with ADC1_IRQn preemption and sub priority both 0.
Program and data path main initializes clocks, GPIO, NVIC and the ADC, starts continuous conversion and enters while(1) incrementing gCnt;
when a result leaves the window, ADC1_IRQHandler clears the ADC_INT_AWDG pending bit and increments gCntAwdg.
Main APIs ADC_ConfigRegularChannel, ADC_ConfigAnalogWatchdogThresholds, ADC_ConfigAnalogWatchdogSingleChannel, ADC_ConfigAnalogWatchdogWorkChannelType, ADC_ConfigInt, ADC_GetIntStatus, ADC_ClearIntPendingBit
Verification Drive PB1 outside the threshold window and inspect gCntAwdg in the watch window;
it keeps growing, and stops growing while the voltage stays inside the window.
Use note The threshold comparison happens before data alignment, so both thresholds are compared against the unshifted result;
ADC_ConfigAnalogWatchdogSingleChannel is meaningful only in single-channel mode.
Core-code walkthrough and porting

The example uses the analog watchdog to guard a single regular channel and lets ADC1_IRQHandler count the out-of-range events.

Data path: PB1 voltage -> channel 9 -> ADC_ConfigAnalogWatchdogThresholds sets the thresholds -> ADC_ConfigAnalogWatchdogSingleChannel selects the channel -> ADC_ConfigInt enables ADC_INT_AWDG -> the interrupt counts

1. Configuring the thresholds, the guarded channel and the interrupt. Both thresholds are written at once and the guarded channel is selected in single-channel mode.

src/main.csrc/main.c · ADC_Initial
    /* ADC1 regular channel9 configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_CH_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);
    /* Configure high and low analog watchdog thresholds */
    ADC_ConfigAnalogWatchdogThresholds(ADC1, 0x0B00, 0x0300);
    /* Configure channel as the single analog watchdog guarded channel */
    ADC_ConfigAnalogWatchdogSingleChannel(ADC1, ADC_CH_CHANNEL);
    /* Enable analog watchdog on one regular channel */
    ADC_ConfigAnalogWatchdogWorkChannelType(ADC1, ADC_ANALOG_WTDG_SINGLEREG_ENABLE);
    /* Enable AWD interrupt */
    ADC_ConfigInt(ADC1, ADC_INT_AWDG, ENABLE);

2. Enabling the ADC1 interrupt in the NVIC. The watchdog interrupt reaches the CPU only after the interrupt controller is configured and the channel is enabled.

src/main.csrc/main.c · NVIC_Configuration
    NVIC_InitType NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel                   = ADC1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

3. Clearing the flag and counting in the handler. The handler first checks the interrupt source, clears the pending bit and then increments the counter.

src/n32g41x_it.csrc/n32g41x_it.c · ADC1_IRQHandler
    if(ADC_GetIntStatus(ADC1, ADC_INT_AWDG) != RESET)
    {
        /* Clear ADC1 AWD pending interrupt bit */
        ADC_ClearIntPendingBit(ADC1, ADC_INT_AWDG);
        gCntAwdg++;
    }

Corresponding source files: src/main.c, src/n32g41x_it.c

5.1.3.7 ExtLinesTrigger External line trigger

Example directory: projects/n32g41x_EVAL/examples/ADC/ExtLinesTrigger/

PA12 and PA11 rising edges→EXTI events trigger→ADC1 regular and injected conversions→the JENDC interrupt reads the injected results→DMA moves the regular results

Item Source analysis
Function Uses two external EXTI lines to trigger regular and injected conversions, with the regular results going through DMA and the injected results read in the interrupt.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration, EXTI_Configuration, DMA_Config and NVIC_Configuration;
inc/main.h: channel and EXTI trigger pin macros;
src/n32g41x_it.c: ADC1_IRQHandler and the Index definition;
inc/n32g41x_it.h: interrupt declarations;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration The regular group is PA0 and PA1 and the injected group is PA2 and PA3, both with sequence length 2;
ContinueConvEn is DISABLE, the regular trigger source is ADC_EXT_TRIG_REG_CONV_EXT_INT0_15 and the injected trigger source is ADC_EXT_TRIG_INJ_CONV_EXT_INT0_15;
PA12 uses EXTI line 10 and PA11 uses EXTI line 11, both in event mode on the rising edge;
DMA in circular mode with buffer size 64.
Program and data path main initializes clocks, NVIC, GPIO, EXTI, DMA and the ADC;
the regular results are written by DMA into ADC_RegularConvertedValueTab[64] and at the end of each injected conversion ADC1_IRQHandler reads the two injected values into ADC_InjectedConvertedValueTab[32].
Main APIs ADC_ConfigRegularChannel, ADC_ConfigInjectedChannel, ADC_ConfigInjectedSequencerLength, ADC_ConfigExternalTrigInjectedConv, ADC_ConfigRegularExtLineTrigSource, ADC_ConfigInjectedExtLineTrigSource, ADC_ConfigInt, ADC_GetInjectedConversionDat
Verification Apply rising edges to PA12 and PA11 with a signal source;
the regular results should update in ADC_RegularConvertedValueTab and the injected results should appear in pairs in ADC_InjectedConvertedValueTab.
Use note The injected data registers are read-only and can be read only by offset through ADC_GetInjectedConversionDat;
external line triggering requires mapping the EXTI lines to the ADC triggers with ADC_ConfigRegularExtLineTrigSource and ADC_ConfigInjectedExtLineTrigSource first.
Core-code walkthrough and porting

The example uses two EXTI lines to trigger regular and injected conversions at the same time, handling the two kinds of results with DMA and an interrupt.

Data path: PA12 and PA11 rising edges -> EXTI events -> ADC external trigger -> regular results written by DMA into ADC_RegularConvertedValueTab -> the JENDC interrupt reads injected values into ADC_InjectedConvertedValueTab

1. Regular channels and external line triggering. Two channels are placed in the regular sequence, and after choosing ADC_EXT_TRIG_REG_CONV_EXT_INT0_15 the specific EXTI line is selected in software.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = DISABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_EXT_INT0_15;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 2;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel configuration */
    ADC_ConfigRegularChannel(ADC1, ADC1_Channel_00_PA0, 1, ADC_SAMP_TIME_CYCLES_240);
    ADC_ConfigRegularChannel(ADC1, ADC1_Channel_01_PA1, 2, ADC_SAMP_TIME_CYCLES_240);

2. Injected channels, trigger source and interrupt. The injected sequence length, the channels and the external trigger source are set in turn, and finally the two EXTI lines are mapped to the ADC.

src/main.csrc/main.c · ADC_Initial
    /* Set injected sequencer length */
    ADC_ConfigInjectedSequencerLength(ADC1, 2);
    /* ADC1 injected channel configuration */
    ADC_ConfigInjectedChannel(ADC1, ADC1_Channel_02_PA2, 1, ADC_SAMP_TIME_CYCLES_240);
    ADC_ConfigInjectedChannel(ADC1, ADC1_Channel_03_PA3, 2, ADC_SAMP_TIME_CYCLES_240);
    /* ADC1 injected external trigger configuration */
    ADC_ConfigExternalTrigInjectedConv(ADC1, ADC_EXT_TRIG_INJ_CONV_EXT_INT0_15);

    /* Enable JENDC interrupt */
    ADC_ConfigInt(ADC1, ADC_INT_JENDC, ENABLE);

    ADC_ConfigRegularExtLineTrigSource(ADC1, Regular_ExtLine_TrigSource);
    ADC_ConfigInjectedExtLineTrigSource(ADC1, Injected_ExtLine_TrigSource);

3. Configuring the two EXTI lines as event mode on the rising edge. Each EXTI line is first associated with a GPIO pin and then set to event mode, so the event triggers the ADC instead of the CPU.

src/main.csrc/main.c · EXTI_Configuration
    EXTI_InitStruct(&EXTI_InitStructure);
    GPIO_ConfigEXTILine(REG_EXTI_PortSOURCE, REG_EXTI_PinSOURCE);
    /* EXTI line10 configuration -----------------------------------------------*/
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Event;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_Line    = REG_EXTI_LINE;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

    GPIO_ConfigEXTILine(INJ_EXTI_PortSOURCE, INJ_EXTI_PinSOURCE);
    /* EXTI line11 configuration -----------------------------------------------*/
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Event;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_Line    = INJ_EXTI_LINE;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

4. Reading the two injected values in the handler. It clears JENDC and then reads the injected data registers by offset, writing them in a ring.

src/n32g41x_it.csrc/n32g41x_it.c · ADC1_IRQHandler
    if(ADC_GetIntStatus(ADC1, ADC_INT_JENDC) != RESET)
    {
        /* Clear ADC1 JEOC pending interrupt bit */
        ADC_ClearIntPendingBit(ADC1, ADC_INT_JENDC);

        /* Get injected channel1 and channel2 converted value */
        ADC_InjectedConvertedValueTab[Index++] = ADC_GetInjectedConversionDat(ADC1, ADC_INJECT_DATA_OFFSET_1);
        ADC_InjectedConvertedValueTab[Index++] = ADC_GetInjectedConversionDat(ADC1, ADC_INJECT_DATA_OFFSET_2);

        if (Index == 32)
        {
            Index = 0;
        }
    }

Corresponding source files: src/main.c, src/n32g41x_it.c

5.1.3.8 RegSimul_DualMode Regular simultaneous dual mode

Example directory: projects/n32g41x_EVAL/examples/ADC/RegSimul_DualMode/

PB0 and PB1 with PA4 and PA5 analog inputs→ADC1 and ADC2 in regular simultaneous mode→the two results packed into one 32-bit word→DMA moves 16 words

Item Source analysis
Function Puts ADC1 and ADC2 in regular simultaneous mode so that the results of two channels are packed into one 32-bit word moved by DMA.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration and DMA_Config;
inc/main.h: channel, port and pin macros for both ADCs;
src/n32g41x_it.c and inc/n32g41x_it.h: interrupt handlers;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration The WorkMode of both ADC1 and ADC2 is ADC_WORKMODE_DUAL_REG_SIMULT, MultiChEn and ContinueConvEn are both enabled, ChsNumber is 2 and the sample time is ADC_SAMP_TIME_CYCLES_600;
DMA channel 1 in normal mode, word transfers, buffer size 16.
Program and data path main initializes clocks, GPIO, DMA and the ADC, starts the software conversion and waits for the DMA transfer complete flag DMA_FLAG_TC1 before clearing it;
each pair of simultaneous results occupies one 32-bit cell of ADC_DualConvertedValueTab, with the low 16 bits for ADC1 and the high 16 bits for ADC2.
Main APIs ADC_InitStruct, ADC_Init, ADC_ConfigRegularChannel, ADC_Enable, ADC_GetFlagStatus, ADC_EnableDMA, ADC_EnableSoftwareStartConv
Verification Apply voltages to the two pin groups and inspect ADC_DualConvertedValueTab in the watch window;
the low and high 16 bits of each 32-bit word should correspond to the ADC1 and ADC2 channels respectively.
Use note The work mode bits of the slave ADC must match the master, and changing the channel configuration causes a dual-ADC restart and loss of synchronisation, so the dual ADC should be disabled first;
DMA moves only the low 16 bits, and the high 16 bits must be read as a word.
Core-code walkthrough and porting

The example puts ADC1 and ADC2 in regular simultaneous mode, where the two results are packed into one 32-bit word moved by DMA.

Data path: ADC1 and ADC2 channels -> ADC_WORKMODE_DUAL_REG_SIMULT -> simultaneous conversion -> DMA moves the word -> ADC_DualConvertedValueTab[16]

1. Configuring ADC1 for regular simultaneous mode. The master ADC is initialized in the dual mode first and then given two regular channels.

src/main.csrc/main.c · ADC_Initial
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStruct(&ADC_InitStructure);
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_DUAL_REG_SIMULT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 2;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel configuration */
    ADC_ConfigRegularChannel(ADC1, ADC1_CH1_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_600);
    ADC_ConfigRegularChannel(ADC1, ADC1_CH2_CHANNEL, 2, ADC_SAMP_TIME_CYCLES_600);

2. Configuring ADC2 with the same mode. The slave ADC keeps the same mode bits as the master, otherwise synchronisation cannot be established.

src/main.csrc/main.c · ADC_Initial
    /* ADC2 configuration ------------------------------------------------------*/
    ADC_InitStruct(&ADC_InitStructure);
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_DUAL_REG_SIMULT;
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_SOFTWARE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 2;
    ADC_Init(ADC2, &ADC_InitStructure);
    /* ADC2 regular channel configuration */
    ADC_ConfigRegularChannel(ADC2, ADC2_CH1_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_600);
    ADC_ConfigRegularChannel(ADC2, ADC2_CH2_CHANNEL, 2, ADC_SAMP_TIME_CYCLES_600);

3. Enabling both ADCs, waiting for ready and then opening DMA. Both ADCs must be enabled and ready, and the DMA request is issued by the master ADC.

src/main.csrc/main.c · ADC_Initial
    /* Enable ADC1 ADC2 */
    ADC_Enable(ADC1, ENABLE);
    ADC_Enable(ADC2, ENABLE);
    /* Check ADC1 Ready */
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY) == RESET)
        ;
    /* Check ADC2 Ready */
    while(ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY) == RESET)
        ;
    /* Enable ADC1 DMA */
    ADC_EnableDMA(ADC1, ENABLE);

4. Having DMA move 16 words with word transfers in normal mode. In simultaneous mode one 32-bit word carries both results, so the transfer width is a word.

src/main.csrc/main.c · DMA_Config
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)ADC_DualConvertedValueTab;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = 16;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_WORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Word;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;

5. Waiting for the DMA transfer to finish in the main loop. In normal mode the transfer complete flag is raised after the configured number of words, and the main program polls and clears it.

src/main.csrc/main.c · main
    ADC_EnableSoftwareStartConv(ADC1, ENABLE);
    /* Test on DMA channel1 transfer complete flag */
    while (!DMA_GetFlagStatus(DMA_FLAG_TC1, DMA))
        ;
    /* Clear DMA channel1 transfer complete flag */
    DMA_ClearFlag(DMA_FLAG_TC1, DMA);

Corresponding source files: src/main.c

5.1.3.9 TIMTrigger_AutoInjection Timer trigger with automatic injection

Example directory: projects/n32g41x_EVAL/examples/ADC/TIMTrigger_AutoInjection/

GTIM1 CH4 compare event triggers→ADC1 regular channel conversion→an injected channel runs automatically after the regular one→the JENDC interrupt reads the injected value→PC6 toggles as an indicator

Item Source analysis
Function Uses the GTIM1 CH4 compare event to trigger a regular conversion, then injects one channel automatically once the regular conversion finishes, reading the injected value in the interrupt.
Source files src/main.c: ADC_Initial, main, RCC_Configuration, GPIO_Configuration, TIM_Configuration, DMA_Config and NVIC_Configuration;
inc/main.h: channel, trigger and pin macros;
src/n32g41x_it.c: ADC1_IRQHandler and the Index definition;
inc/n32g41x_it.h: interrupt declarations;
readme.txt: function and environment notes;
MDK-ARM/ and EWARM/: Keil and IAR projects.
Key configuration The regular channel is PA1 and the injected channel is PB1, with both sequence lengths 1;
MultiChEn and ContinueConvEn are DISABLE and the regular trigger source is ADC_EXT_TRIG_REG_CONV_GTIM1_CC4;
ADC_EnableAutoInjectedConv and ADC_INT_JENDC are enabled;
GTIM1 is prescaled to 16 MHz with period 1600 and CH1 and CH4 in PWM1 mode with pulse 800;
DMA in circular mode with buffer size 32.
Program and data path main initializes clocks, NVIC, GPIO, GTIM1, DMA and the ADC, and finally starts the timer with TIM_Enable(GTIM1, ENABLE);
the regular results are written by DMA into ADC_RegularConvertedValueTab[32], and at the end of each automatic injection ADC1_IRQHandler toggles PC6 and reads the injected value into ADC_InjectedConvertedValueTab[32].
Main APIs ADC_ConfigRegularChannel, ADC_ConfigInjectedSequencerLength, ADC_ConfigInjectedChannel, ADC_EnableAutoInjectedConv, ADC_ConfigInt, ADC_GetInjectedConversionDat, ADC_EnableDMA
Verification Observe the GTIM1 CH4 PWM output on PA3 with an oscilloscope and confirm in the watch window that ADC_RegularConvertedValueTab and ADC_InjectedConvertedValueTab update together;
PC6 emits one pulse on every injection interrupt.
Use note Automatic injection and the discontinuous mode of the regular group cannot be used at the same time;
the injected sequence needs its own length setting, and the argument of ADC_ConfigInjectedChannel is the channel position in the injected sequence.
Core-code walkthrough and porting

The example uses the GTIM1 CH4 event to trigger a regular conversion, with an injected channel running automatically once the regular one finishes.

Data path: GTIM1 CH4 event -> ADC regular trigger -> regular conversion finishes -> the injected channel runs automatically -> the JENDC interrupt reads the injected value and toggles PC6

1. Regular group triggered by GTIM1_CC4, one channel and a single conversion. Only one channel is placed in the regular sequence and the trigger source is timer channel 4.

src/main.csrc/main.c · ADC_Initial
    ADC_InitStruct(&ADC_InitStructure);
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.WorkMode       = ADC_WORKMODE_INDEPENDENT;
    ADC_InitStructure.MultiChEn      = DISABLE;
    ADC_InitStructure.ContinueConvEn = DISABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIG_REG_CONV_GTIM1_CC4;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel configuration */
    ADC_ConfigRegularChannel(ADC1, ADC_REG_CH_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);

2. Configuring automatic injection and enabling the JENDC interrupt. The injected sequence length is 1, and once automatic injection is enabled a regular conversion triggers one injected conversion when it finishes.

src/main.csrc/main.c · ADC_Initial
    /* Set injected sequencer length */
    ADC_ConfigInjectedSequencerLength(ADC1, 1);
    /* ADC1 injected channel configuration */
    ADC_ConfigInjectedChannel(ADC1, ADC_INJ_CH_CHANNEL, 1, ADC_SAMP_TIME_CYCLES_240);
    /* Enable automatic injected conversion start after regular one */
    ADC_EnableAutoInjectedConv(ADC1, ENABLE);

    /* Enable JENDC interrupt */
    ADC_ConfigInt(ADC1, ADC_INT_JENDC, ENABLE);

3. Configuring the GTIM1 time base and the PWM1 output of CH1 and CH4. The timer prescales the clock to 16 MHz with period 1600 and pulse 800 on both channels, where CH4 acts as the ADC trigger source.

src/main.csrc/main.c · TIM_Configuration
    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(GTIM1, &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.Pulse       = Pluse_Val;
    TIM_OCInitStructure.OCPolarity  = TIM_OC_POLARITY_HIGH;
    TIM_InitOc1(GTIM1, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(GTIM1, TIM_OC_PRE_LOAD_ENABLE);

    /* PWM1 Mode configuration: Channel4 */
    TIM_InitOc4(GTIM1, &TIM_OCInitStructure);
    TIM_ConfigOc4Preload(GTIM1, TIM_OC_PRE_LOAD_ENABLE);

    TIM_ConfigArPreload(GTIM1, ENABLE);

4. Reading the injected value and toggling PC6 in the handler. The handler sets PC6 on entry, resets it after reading the injected result, and uses the pin level to indicate that an injected conversion has occurred.

src/n32g41x_it.csrc/n32g41x_it.c · ADC1_IRQHandler
    GPIO_SetBits(GPIO_TOGGLE_PORT, GPIO_TOGGLE_PIN);
    if(ADC_GetIntStatus(ADC1, ADC_INT_JENDC) != RESET)
    {
        /* Clear ADC1 JEOC pending interrupt bit */
        ADC_ClearIntPendingBit(ADC1, ADC_INT_JENDC);

        /* Get injected channel1 converted value */
        ADC_InjectedConvertedValueTab[Index++] = ADC_GetInjectedConversionDat(ADC1, ADC_INJECT_DATA_OFFSET_1);
        /* Reset toggle pin */
        GPIO_ResetBits(GPIO_TOGGLE_PORT, GPIO_TOGGLE_PIN);
        if (Index == 32)
        {
            Index = 0;
        }
    }

Corresponding source files: src/main.c, src/n32g41x_it.c

5.1.4 Notes and troubleshooting

Scenario Check & action Source
ADCCLK above the limit The ADC clock must not exceed 36 MHz;
select a divider of 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 32 or 64 with ADC_ClockModeConfig and choose a larger divider at a high system clock so that ADCCLK stays within 36 MHz.
User manual
Changing the sequence during a conversion ADC_RSEQx and ADC_JSEQ may be changed only while the ADC is idle;
rewriting the sequence during a conversion disturbs the channel order, so stop the conversion before configuring.
User manual
Discontinuous mode conflicting with automatic injection Only one of the regular and injected groups may use discontinuous mode, and automatic injection and discontinuous mode cannot be used at the same time;
disable automatic injection when discontinuous conversions are needed.
User manual
Oversampling and offset compensation Offset compensation has no effect once oversampling is enabled and the OFFSCHxEN bits are ignored;
data alignment is not supported with oversampling either, so neither can be combined with it.
User manual
Master and slave dual-ADC configuration The work mode bits of the slave ADC must match the master;
changing the channel configuration causes a dual-ADC restart and loss of synchronisation, so disable the dual ADC before modifying the configuration.
User manual
Same-channel sample windows in simultaneous mode When the two ADCs sample the same channel in simultaneous mode the sample windows must not overlap, otherwise the results are not reliable;
stagger the sample times or use another mode.
User manual
Temperature sensor accuracy The ideal sample time of the temperature sensor is at least 17.1 us and its maximum error is about 3 degrees Celsius, making it better for observing temperature trends than for measuring absolute temperature;
a longer sample time setting reduces the error.
User manual

The N32G412 and N32G415 series errata sheet V1.0.0 (2026.6.30) lists a single row for revision A chips with an empty errata link column, and gives no ADC-related entries.

Nations Technologies DevKit Docs

Datasheets, SDK, driver APIs and demo guides for Nations Technologies MCU development kits, organized by chip series.

© 2026 Nations Technologies Inc. All rights reserved.粤ICP备11069485号This site uses cookie-free anonymous analytics.