void initAdc (ADC_t * adc) { ADC_CalibrationValues_Load (adc); ADC_ConvMode_and_Resolution_Config (adc, ADC_ConvMode_Unsigned, ADC_RESOLUTION_8BIT_gc); ADC_Prescaler_Config (adc, ADC_PRESCALER_DIV16_gc); // Fadc = 250khz ADC_Reference_Config (adc, ADC_REFSEL_INT1V_gc); // vref = internal 1v /* Setup channel 0, 1, 2 and 3 to have single ended input and 1x gain. */ ADC_Ch_InputMode_and_Gain_Config (&(adc->CH0), ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config (&(adc->CH1), ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config (&(adc->CH2), ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config (&(adc->CH3), ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); /* Enable high level sample complete interrupt for channel 3 */ ADC_Ch_Interrupts_Config (&(adc->CH0), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc); ADC_Ch_Interrupts_Config (&(adc->CH1), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc); ADC_Ch_Interrupts_Config (&(adc->CH2), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc); ADC_Ch_Interrupts_Config (&(adc->CH3), ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc); PMIC.CTRL |= PMIC_HILVLEN_bm; // Enable low level interrupts ADC_Enable (adc); // Enable ADC A with free running mode ADC_Wait_32MHz (adc); // Wait until common mode voltage is stable }
uint16_t readADC(){ uint16_t ADC_result = 0; int8_t offset; /* Move stored calibration values to ADC B */ ADC_CalibrationValues_Load(&ADCA); /* Set up ADC B to have signed conversion mode and 12 bit resolution. */ ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc); // The ADC has different voltage reference options, controlled by the REFSEL bits in the // REFCTRL register. Here the internal reference is selected ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc); // The clock into the ADC decide the maximum sample rate and the conversion time, and // this is controlled by the PRESCALER bits in the PRESCALER register. Here, the // Peripheral Clock is divided by 8 ( gives 250 KSPS with 2Mhz clock ) ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV8_gc); // The used Virtual Channel (CH0) must be set in the correct mode // In this task we will use single ended input, so this mode is selected /* Setup channel 0 to have single ended input. */ ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0, ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // Setting up the which pins to convert. // Note that the negative pin is internally connected to ground ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN1_gc); // Before the ADC can be used it must be enabled ADC_Enable(&ADCA); // Wait until the ADC is ready ADC_Wait_32MHz(&ADCA); // In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is // ouput on the LEDPORT when the conversion is done /* Get offset value for ADC B. */ offset = ADC_Offset_Get_Unsigned(&ADCA, &(ADCA.CH0), true); for(int i = 0; i<5; i++){ ADC_Ch_Conversion_Start(&ADCA.CH0); while(!ADC_Ch_Conversion_Complete(&ADCA.CH0)); //ADCB.INTFLAGS = ADC_CH0IF_bm; // Clear CH0IF by writing a one to it ADC_result += ADCA.CH0RES;// - offset; } return ADC_result/5; }
/** * Name : adc_init * * Synopsis : void adc_init (void) * * Description : Initialize the main system clock * */ void adc_init (void) { /////////////////FROM XPLAINED 1505//////////////////////////////// // Variable for use when we read the result from an ADC channel //PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc; // This pin must be grounded to "enable" NTC-resistor /* Move stored calibration values to ADC B */ ADC_CalibrationValues_Load(&ADCA); /* Set up ADC A to have signed conversion mode and 8 bit resolution. */ ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc); // The ADC has different voltage reference options, controlled by the REFSEL bits in the // REFCTRL register. Here the internal reference is selected ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc); // The clock into the ADC decides the maximum sample rate and the conversion time, and // this is controlled by the PRESCALER bits in the PRESCALER register. Here, the // Peripheral Clock is divided by 8 ( gives 250 KSPS with 2Mhz clock ) ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV8_gc); // The used Virtual Channel (CH0) must be set in the correct mode // In this task we will use single ended input, so this mode is selected /* Setup channel 0 to have single ended input. */ ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); // Setting up the which pins to convert. // Note that the negative pin is internally connected to ground //ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN9_gc, ADC_CH_MUXNEG_PIN1_gc); ADCA.CH0.MUXCTRL |= ADC_CH_MUXPOS_PIN0_gc; ADCA.CH1.MUXCTRL |= ADC_CH_MUXPOS_PIN1_gc; ADCA.CH2.MUXCTRL |= ADC_CH_MUXPOS_PIN2_gc; // Before the ADC can be used it must be enabled ADC_Enable(&ADCA); // Wait until the ADC is ready ADC_Wait_8MHz(&ADCA); // In the while(1) loop, a conversion is started on CH0 and the 8 MSB of the result is // output on the LEDPORT when the conversion is done /* Get offset value for ADC B. */ adcx.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH0), true); adcy.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH1), true); adcz.offset = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true); }
void adc_init(void) { ADC_CalibrationValues_Load(&ADCA); ADC_ConvMode_and_Resolution_Config(&ADCA, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc); ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV16_gc); ADC_Reference_Config(&ADCA, ADC_REFSEL_VCC_gc); ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0, ADC_CH_INPUTMODE_SINGLEENDED_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN7_gc, ADC_CH_MUXNEG_PIN0_gc); ADC_Enable(&ADCA); ADC_Wait_8MHz(&ADCA); }
void adc_temp_init(void) { // enable 1V reference and temperature modules ADC_BandgapReference_Enable(&ADCB); ADC_TempReference_Enable(&ADCB); // load calibration from signature bytes ADC_CalibrationValues_Load(&ADCB); // Conversion mode and resolution (12 bit right-aligned) ADC_ConvMode_and_Resolution_Config(&ADCB, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc); // prescaler from system clock (fastest) ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV4_gc); // internal 1V reference ADC_Reference_Config(&ADCB, ADC_REFSEL_INT1V_gc); // channel 0 for temperature ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0, ADC_CH_INPUTMODE_INTERNAL_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXINT_TEMP_gc, ADC_CH_MUXNEG_PIN0_gc); // channel 1 for VCC/10 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1, ADC_CH_INPUTMODE_INTERNAL_gc, ADC_CH_GAIN_1X_gc); ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXINT_SCALEDVCC_gc, ADC_CH_MUXNEG_PIN0_gc); ADC_Enable(&ADCB); ADC_Wait_8MHz(&ADCB); }
int main(void) { facilitatePowersaving(); // Configure switches PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches SWITCHPORT.DIRCLR = 0xff; // Set port as input // Configure LEDs PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1 LEDPORT.DIRSET = 0xff; // Set port as output LEDPORT.OUT = 0x00; // Set initial value // Set up ADCB0 on PB0 to read temp sensor. More of this can be achieved by using driver from appnote AVR1300 PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc; // This pin must be grounded to "enable" NTC-resistor PORTB.DIRCLR = PIN0; PORTB.PIN0CTRL = (PORTB.PIN0CTRL & ~PORT_OPC_gm); ADC_CalibrationValues_Load(&ADCB); // Load factory calibration data for ADC ADCB.CH0.CTRL = (ADCB.CH0.CTRL & ~ADC_CH_INPUTMODE_gm) | ADC_CH_INPUTMODE_SINGLEENDED_gc; // Single ended input ADCB.CH0.MUXCTRL = (ADCB.CH0.MUXCTRL & ~ADC_CH_MUXPOS_gm) | ADC_CH_MUXPOS_PIN0_gc; // Pin 0 is input ADCB.REFCTRL = (ADCB.REFCTRL & ~ADC_REFSEL_gm) | ADC_REFSEL_VCC_gc; // Internal AVCC/1.6 as reference ADCB.CTRLB |= ADC_FREERUN_bm; // Free running mode ADCB.PRESCALER = (ADCB.PRESCALER & ~ADC_PRESCALER_gm) | ADC_PRESCALER_DIV512_gc; // Divide clock by 1024. ADCB.CTRLB = (ADCB.CTRLB & ~ADC_RESOLUTION_gm) | ADC_RESOLUTION_8BIT_gc; // Set 8 bit resolution ADCB.CTRLA |= ADC_ENABLE_bm; // Enable ADC // Set up DMA CH0 to transfer from ADC to LEDS. We only read low byte. DMA_Enable(); DMA_SetupBlock( &DMA.CH0, (void const *) &(ADCB.CH0RES), DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_FIXED_gc, (void const *) &(LEDPORT.OUT), DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_FIXED_gc, 1, DMA_CH_BURSTLEN_1BYTE_gc, 0, true ); DMA_EnableSingleShot( &DMA.CH0 ); DMA_SetTriggerSource( &DMA.CH0, DMA_CH_TRIGSRC_ADCB_CH0_gc ); // ADC Channel 0 is trigger source. // Set up interrupt on button 0, or else we can't come back from IDLE SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc; SWITCHPORT.INT0MASK = SWITCHMASK_ACTIVE; SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_FALLING_gc; // Enable low interrupt level in PMIC and enable global interrupts. PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); // Main loop. while (1) { if ((SWITCHPORT.IN & SWITCHMASK_ACTIVE) == 0x00) { // Button 0 pressed. Enter ACTIVE mode again. DMA_DisableChannel( &DMA.CH0 ); SLEEP.CTRL &= ~SLEEP_SEN_bm; // Disable sleep. sleep() is now ineffective. } else if ((SWITCHPORT.IN & SWITCHMASK_IDLE) == 0x00) { // Button 1 pressed. Enter Idle mode DMA_EnableChannel( &DMA.CH0 ); // Set and enable sleep. SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep. } else if (SLEEP.CTRL & SLEEP_SEN_bm) { // We are in wanting-to-sleep mode, but were awake. sleep(); } else { // Do active sampling and transfer of ADC data. LEDPORT.OUT = ADCB.CH0RES & 0xFF; } } }
int main(void) { //! set the power reduction register to minimize current consumption init_power_reduction(); //! set CPU clock to 32MHz and enables the DFLL32MHz clock_init(); //! initialize the LCD module init_lcd(); //! display all the segments in LCD lcd_show_all(); //! initialize the GPIO pins init_ioport(); //! initializes the UART init_UART(); //! load the calibration data from flash ADC_CalibrationValues_Load(&ADCA); //! get the ADC offset value get_offset(); //! initialize the ADC init_ADC(); //! load the calibration value from eeprom init_eeprom(); //! initilize RTC to external clock and 1 sec interrupt rtc_init(); //! initilize the timer init_timer(); while(1) { //! rtc_flag is set if (rtc_flag == 1) { //! perform the calculation of metering paramters calculate(); //for debugging if(cover_open_flag ==1) PORTD.OUTTGL = PIN3_bm; //TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc; TCC1.INTCTRLA = (TCC1.INTCTRLA & ~(TC1_OVFINTLVL_gm | TC1_ERRINTLVL_gm))|TC1_OVFINTLVL0_bm; //! if power on detected if(power_status_flag == POWER_ON_DETECTED) { //! change the clock frequency to 32MHz CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc ); //! switch off the battery PORTD.PIN4CTRL = PORT_OPC_WIREDANDPULL_gc; //PORTD.OUTSET = PIN4_bm; //! initialize gpio pins init_ioport(); //! change the sleep mode to ideal sleep SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_IDLE_gc; //! enable ADC & Timer ADC_Enable(&ADCA); TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc; //! initialize lcd module init_lcd(); //! update power status flag power_status_flag = POWERED_UP; } //! update the LCD display lcd_disp_key(); tamper_check(); if( active_power[0] > max_demand ) { max_demand = active_power[0]; } //! check for calibration flag and proceed and call the appropriate calibration funtion if(calibration_flag != 0) { //! checking the calibration flag for calibrating the date & time if (calibration_flag == 1) { calibrate_time_date(); } //! checking the calibration flag for calibrating the voltage else if (calibration_flag == 2) { calibrate_voltage(); } //! checking the calibration flag for calculating the offset value else if (calibration_flag == 3) { calibrate_no_load(); } //! checking the calibration flag for calculating the phase angle variation else if (calibration_flag == 4) { calibrate_phase(); } //! checking the calibration flag for calculating watt varition else if (calibration_flag == 5) { calibrate_watt(); } else if (calibration_flag == 6) //! checking the calibration flag for calibrating the current { calibrate_current(); } } rtc_flag = 0; __watchdog_reset(); } //! checking the power_status, if power off is detected else if(power_status_flag == POWER_OFF_DETECTED) { //! switch on the battery PORTD.PIN4CTRL = PORT_OPC_WIREDAND_gc; //PORTD.OUTCLR = PIN4_bm; //! change the sleep mode to power save mode SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm)| SLEEP_SMODE_PSAVE_gc; //! switch off the LCD lcd_command(LCD_COMMAND,0x02); //! change reset the gpio pin facilitatePowersaving(); //! disable the ADC ADC_Disable(&ADCA); //! disable the timer TCC1.CTRLA = ( TCC1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_OFF_gc; //! clear all the varilable used in for energy calculation meter_flush(); //! reduce the cpu clock frequency to minimize power consumption CLKSYS_Prescalers_Config( CLK_PSADIV_64_gc, CLK_PSBCDIV_1_1_gc ); //! update power status flag power_status_flag = POWER_OFF; __watchdog_reset(); } //! goes to sleep SLEEP.CTRL |= SLEEP_SEN_bm; asm("sleep"); } }
//----------------------------------------------------------------------------- // functions //----------------------------------------------------------------------------- void adc_init(void) { /* Note: port_init() must be run before this function, so that the inputs are set correctly. We are using both ADCs. So everything will be set up for ADCA && ADCB. */ // Load the production calibration data into each ADC. // This data was taken by Atmel and is stored in the micro. // This function takes care of the whole process for you. ADC_CalibrationValues_Load(&ADCA); ADC_CalibrationValues_Load(&ADCB); // Set the mode of operation for each ADC // Signed operation mode is required for the differential configuration. ADC_ConvMode_and_Resolution_Config(&ADCA,signed_y,ADC_RESOLUTION_12BIT_gc); ADC_ConvMode_and_Resolution_Config(&ADCB,signed_y,ADC_RESOLUTION_12BIT_gc); // Set ADC clocks // 32MHz / 128 = 250KHz // I currently have no explanation for this choice // Atmel documentation states that you need to stay within the recommended // ADC frequencies, but I cannot find the specific numbers. ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV128_gc); ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV128_gc); // Select reference to be external reference on PIN0 for A and B ADC_Reference_Config(&ADCA, ADC_REFSEL_AREFA_gc); ADC_Reference_Config(&ADCB, ADC_REFSEL_AREFB_gc); // Setup all channels to have differential input and 1X gain ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // V1 ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // V2 ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // reference ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // I1 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH1,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // I2 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH2,ADC_CH_INPUTMODE_DIFF_gc, ADC_CH_GAIN_1X_gc); // reference // Select the input pins for each ADC. /* See AnodV2.1.sch eagle file: V1 - A1 V2 - A2 I1 - B1 I2 - B2 Ref - A0,A3,B0,B3 */ ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN1_gc, \ ADC_CH_MUXNEG_PIN3_gc); // V1 ADC_Ch_InputMux_Config(&ADCA.CH1, ADC_CH_MUXPOS_PIN2_gc, \ ADC_CH_MUXNEG_PIN3_gc); // V2 ADC_Ch_InputMux_Config(&ADCA.CH2, ADC_CH_MUXPOS_PIN3_gc, \ ADC_CH_MUXNEG_PIN3_gc); // Offset calib ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN1_gc, \ ADC_CH_MUXNEG_PIN3_gc); // V1 ADC_Ch_InputMux_Config(&ADCB.CH1, ADC_CH_MUXPOS_PIN2_gc, ADC_CH_MUXNEG_PIN3_gc); // V2 ADC_Ch_InputMux_Config(&ADCB.CH2, ADC_CH_MUXPOS_PIN3_gc, ADC_CH_MUXNEG_PIN3_gc); // Offset calib // Configure the ADCA.CH2 interrupt. // This will trip once a reading on channel 2 has been completely resolved. // I am assuming the chan 0 and 1 of both ADCs will have their results completed // when chan 2 is done. This is based from the Xmega A manual (sect 25) ADC_Ch_Interrupts_Config(&ADCA.CH1, ADC_CH_INTMODE_COMPLETE_gc, \ ADC_CH_INTLVL_LO_gc); //Enable ADCs ADC_Enable(&ADCA); ADC_Enable(&ADCB); // Wait until common mode voltage is stable so tha bypass transients are not passed. // What is the difference between the 32 and 8 MHz versions, // and which one do I want? ADC_Wait_32MHz(&ADCA); ADC_Wait_32MHz(&ADCB); // The TCD0 timer will periodically trigger an event that will create an event // on channel 0. (Xmega A manual sect 6) eflags.setEventSource = EVSYS_SetEventSource(0, EVSYS_CHMUX_TCD0_OVF_gc); TC0_ConfigClockSource(&TCD0, TC_CLKSEL_DIV8_gc); TCD0.PER = 200; // 1/f = 1/(32MHz/DIVx/PER) --- 200---50us---20KHz // This is moved to the adc_test() fun. May want to enable it here later. // enable timer overflow int and set priority to low. //TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc; // An event on eventChan 0 will trigger a sweep of chan 0,1 in ADCA && ADCB. // I do not know what would happen if an event happened on eventChan 1,2,3. ADC_Events_Config(&ADCA, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc); ADC_Events_Config(&ADCB, ADC_EVSEL_0123_gc, ADC_EVACT_SWEEP_gc); ADC_SweepChannels_Config(&ADCA, ADC_SWEEP_01_gc); ADC_SweepChannels_Config(&ADCB, ADC_SWEEP_01_gc); // Calibration routine for the ADCs // Find offset with two pins shorted together. // Steve also found the offset for the current with 0 current flowing into them, // but did not do an equivalent for voltage. I will leave this out for now. offset_A = ADC_Offset_Get_Signed(&ADCA, &(ADCA.CH2), true); offset_B = ADC_Offset_Get_Signed(&ADCB, &(ADCB.CH2), true); }