use ADC regular group for convertion

This commit is contained in:
King Kévin 2016-04-04 10:52:31 +02:00
parent f89a9b8ea6
commit e16d7ae476
1 changed files with 34 additions and 27 deletions

61
main.c
View File

@ -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");