vadc_usage.h File Reference


Detailed Description

Headerfile for vadc_usage.c.

Contains defines and prototypes for vadc_usage.c. Also contains external variable definitions for cell voltage, vadc voltages and vadc sampling complete flag.

Application note:
AVR353: Voltage Reference Calibration and Voltage ADC Usage
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Revision
4814
Date
2008-11-04 12:29:56 +0100 (ti, 04 nov 2008)

Copyright (c) 2008, Atmel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file vadc_usage.h.

#include <stdint.h>

Include dependency graph for vadc_usage.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define BANDGAP_ADJ_DELAY   20*SYSTEM_CLK_Hz/1000000
 Delay to avoid brown-out scaled to system clock cycles. See appnote for details.
#define BANDGAP_WAIT_us   20
 Wait between each update of BGCCR to avoid brown-out for a CREG of <10uF. Given in hole microseconds (from datasheet).
#define BOTTOM_CELL   1
 ADC channel for bottom cell.
#define CALIB_HOT   70
#define CALIB_ROOM   25
#define CELL1   3
 Index into vadc_measurement. VADC_ISR() determines order.
#define CELL2   4
 Index into vadc_measurement. VADC_ISR() determines order.
#define FAILED   -1
#define FIRST_VADC_MEAS   4
 First ADC channel measured - temp sensor.
#define LAST_VADC_MEAS   6
 Last ADC channel measured before Cells.
#define NO_CELLS   2
 Number of cell inputs.
#define NO_VADC   2
 Number of temperature and normal vadc inputs.
#define NO_VADC_CHANNELS   5
 Total number of VADC channels.
#define SUCCESS   0
#define SYSTEM_CLK_Hz   1000000
 System clock frequency in Hz.
#define TOP_CELL   2
 ADC channel for top cell.
#define VADC0   1
 Index into vadc_measurement. VADC_ISR() determines order.
#define VADC1   2
 Index into vadc_measurement. VADC_ISR() determines order.
#define VADC_SCALE_BITS   14
 Number of bit for scaling results (16384). See appnote for formulas/details.
#define VPTAT   0
 Index into vadc_measurement. VADC_ISR() determines order.

Functions

void CalculateADCResults (void)
 Calculate results from the VADC raw values.
int8_t CalibrateVREF (void)
 Voltage reference calibration.
int8_t InitBandgap (void)
 Bandgap initialisation.
void InitCoeff (void)
 Function to load coefficients needed from the signature row.
int16_t MeasureVADCerror (void)
 Measure VADC error.
void StartVADCScan (void)
 Start a scan of all VADC channels.

Variables

uint16_t bg_temp
 Global variable for the result of band-gap temperature measurement/calculation.
uint16_t cell_v [NO_CELLS]
 Global variable for results of Cell Voltage measurements/calculations.
uint8_t vadc_scan_complete
 Flag for signalling VADC sampling complete.
uint16_t vadc_v [NO_VADC]
 Global variable for results of Voltage ADC measurements/calculations.


Define Documentation

#define BANDGAP_ADJ_DELAY   20*SYSTEM_CLK_Hz/1000000

Delay to avoid brown-out scaled to system clock cycles. See appnote for details.

Definition at line 63 of file vadc_usage.h.

Referenced by InitBandgap().

#define BANDGAP_WAIT_us   20

Wait between each update of BGCCR to avoid brown-out for a CREG of <10uF. Given in hole microseconds (from datasheet).

Definition at line 60 of file vadc_usage.h.

#define BOTTOM_CELL   1

ADC channel for bottom cell.

Definition at line 79 of file vadc_usage.h.

Referenced by VADC_ISR().

#define CALIB_HOT   70

Definition at line 68 of file vadc_usage.h.

Referenced by InitBandgap(), and main().

#define CALIB_ROOM   25

Definition at line 67 of file vadc_usage.h.

Referenced by InitBandgap(), and main().

#define CELL1   3

Index into vadc_measurement. VADC_ISR() determines order.

Definition at line 88 of file vadc_usage.h.

Referenced by CalculateADCResults().

#define CELL2   4

Index into vadc_measurement. VADC_ISR() determines order.

Definition at line 89 of file vadc_usage.h.

#define FAILED   -1

Definition at line 66 of file vadc_usage.h.

Referenced by CalibrateVREF(), and InitBandgap().

#define FIRST_VADC_MEAS   4

