Demonstration of Slow RC period calculation, Fast RC calibration and Ultra Low Power RC period measurement. Slow RC is used for calibrating the Fast RC and measuring ULP RC period.
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 main.c.
#include "RC_calib_oscsampleif.h"
#include "ATmega8HVA_16HVA_signature.h"
#include "main.h"

Go to the source code of this file.
Functions | |
| int8_t | InitBandgap (void) |
| Bandgap initialisation. | |
| void | main (void) |
| uint16_t | MeasureTemperature (void) |
| Temperature measurement. | |
| int8_t | ReadButtons (void) |
| Read what/if buttons was pressed. | |
Variables | |
| uint16_t | temp_sensor_coeff |
| < For calculating temperature from VPTAT measurement (internal temperature sensor) | |
| 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.
| FAILED | Loading of signature data failed. | |
| ROOM_TEMPERATURE | Signature data for second insertion test found. | |
| HOT_TEMPERATURE | Signature data only for first insertion test found. |
< Factory calibration of BGCCR and BGCRR.
Definition at line 185 of file main.c.
References BANDGAP_ADJ_DELAY, FAILED, HOT_TEMPERATURE, READ_SIGNATUREBYTE, ROOM_TEMPERATURE, SIG_BGCCR_CALIB_25C, SIG_BGCCR_CALIB_HOT, and SIG_BGCRR_CALIB_25C.
Referenced by main().
00186 { 00188 uint8_t bgccr_cal, bgcrr_cal; 00189 int8_t mode; 00190 00191 bgcrr_cal = READ_SIGNATUREBYTE(SIG_BGCRR_CALIB_25C); 00192 00193 /* Uncomment the following line to do second point calibration. Please notice 00194 * that breaking within 2 cycles of completing a signature byte reading will 00195 * corrupt AVR Studio flash readout. 00196 */ 00197 // bgcrr_cal = 0xFF; 00198 00199 // Check that valid BGCRR data exists in the signature row. 00200 if ( bgcrr_cal != 0xFF ){ 00201 bgccr_cal = 0x3F & READ_SIGNATUREBYTE(SIG_BGCCR_CALIB_25C); 00202 mode = ROOM_TEMPERATURE; 00203 }else{ 00204 // No valid data was found. Load HOT temperature data and abort if that is not valid. 00205 bgcrr_cal = 0x0F; 00206 bgccr_cal = 0x3F & READ_SIGNATUREBYTE(SIG_BGCCR_CALIB_HOT); 00207 00208 if (bgccr_cal == 0x3F) { 00209 return FAILED; 00210 } 00211 00212 mode = HOT_TEMPERATURE; 00213 } 00214 00215 BGCRR = bgcrr_cal; 00216 00217 // If done this way device may enter BOD so use method below. 00218 // BGCCR = bgccr_cal; 00219 00220 // Adjust BGCCR up if needed. Slowly to avoid BOD. 00221 while (BGCCR < bgccr_cal) { 00222 BGCCR++; 00223 __delay_cycles(BANDGAP_ADJ_DELAY); 00224 } 00225 00226 /* Adjust down if necessary. (Safe with regard to BOD, but uses 00227 * longer time to stabilize and thus give correct ADC measurements) 00228 */ 00229 BGCCR = bgccr_cal; 00230 00231 return mode; 00232 }
| void main | ( | void | ) |
< Volatile to avoid compiler warning, since we are only storing it.
Definition at line 63 of file main.c.
References BUTTON_ONE, BUTTON_THREE, BUTTON_TWO, CalculateSlowRCperiod(), CalibrateFastRCruntime(), HOT_TEMPERATURE, InitBandgap(), MeasureTemperature(), MeasureULPRCperiod(), READ_SIGNATUREBYTE, ReadButtons(), ROOM_TEMPERATURE, SIG_VPTAT_H, SIG_VPTAT_L, SUCCESS, TEMP_DIFF_LIMIT, temp_sensor_coeff, and ZERO_C_IN_KELVIN.
00064 { 00065 uint16_t current_temperature, calibration_temperature; 00066 int16_t temp_diff; 00067 uint16_t slow_RC_period; 00068 00070 volatile uint16_t ULP_RC_period; 00071 00072 int8_t button_pressed; 00073 00074 /* Calibrate bandgap reference. This checks if signature row contains 00075 * data from second insertion. No check for failure is implemented. 00076 */ 00077 if (InitBandgap() == ROOM_TEMPERATURE){ 00078 // Fast RC calibrated at room temperature. 00079 calibration_temperature = ZERO_C_IN_KELVIN + ROOM_TEMPERATURE; 00080 }else{ 00081 // Fast RC calibrated at hot temperature. 00082 calibration_temperature = ZERO_C_IN_KELVIN + HOT_TEMPERATURE; 00083 } 00084 00085 // Read temperature sensor coefficient from signature row and store in global variable. 00086 temp_sensor_coeff = READ_SIGNATUREBYTE(SIG_VPTAT_L); 00087 00088 // Avoid writing to SPMCSR register within 6 cycles of previous write. 00089 __delay_cycles(2); 00090 00091 temp_sensor_coeff |= (READ_SIGNATUREBYTE(SIG_VPTAT_H) << 8); 00092 00093 // Output System clock/2 on PINB0 to enable easy debugging. 00094 DDRB |= (1 << DDB0); 00095 MCUCR |= (1 << CKOE); 00096 00097 // Enter eternal loop. 00098 do { 00099 /* In an actual application the temperature measurements would 00100 * be part of the, possibly interrupt driven, VADC measurement 00101 * but here we just manually sample them. 00102 */ 00103 current_temperature = MeasureTemperature(); 00104 temp_diff = current_temperature - calibration_temperature; 00105 button_pressed = ReadButtons(); 00106 00107 // Start calibration if called for, either by temperature difference or button 3 (PB3). 00108 if ( (temp_diff > TEMP_DIFF_LIMIT) || (temp_diff < -TEMP_DIFF_LIMIT) || (button_pressed == BUTTON_THREE) ) { 00109 00110 slow_RC_period = CalculateSlowRCperiod(current_temperature); 00111 ULP_RC_period = MeasureULPRCperiod(slow_RC_period); 00112 00113 /* Here we use the The Slow RC result for ULP RC period measurement and Fast RC calibration. 00114 * In a battery application the Slow RC or ULP RC period would also be used for compensating 00115 * the Coulomb counter ADC results. Please see application note AVR352 for details. 00116 */ 00117 00118 if (CalibrateFastRCruntime(slow_RC_period) == SUCCESS){ 00119 // Save the temperature we calibrated at. 00120 calibration_temperature = current_temperature; 00121 }else{ 00122 // Should flag error here. No action is taken in this application. 00123 } 00124 } 00125 00126 // Adjust FOSCCAL down if button 1 is pressed (PB1), thus decreasing clock frequency. 00127 if (button_pressed == BUTTON_ONE){ 00128 FOSCCAL--; 00129 } 00130 00131 // Adjust FOSCCAL up if button 2 is pressed (PB2), thus increasing clock frequency. 00132 if (button_pressed == BUTTON_TWO){ 00133 FOSCCAL++; 00134 } 00135 00136 } while(1); 00137 }

| uint16_t MeasureTemperature | ( | void | ) |
Temperature measurement.
Returns temperature in Kelvin (uint16_t). Absolute accuracy of the temperature sensor is stated at +/-5 Kelvin in the data sheet.
An alternative could be to use °C with 1 byte signed format, thus giving a range of +127 - -128°C. In an application temperature measurements should be part of the VADC interrupt controlled measurements.
Definition at line 247 of file main.c.
References temp_sensor_coeff, and VTEMP.
Referenced by main().
00248 { 00249 uint32_t temperature; 00250 00251 // VTEMP as input 00252 VADMUX = VTEMP; 00253 00254 temperature = VADC; 00255 00256 // Enable VADC and start conversion 00257 VADCSR = (1 << VADEN) | (1 << VADSC) | (1 << VADCCIF); 00258 00259 do {} while(!(VADCSR & (1 << VADCCIF))); 00260 00261 temperature = VADC; 00262 temperature *= temp_sensor_coeff; 00263 00264 // Disable VADC and reset interrupt flag, interrupting any ongoing conversion 00265 VADCSR = (1 << VADCCIF); 00266 return ((uint16_t)(temperature >> 14)); 00267 }
| int8_t ReadButtons | ( | void | ) |
Read what/if buttons was pressed.
Uses PB1/2/3 as inputs, so they must be configured as inputs (default when device is reset). Waits for button(s) to be released before returning the result.
Definition at line 147 of file main.c.
References BUTTON_MASK, BUTTON_ONE, BUTTON_THREE, BUTTON_TWO, and FAILED.
Referenced by main().
00148 { 00149 uint8_t buttons_pressed; 00150 int8_t return_value; 00151 buttons_pressed = (~PINB & BUTTON_MASK); 00152 00153 do {} while (~PINB & BUTTON_MASK); 00154 00155 switch( buttons_pressed ) { 00156 case (1 << BUTTON_ONE): 00157 return_value = BUTTON_ONE; 00158 break; 00159 case (1 << BUTTON_TWO): 00160 return_value = BUTTON_TWO; 00161 break; 00162 case (1 << BUTTON_THREE): 00163 return_value = BUTTON_THREE; 00164 break; 00165 default : 00166 return_value = FAILED; 00167 break; 00168 } 00169 00170 return return_value; 00171 }
| uint16_t temp_sensor_coeff |
< For calculating temperature from VPTAT measurement (internal temperature sensor)
Definition at line 59 of file main.c.
Referenced by main(), and MeasureTemperature().
1.5.5