read battery voltage

This commit is contained in:
King Kévin 2016-04-03 15:39:55 +02:00
parent e50ab14626
commit 352b3664f9
1 changed files with 47 additions and 0 deletions

47
main.c
View File

@ -38,6 +38,7 @@
#include <libopencm3/cm3/nvic.h> // interrupt utilities
#include <libopencm3/stm32/exti.h> // external interrupt utilities
#include <libopencm3/stm32/timer.h> // timer utilities
#include <libopencm3/stm32/adc.h> // ADC utilities
/* own libraries */
#include "global.h" // board definitions
@ -85,6 +86,17 @@ const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND;
#define SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
/** @} */
/** @defgroup battery_adc ADC used to measure battery voltage
* @{
*/
#define BATTERY_ADC ADC1 /**< ADC used to measure battery voltage */
#define BATTERY_ADC_RCC RCC_ADC1 /**< ADC clock peripheral */
#define BATTERY_ADC_CHANNEL ADC_CHANNEL1 /**< ADC channel */
#define BATTERY_PORT GPIOA /**< port on which the battery is connected */
#define BATTERY_PORT_RCC RCC_GPIOA /**< timer port peripheral clock */
#define BATTERY_PIN GPIO1 /**< pin of the port on which the battery is connected */
/** @} */
/** RGB values for the WS2812b clock LEDs */
uint8_t clock_leds[WS2812B_LEDS*3] = {0};
/** current time in tick */
@ -423,6 +435,23 @@ int main(void)
nvic_enable_irq(SQUARE_WAVE_TIMER_IRQ); // allow interrupt for timer
timer_enable_counter(SQUARE_WAVE_TIMER); // enable timer to count ticks
// setup ADC to ready battery voltage (single conversion of a regular channel without interrupt)
rcc_periph_clock_enable(BATTERY_PORT_RCC); // enable clock for GPIO peripheral
gpio_set_mode(BATTERY_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, BATTERY_PIN); // set GPIO as analogue input for the ADC
rcc_periph_clock_enable(BATTERY_ADC_RCC); // enable clock for ADC peripheral
adc_off(BATTERY_ADC); // switch off ADC while configuring it
// configuration is correct per default
adc_set_single_conversion_mode(BATTERY_ADC); // we just want one measurement
adc_set_sample_time(BATTERY_ADC, BATTERY_ADC_CHANNEL, ADC_SMPR_SMP_28DOT5CYC); // use 28.5 cycles to sample (long enough to be stable)
adc_enable_temperature_sensor(BATTERY_ADC); // enable internal voltage reference
adc_set_sample_time(BATTERY_ADC, ADC_CHANNEL17, ADC_SMPR_SMP_28DOT5CYC); // use 28.5 cycles to sample internal voltage reference
adc_power_on(BATTERY_ADC); // switch on ADC
for (uint32_t i = 0; i < 800000; i++) { // wait t_stab for the ADC to stabilize
__asm__("nop");
}
adc_reset_calibration(BATTERY_ADC); // remove previous non-calibration
adc_calibration(BATTERY_ADC); // calibrate ADC for less accuracy errors
printf("welcome to the CuVoodoo LED clock\n"); // print welcome message
led_on(); // switch on LED to indicate setup completed
@ -431,6 +460,24 @@ int main(void)
printf("/!\\ RTC oscillator is disabled\n");
}
// read internal reference 1.2V voltage
uint8_t channels[] = {ADC_CHANNEL17}; // voltages to convert
adc_set_regular_sequence(BATTERY_ADC, LENGTH(channels), channels); // set channels to convert
adc_start_conversion_direct(BATTERY_ADC); // start conversion to get voltages
while (!adc_eoc(BATTERY_ADC)); // wait until conversion finished
uint16_t ref_value = adc_read_regular(BATTERY_ADC); // read internal reference 1.2V voltage value
// check RTC battery voltage
channels[0] = BATTERY_ADC_CHANNEL; // voltage to convert
adc_set_regular_sequence(BATTERY_ADC, LENGTH(channels), channels); // set channels to convert
adc_start_conversion_direct(BATTERY_ADC); // start conversion to get voltages
while (!adc_eoc(BATTERY_ADC)); // wait until conversion finished
uint16_t battery_value = adc_read_regular(BATTERY_ADC); // read converted battery voltage
float battery_voltage = battery_value*1.2/ref_value; // calculate battery voltage
if (battery_voltage<2.4) {
printf("/!\\ low ");
}
printf("battery voltage: %.2fV\n", battery_voltage);
// get date and time
uint16_t* rtc_time = rtc_read_time(); // get RTC time/date
current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // the current time