First ADC channel measured - temp sensor.

Definition at line 81 of file vadc_usage.h.

Referenced by StartVADCScan().

#define LAST_VADC_MEAS   6

Last ADC channel measured before Cells.

Definition at line 82 of file vadc_usage.h.

Referenced by VADC_ISR().

#define NO_CELLS   2

Number of cell inputs.

Definition at line 74 of file vadc_usage.h.

Referenced by CalculateADCResults().

#define NO_VADC   2

Number of temperature and normal vadc inputs.

Definition at line 75 of file vadc_usage.h.

Referenced by CalculateADCResults().

#define NO_VADC_CHANNELS   5

Total number of VADC channels.

Definition at line 76 of file vadc_usage.h.

#define SUCCESS   0

Definition at line 65 of file vadc_usage.h.

Referenced by CalibrateVREF().

#define SYSTEM_CLK_Hz   1000000

System clock frequency in Hz.

Definition at line 57 of file vadc_usage.h.

#define TOP_CELL   2

ADC channel for top cell.

Definition at line 78 of file vadc_usage.h.

Referenced by VADC_ISR().

#define VADC0   1

Index into vadc_measurement. VADC_ISR() determines order.

Definition at line 86 of file vadc_usage.h.

Referenced by CalculateADCResults().

#define VADC1   2

Index into vadc_measurement. VADC_ISR() determines order.

Definition at line 87 of file vadc_usage.h.

#define VADC_SCALE_BITS   14

Number of bit for scaling results (16384). See appnote for formulas/details.

Definition at line 71 of file vadc_usage.h.

Referenced by CalculateADCResults(), and MeasureVADCerror().

#define VPTAT   0

Index into vadc_measurement. VADC_ISR() determines order.

Definition at line 85 of file vadc_usage.h.

Referenced by CalculateADCResults().


Function Documentation

void CalculateADCResults ( void   ) 

Calculate results from the VADC raw values.

Function uses values from vadc_measurement variable and stores results in global variables cell_v and bg_temp. The formulas are found in the data sheet and details in the application note.

Definition at line 300 of file vadc_usage.c.

References bg_temp, CELL1, cell_gain, cell_offset, cell_v, NO_CELLS, NO_VADC, VADC0, vadc_gain, vadc_measurement, vadc_offset, VADC_SCALE_BITS, vadc_v, VPTAT, and vptat_coeff.

Referenced by main().

00301 {
00302     uint32_t calc;
00303     uint8_t index;
00304 
00305     // Calculate new cell voltages.
00306     for(index = 0 ; index < NO_CELLS ; index++) {
00307         calc = vadc_measurement[index + CELL1];
00308         calc -= cell_offset[index];
00309         calc *= cell_gain[index];
00310         cell_v[index] = (uint16_t)(calc >> VADC_SCALE_BITS);
00311     }
00312 
00313     /* Code checking for under or over-voltage, and/or calculating cell
00314      * impedances could be inserted here.
00315      */
00316 
00317     // Calculate new VADC voltages.
00318     for(index = 0 ; index < NO_VADC ; index++) {
00319         calc = vadc_measurement[index + VADC0];
00320         calc -= vadc_offset[index];
00321         calc *= vadc_gain[index];
00322         vadc_v[index] = (uint16_t)((calc >> VADC_SCALE_BITS)/10);
00323     }
00324 
00325     // Calculate temperature from measurement of internal temp sensor (VPTAT).
00326     calc = vadc_measurement[VPTAT];
00327     calc *= vptat_coeff;
00328     calc >>= VADC_SCALE_BITS;
00329     bg_temp = (uint16_t)(calc);
00330 
00331     /* Code for calculating temperature from external thermistors connected to
00332      * VADC0 and/or VADC1 could be inserted here. Gain and offset coefficients for
00333      * vadc inputs are stored in signature row.
00334      */
00335 }

int8_t CalibrateVREF ( void   ) 

Voltage reference calibration.

Calibrates the bandgap reference. Assumes 4096mV in on PV1 (Cell1). Values in calibration.h have to be adjusted if any other value is used. The reference needs to be calibrated to factory default before performing this calibration, and if it fails the reference is not correct and factory defaults should be used.

Calibration of bandgap at room temperature only needs to be done if device isn't calibrated so in Atmel factory. Otherwise calibration can be done by reading out signature data.

