From e16d7ae476d45fddbfa9cf5f271399be7533e684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Mon, 4 Apr 2016 10:52:31 +0200 Subject: [PATCH] use ADC regular group for convertion --- main.c | 61 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/main.c b/main.c index 759b78d..a9bc986 100644 --- a/main.c +++ b/main.c @@ -73,13 +73,20 @@ const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND; /** @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 */ /** @} */ +/** @defgroup photoresistor_adc ADC used to ambient luminosity + * @{ + */ +#define PHOTORESISTOR_ADC_CHANNEL ADC_CHANNEL0 /**< ADC channel */ +#define PHOTORESISTOR_PORT GPIOA /**< port on which the battery is connected */ +#define PHOTORESISTOR_PORT_RCC RCC_GPIOA /**< timer port peripheral clock */ +#define PHOTORESISTOR_PIN GPIO0 /**< 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}; @@ -372,38 +379,38 @@ int main(void) clock_leds_set(); // set the colors of all LEDs ws2812b_transmit(); // transmit set color - // 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 + // setup ADC to read battery voltage + rcc_periph_clock_enable(BATTERY_PORT_RCC); // enable clock for battery GPIO peripheral + gpio_set_mode(BATTERY_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, BATTERY_PIN); // set battery GPIO as analogue input for the ADC + rcc_periph_clock_enable(PHOTORESISTOR_PORT_RCC); // enable clock for photo-resistor GPIO peripheral + gpio_set_mode(PHOTORESISTOR_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, PHOTORESISTOR_PIN); // set photo-resistor GPIO as analogue input for the ADC + rcc_periph_clock_enable(RCC_ADC1); // enable clock for ADC peripheral + adc_off(ADC1); // 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 + adc_set_single_conversion_mode(ADC1); // we just want one measurement + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); // use 28.5 cycles to sample (long enough to be stable) + adc_enable_temperature_sensor(ADC1); // enable internal voltage reference + adc_enable_discontinuous_mode_regular(ADC1, 1); // do only one conversion per sequence + adc_enable_external_trigger_regular(ADC1, ADC_CR2_EXTSEL_SWSTART); // use software trigger to start conversion + adc_power_on(ADC1); // 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 + adc_reset_calibration(ADC1); // remove previous non-calibration + adc_calibration(ADC1); // 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 - // 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 + // read internal reference 1.2V and RTC battery voltages + uint8_t channels[] = {ADC_CHANNEL17, BATTERY_ADC_CHANNEL}; // voltages to convert + adc_set_regular_sequence(ADC1, LENGTH(channels), channels); // set channels to convert + adc_start_conversion_regular(ADC1); // start conversion to get first voltage of this group + while (!adc_eoc(ADC1)); // wait until conversion finished + uint16_t ref_value = adc_read_regular(ADC1); // read internal reference 1.2V voltage value + adc_start_conversion_regular(ADC1); // start conversion to get second voltage of this group + while (!adc_eoc(ADC1)); // wait until conversion finished + uint16_t battery_value = adc_read_regular(ADC1); // read converted battery voltage float battery_voltage = battery_value*1.2/ref_value; // calculate battery voltage if (battery_voltage<2.4) { printf("/!\\ low "); @@ -411,7 +418,7 @@ int main(void) printf("battery voltage: %.2fV\n", battery_voltage); // get date and time - printf("%02lu:%02lu:%02lu\n", rtc_get_counter_val()/ticks_hour, (rtc_get_counter_val()%ticks_hour)/ticks_minute, (rtc_get_counter_val()%ticks_minute)/ticks_second); // display time + printf("current time: %02lu:%02lu:%02lu\n", rtc_get_counter_val()/ticks_hour, (rtc_get_counter_val()%ticks_hour)/ticks_minute, (rtc_get_counter_val()%ticks_minute)/ticks_second); // display time clock_animate_time(rtc_get_counter_val()); // set time with animation printf("input commands\n");