5.31 VREFBUF Guide
This chapter describes the file composition and 6 public functions of the VREFBUF driver in the N32H49x standard peripheral library, together with the ADC_VREFBUF example. The VREFBUF is a voltage reference buffer built into the chip that can supply a 2.048 V, 2.5 V or 2.9 V reference to the ADC, the 12-bit DAC or external components; for the distinction between output mode and external input mode, and the high-impedance configuration and enable order, see the “Voltage reference buffer (VREFBUF)” chapter of the user manual.
5.31.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_vrefbuf.h |
Defines the voltage scale options and register masks, and declares the 6 public functions |
firmware/n32h49x_std_periph_driver/src/n32h49x_vrefbuf.c |
Implements the 6 functions above: enable and high-impedance control, scale selection and factory trim retrieval, trim enable and trim code writing, and ready status readback |
projects/n32h49x_EVAL/examples/VREFBUF/ |
VREFBUF example root directory, containing the single ADC_VREFBUF example |
projects/n32h49x_EVAL/examples/VREFBUF/ADC_VREFBUF/ |
Project directory composition of this example: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32h49x_EVAL/bsp/ |
Common board files referenced by this example: the UART log function |
5.31.2 API reference
The following 6 public functions are listed in the declaration order of n32h49x_vrefbuf.h in 3 groups; each entry gives a summary and the original comment above the function in n32h49x_vrefbuf.c.
Enable and high impedance
VREFBUF_Enable, VREFBUF_EnableHIM
Voltage scale and trim
VREFBUF_SetVoltageScale, VREFBUF_EnableTrim, VREFBUF_SetTrimming
Status
VREFBUF_IsVREFReady
void VREFBUF_Enable(FunctionalState Cmd)Enable or disable internal voltage reference.
name VREFBUF_Enable.
fun Enable or disable internal voltage reference.
param Cmd :
- ENABLE
- DISABLE
return none
void VREFBUF_EnableHIM(FunctionalState Cmd)Enable or disable high impedance (VREF+ pin is high impedance).
name VREFBUF_EnableHIM.
fun Enable or disable high impedance (VREF+ pin is high impedance).
param Cmd :
- ENABLE
- DISABLE
return none
void VREFBUF_SetVoltageScale(uint32_t Scale)Set the Voltage reference scale.
name VREFBUF_SetVoltageScale.
fun Set the Voltage reference scale.
param Scale
- VREFBUF_VOLTAGE_SCALE_2_048V
- VREFBUF_VOLTAGE_SCALE_2_5V
- VREFBUF_VOLTAGE_SCALE_2_9V
return none
Use note: The implementation first loads the trim value for the selected scale from the factory calibration area into VREFBUF_TRIM, then updates the scale selection bits in RCC->VREFCTRL; the function enables the PWR clock itself before doing so.
void VREFBUF_EnableTrim(FunctionalState Cmd)Enable or disable VREFBUF triming.
name VREFBUF_EnableTrim.
fun Enable or disable VREFBUF triming.
param Cmd :
- ENABLE
- DISABLE
return none
void VREFBUF_SetTrimming(uint32_t Value)Set the trimming code for VREFBUF calibration.
name VREFBUF_SetTrimming.
fun Set the trimming code for VREFBUF calibration.
param Value :Value Between 0 and 0x3F
return none
FlagStatus VREFBUF_IsVREFReady(void)Checks whether VREFBUF ready flag is set or not.
name VREFBUF_IsVREFReady.
fun Checks whether VREFBUF ready flag is set or not.
param none
return The new state of VREFBUF_READY (SET or RESET).
5.31.3 Demo descriptions
This section describes the single VREFBUF example: ADC_VREFBUF configures the VREFBUF in output mode to output a 2.5 V reference and samples VREF+ with the VREFINT channel of ADC1.
5.31.3.1 ADC_VREFBUF VREFBUF reference voltage sampling
Example directory: projects/n32h49x_EVAL/examples/VREFBUF/ADC_VREFBUF/
Configure the system and ADC clocks→Set the analog input pins to analog mode→Initialize the ADC and run calibration→Configure the VREFBUF voltage scale in output mode and wait for ready→Sample the VREFINT channel repeatedly in the main loop
| Item | Source analysis |
|---|---|
| Function | Configures the VREFBUF in output mode to output a 2.5 V reference and waits for VREFBUF_CTRL.RDY;ADC1 samples VREF+ through the internal ADC1_Channel_18_VREFINT channel, and the conversion result is stored periodically in ADC1ConvertedValue[0]. |
| Source files | src/main.c: main, RCC_Configuration, GPIO_Configuration, ADC_Initial, VREFBUF_CONFIG, ADC_GetData;inc/main.h: includes n32h49x_adc.h, n32h49x_vrefbuf.h, n32h49x_rcc.h, n32h49x_gpio.h;src/n32h49x_it.c, inc/n32h49x_it.h: interrupt service routines (exception handlers only);readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16) and RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8);Pins: PA1 and PA2 set as analog input; Reference: VREFBUF_MODE_OUTPUT with VREFBUF_VOLTAGE_SCALE_2_5V, and VREFBUF_EnableHIM(DISABLE) is called;ADC: independent mode, 12-bit resolution, software trigger, sample time ADC_SAMP_TIME_CYCLES_239_5. |
| Program and data path | main calls RCC_Configuration, GPIO_Configuration and ADC_Initial(ADC1) in turn;ADC_Initial configures the conversion parameters, enables the internal VREFINT channel, enables the ADC and waits for ADC_FLAG_RDY, then performs a single calibration;VREFBUF_CONFIG selects output mode, sets the 2.5 V scale, disables high impedance, enables the buffer and waits for VREFBUF_IsVREFReady;while(1) samples VREF+ repeatedly with ADC_GetData(ADC1, ADC1_Channel_18_VREFINT). |
| Main APIs | VREFBUF_SetVoltageScale, VREFBUF_EnableHIM, VREFBUF_Enable, VREFBUF_IsVREFReady |
| Verification | After building, downloading and running, observe ADC1ConvertedValue[0] with a debugger;its code corresponds to a VREF+ sample of about 2.5 V; a multimeter on the VREF+ pin reading close to 2.5 V also shows that the output is normal. |
| Use note | The hardware development environment is the full-featured board N32H497ZGL7_EVB V1.0; the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1; a 100 nF decoupling capacitor must be placed close to the VREF+ pin; the example switches between output and input mode by writing bit10 of VREFBUF_EN_CTRL (address 0x40010020) directly. |
Core-code walkthrough and porting
The example first configures the system and ADC clocks and the analog input pins and completes the ADC calibration, then configures the VREFBUF voltage scale in output mode and waits for ready, and finally samples the VREFINT channel repeatedly in the main loop.
Data path: RCC_Configuration configures the GPIO and ADC clocks → GPIO_Configuration sets PA1 and PA2 as analog input → ADC_Initial enables the VREFINT channel and calibrates → VREFBUF_CONFIG writes VREFBUF_TRIM and RCC->VREFCTRL and waits for ready → ADC_GetData samples VREFINT into ADC1ConvertedValue
1. Configure the system and ADC clocks. RCC_Configuration enables the GPIOA to GPIOD and ADC1 clocks, sets the ADC working clock to an AHB division and the ADC1M clock source to HSI.
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable GPIOA, GPIOB, GPIOC ,GPIOD clocks */
RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB | RCC_AHB_PERIPHEN_GPIOC | RCC_AHB_PERIPHEN_GPIOD, ENABLE);
/* Enable ADC1 clocks */
RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_ADC1 ,ENABLE);
/* RCC_ADCHCLK_DIV16*/
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV16);
RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8); //selsect HSI as RCC ADC1M CLK Source
When porting to other models the unused GPIO clocks can be trimmed, but the ADC1 clock and the ADC_ConfigClk and RCC_ConfigAdc1mClk settings must stay consistent.
2. Configure the analog input pins. GPIO_Configuration configures PA1 and PA2 as analog mode for the ADC to sample.
void GPIO_Configuration(void)
{
GPIO_InitType GPIO_InitStructure;
/* Configure PA1 PA2 as analog input -----------------------*/
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2;;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_ANALOG;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
}
When porting to another board, only GPIO_InitStructure.Pin and the actual channel pins need to change; sampling the internal VREFINT channel does not use an external pin.
3. Initialize the ADC and calibrate. ADC_Initial configures independent mode, 12-bit resolution and software trigger, enables the internal VREFINT channel, waits for ADC_FLAG_RDY and then performs a single calibration.
void ADC_Initial(ADC_Module* ADCx)
{
/* 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_InitStructure.Resolution = ADC_DATA_RES_12BIT;
ADC_Init(ADCx, &ADC_InitStructure);
ADC_EnableTempSensorVrefint(ENABLE);
/* Enable ADCx */
ADC_Enable(ADCx, ENABLE);
/*Check ADC Ready*/
while(ADC_GetFlagStatus(ADCx,ADC_FLAG_RDY) == RESET)
;
/* Start ADCx calibration */
ADC_CalibrationOperation(ADCx,ADC_CALIBRATION_SINGLE_MODE);
/* Check the end of ADCx calibration */
while (ADC_GetCalibrationStatus(ADCx,ADC_CALIBRATION_SINGLE_MODE))
;
}
When porting, keep the empty loops that wait for ready and for the calibration to finish; without these two steps the conversion result is unreliable.
4. Configure and start the VREFBUF. In output mode VREFBUF_CONFIG first writes bit10 of VREFBUF_EN_CTRL to select the internal reference, then sets the voltage scale, disables high impedance, enables the buffer and waits for ready; input mode does the opposite.
if(VrefBufferMode == VREFBUF_MODE_OUTPUT)
{
*(uint32_t *)VREFBUF_EN_CTRL |= (1<<10);
VREFBUF_SetVoltageScale(voltage);
VREFBUF_EnableHIM(DISABLE);
VREFBUF_Enable(ENABLE);
while(VREFBUF_IsVREFReady() == RESET);
}
else
{
*(uint32_t *)VREFBUF_EN_CTRL &= (~(1<<10));
VREFBUF_EnableHIM(ENABLE);
VREFBUF_Enable(DISABLE);
}
In output mode high impedance must be disabled (HIM = 0) before enabling the buffer, otherwise VREF+ does not output the internal reference voltage.
5. Sample VREFINT in the main loop. After the initialization above, main samples ADC1_Channel_18_VREFINT repeatedly with ADC_GetData inside while(1).
int main(void)
{
/* System clocks configuration ----------------------------------------------*/
RCC_Configuration();
/* GPIO configuration -------------------------------------------------------*/
GPIO_Configuration();
/* ADC1 configuration -----------------------------------------*/
ADC_Initial(ADC1);
VREFBUF_CONFIG(VREFBUF_MODE_OUTPUT,VREFBUF_VOLTAGE_SCALE_2_5V);
while (1)
{
ADC1ConvertedValue[0]=ADC_GetData(ADC1,ADC1_Channel_18_VREFINT);
}
}
ADC_GetData reconfigures the regular channel and starts a software conversion on each sample, which suits polling observation of VREF+ changes.
Corresponding source files: src/main.c
5.31.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| Output mode and external input mode | Output mode and external input mode are mutually exclusive; never enable the external input while the internal output is active. |
User manual |
| VREF+ tied to VDDA | If VREF+ and VDDA are tied together in the package, the voltage reference buffer is unavailable, must stay disabled, and VREFBUF_CTRL.HIM must be set to 1. |
User manual |
| Enable order and ready | Configure VREFBUF_CTRL.HIM to 0 first, then set VREFBUF_CTRL.EN to 1;wait until VREFBUF_CTRL.RDY is set (the output has reached 90% of the expected value) before using the reference voltage. |
User manual |
| Voltage constraints | The input voltage on VREF+ must not exceed VDDA; once the VREFBUF is enabled, no external voltage may be applied to the VREF+ pin. |
User manual |
| VREF- connection | While the VREFBUF is operating, VREF- is connected to VSSA by default. | User manual |
| Decoupling capacitor | The 100 nF filter capacitor is important and must be placed on the PCB as close as possible to the VREF+ pin. | User manual |
| Trim data | On every VREFBUF restart or scale change the calibration data is loaded automatically into VREFBUF_CTRL.TRIMDATA[5:0];after writing TRIMDATA[5:0] directly, set TRIMEN for the new trim to take effect, after which the scale setting no longer affects this register until the device is reset. |
User manual |