Returns:
Status, SUCCESS or FAILED as defined in vadc_usage.h

Definition at line 353 of file vadc_usage.c.

References CAL_CHANNEL, FAILED, MeasureVADCerror(), SUCCESS, temp_cal, and vcalibration_level.

Referenced by main().

00354 {
00355     volatile uint32_t temp;
00356     int16_t v_error;        // Variable to keep error after conversion.
00357     int16_t last_v_error;   // Value used to keep old error value during linear scan.
00358     int8_t counter;         // Value used to count BGCCR value and index.
00359 
00360     // Select terminal input defined in calibration.h
00361     VADMUX = CAL_CHANNEL;
00362 
00363     // Enable the VADC.
00364     VADCSR = (1 << VADEN);
00365 
00366     // Start a VADC conversion and clear any pending interrupts
00367     VADCSR |= (1 << VADSC) | (1 << VADCCIF);
00368 
00369     // Wait while conversion in progress
00370     do {} while(!(VADCSR & (1 << VADCCIF)));
00371 
00372     // Dummy read to ensure correct data for next conversion.
00373     temp = VADC;
00374 
00375 
00376     /* If using cell balancing (e.g ATmega406, and not on ATmega8/16HVA),
00377      * code should be inserted here to wait for error to cancel out.
00378      */
00379 
00380     // First we do the BGCRR / temperature stability calibration.
00381     v_error = MeasureVADCerror();
00382     counter = 8;
00383 
00384     // Check for all different test limits.
00385     while ( (v_error < vcalibration_level[counter]) && (counter >= 0) ) {
00386         counter--;
00387     }
00388 
00389     // Set BGCRR to correct setting.
00390     BGCRR = temp_cal[counter];
00391 
00392     // Then we do the BGCCR / absolute value calibration.
00393     v_error = MeasureVADCerror();
00394 
00395     if (v_error < 0){
00396         do {
00397             // Ratio_counter bit 6 set means calibration failed.
00398             if(--BGCCR == 0x40){
00399                 // Return with fail flag.
00400                 return FAILED;
00401             }
00402             last_v_error = v_error;
00403             v_error = MeasureVADCerror();
00404 
00405         } while (v_error < 0);
00406 
00407         // Neighbor check, as previous step can select the next best value.
00408         if (v_error > -last_v_error){
00409             BGCCR++;
00410         }
00411 
00412     }else{
00413         do{
00414             // Ratio_counter bit 6 set means calibration failed.
00415             if(++BGCCR == 0x40){
00416                 // Return with fail flag.
00417                 return FAILED;
00418             }
00419             last_v_error = v_error;
00420             v_error = MeasureVADCerror();
00421 
00422         } while (v_error < 0);
00423 
00424         // Neighbor check, as previous step can select the next best value.
00425         if(-v_error > last_v_error){
00426             BGCCR--;
00427         }
00428     }
00429 
00430     /* The found values should be stored in eeprom or possibly flash for
00431      * correct initialisation if device is reset.
00432      */
00433     return SUCCESS;
00434 }

Here is the call graph for this function:

int8_t InitBandgap ( void   ) 

Bandgap initialisation.

Initialises the bandgap voltage reference to factory calibration. If second calibration has been done at room temperature those values are loaded. BGCCR need to be changed slowly to avoid BOD. See appnote for details.

Return values:
FAILED Loading of signature data failed.
CALIB_ROOM Signature data for second insertion test found.
CALIB_HOT Signature data only for fist insertion test found.

< Factory calibration of BGCCR and BGCRR.

Definition at line 156 of file vadc_usage.c.

References BANDGAP_ADJ_DELAY, CALIB_HOT, CALIB_ROOM, FAILED, READ_SIGNATUREBYTE, SIG_BGCCR_CALIB_25C, SIG_BGCCR_CALIB_HOT, and SIG_BGCRR_CALIB_25C.

Referenced by main().

00157 {
00159     uint8_t bgccr_cal, bgcrr_cal;
00160     int8_t  mode;
00161 
00162     bgcrr_cal = READ_SIGNATUREBYTE(SIG_BGCRR_CALIB_25C);
00163 
00164 #ifdef IGNORE_2ND_CAL
00165     // To do second point calibration on parts that already have.
00166     bgcrr_cal = 0xFF;
00167 #endif
00168 
00169     /* Please note that breaking within 2 cycles of completing a signature byte
00170      * reading will corrupt further AVR Studio flash readout until a reset is issued.
00171      */
00172     if ( bgcrr_cal != 0xFF ){
00173         // Check to see if part was calibrated at room temperature.
00174         bgccr_cal = 0x3F & READ_SIGNATUREBYTE(SIG_BGCCR_CALIB_25C);
00175         mode = CALIB_ROOM;
00176     } else {
00177         bgcrr_cal = 0x0F;
00178         bgccr_cal = 0x3F & READ_SIGNATUREBYTE(SIG_BGCCR_CALIB_HOT);
00179 
00180         if (bgccr_cal == 0x3F) {
00181             return FAILED;
00182         }
00183 
00184         mode = CALIB_HOT;
00185     }
00186 
00187     BGCRR = bgcrr_cal;
00188 
00189     // If done this way device may enter BOD so use method below.
00190     // BGCCR = bgccr_cal;
00191 
00192     while (BGCCR < bgccr_cal){
00193         // Adjust BGCCR up if needed. Slowly to avoid BOD.
00194         BGCCR++;
00195         __delay_cycles(BANDGAP_ADJ_DELAY);
00196     }
00197 
00198     // Adjust down if necessary. (Safe - but results in wrong ADC measurements until VREF is stabilized)
00199     BGCCR = bgccr_cal;
00200 
00201     return mode;
00202 }

void InitCoeff ( void   ) 

Function to load coefficients needed from the signature row.

Loads all signature data into an array and then stores the relevant ones in (file) global variables.

Definition at line 91 of file vadc_usage.c.

References cell_gain, cell_offset, READ_SIGNATUREBYTE, SIG_END_ADDRESS, SIG_VADC_ADC0_GAIN_H, SIG_VADC_ADC0_GAIN_L, SIG_VADC_ADC0_OFFSET, SIG_VADC_ADC1_GAIN_H, SIG_VADC_ADC1_GAIN_L, SIG_VADC_ADC1_OFFSET, SIG_VADC_CELL1_GAIN_H, SIG_VADC_CELL1_GAIN_L, SIG_VADC_CELL1_OFFSET, SIG_VADC_CELL2_GAIN_H, SIG_VADC_CELL2_GAIN_L, SIG_VADC_CELL2_OFFSET, SIG_VADC_RAW_ADC0_H, SIG_VADC_RAW_ADC0_L, SIG_VADC_RAW_CELL1_H, SIG_VADC_RAW_CELL1_L, SIG_VPTAT_H, SIG_VPTAT_L, vadc_gain, vadc_offset, and vptat_coeff.

Referenced by main().

00092 {
00093     uint8_t signature_array[SIG_END_ADDRESS+1];
00094 
00095     for(uint8_t i=0 ; i <= SIG_END_ADDRESS ; i++){
00096         signature_array[i] = READ_SIGNATUREBYTE(i);
00097     }
00098 
00099     /* Please note that breaking within 2 cycles of completing a signature byte
00100      * reading will corrupt further AVR Studio flash readout until a reset is issued.
00101      */
00102 
00103     // Coefficient for temperature calculation from internal sensor.
00104     vptat_coeff = signature_array[SIG_VPTAT_L];
00105     vptat_coeff |= signature_array[SIG_VPTAT_H] << 8;
00106 
00107     // Coefficients for cell gain and offset.
00108     cell_gain[0] = signature_array[SIG_VADC_CELL1_GAIN_L];
00109     cell_gain[0] |= signature_array[SIG_VADC_CELL1_GAIN_H] << 8;
00110     cell_offset[0] = signature_array[SIG_VADC_CELL1_OFFSET];
00111 
00112     cell_gain[1] = signature_array[SIG_VADC_CELL2_GAIN_L];
00113     cell_gain[1] |= signature_array[SIG_VADC_CELL2_GAIN_H] << 8;
00114     cell_offset[1] = signature_array[SIG_VADC_CELL2_OFFSET];
00115 
00116     // Coefficients for VADC gain and offset.
00117     vadc_gain[0] = signature_array[SIG_VADC_ADC0_GAIN_L];
00118     vadc_gain[0] |= signature_array[SIG_VADC_ADC0_GAIN_H] << 8;
00119     vadc_offset[0] = signature_array[SIG_VADC_ADC0_OFFSET];
00120 
00121     vadc_gain[1] = signature_array[SIG_VADC_ADC1_GAIN_L];
00122     vadc_gain[1] |= signature_array[SIG_VADC_ADC1_GAIN_H] << 8;
00123     vadc_offset[1] = signature_array[SIG_VADC_ADC1_OFFSET];
00124 
00125 // Only load raw calibration values if needed.
00126 #ifndef USE_CAL_GAIN
00127 
00128 // Using Cell1 for calibration.
00129 #ifdef USE_CELL1_CAL
00130     // RAW Cell1 measurements for 4096mV in.
00131     raw_cal = signature_array[SIG_VADC_RAW_CELL1_L];
00132     raw_cal |= signature_array[SIG_VADC_RAW_CELL1_H] << 8;
00133 
00134 // Using VADC0 for calibration.
00135 #else
00136     // RAW VADC0 measurements with (4096/5)mV in.
00137     raw_cal = signature_array[SIG_VADC_RAW_ADC0_L];
00138     raw_cal |= signature_array[SIG_VADC_RAW_ADC0_H] << 8;
00139 #endif
00140 
00141 #endif
00142 
00143 }

int16_t MeasureVADCerror ( void   ) 

Measure VADC error.

Subroutine for measurement of VADC input and calculation of error. Uses defines from calibration.h.

Returns:
VADC_error

Definition at line 444 of file vadc_usage.c.

References CAL_GAIN, CAL_OFFSET, VADC_SCALE_BITS, and VCALIB_VALUE.

Referenced by CalibrateVREF().

00445 {
00446     // Variable to keep error after conversion.
00447     int32_t vadc_error;
00448 
00449     // Start a VADC conversion and clear any pending interrupts
00450     VADCSR |= (1 << VADSC) | (1 << VADCCIF);
00451 
00452     // Wait while conversion in progress
00453     do {} while(!(VADCSR & (1 << VADCCIF)));
00454 
00455     // Calculate error of VADC measurement.
00456     vadc_error = VADC;
00457 
00458 #ifdef USE_CAL_GAIN
00459     vadc_error -= CAL_OFFSET;
00460     vadc_error *= CAL_GAIN;
00461 
00462     // Divide by 16384.
00463     vadc_error >>= VADC_SCALE_BITS;
00464 #endif
00465 
00466     vadc_error -= VCALIB_VALUE;
00467     return (int16_t) vadc_error;
00468 }

void StartVADCScan ( void   ) 

Start a scan of all VADC channels.

VADC is set up and interrupts enabled. Global interrupts are also enabled, so make sure all other interrupts are correctly configured before running this. The interrupt routine VADC_ISR does the actual vadc measurements.

Note:
If not using ADC0-1 exclusively as analog inputs, you must modify the disabling of the ADC0-1 digital input buffer.

Definition at line 215 of file vadc_usage.c.

References FIRST_VADC_MEAS, and vadc_scan_complete.

Referenced by main().

00216 {
00217     //disable ADC0-1 digital input buffer.
00218     DIDR0 = 0x03;
00219     vadc_scan_complete = 0;
00220 
00221     // Start set up for first channel.
00222     VADMUX = FIRST_VADC_MEAS;
00223 
00224     // Clear any pending interrupt
00225     VADCSR = (1<<VADEN) | (1<<VADCCIF);
00226 
00227     //Start the first conversion & enable interrupts
00228     VADCSR = (1<<VADEN) | (1<<VADSC) | (1<<VADCCIE);
00229 
00230     // Make sure interrupt are enabled.
00231     __enable_interrupt();
00232 }


Variable Documentation

uint16_t bg_temp

Global variable for the result of band-gap temperature measurement/calculation.

Definition at line 79 of file vadc_usage.c.

Referenced by CalculateADCResults().

uint16_t cell_v[NO_CELLS]

Global variable for results of Cell Voltage measurements/calculations.

Definition at line 77 of file vadc_usage.c.

Referenced by CalculateADCResults().

Flag for signalling VADC sampling complete.

Definition at line 80 of file vadc_usage.c.

Referenced by main(), StartVADCScan(), and VADC_ISR().

uint16_t vadc_v[NO_VADC]

Global variable for results of Voltage ADC measurements/calculations.

Definition at line 78 of file vadc_usage.c.

Referenced by CalculateADCResults().


Generated on Wed Nov 5 08:17:26 2008 for AVR353: Voltage Reference Calibration and Voltage ADC Usage by  doxygen 1.5.5