int main(void) { uint8_t channel_array[16]; uint16_t temperature = 0; rcc_clock_setup_in_hse_12mhz_out_72mhz(); gpio_setup(); usart_setup(); timer_setup(); adc_setup(); gpio_set(GPIOA, GPIO8); /* LED1 on */ gpio_set(GPIOC, GPIO15); /* LED2 on */ /* Send a message on USART1. */ usart_send_blocking(USART2, 's'); usart_send_blocking(USART2, 't'); usart_send_blocking(USART2, 'm'); usart_send_blocking(USART2, '\r'); usart_send_blocking(USART2, '\n'); /* Select the channel we want to convert. 16=temperature_sensor. */ channel_array[0] = 16; /* Set the injected sequence here, with number of channels */ adc_set_injected_sequence(ADC1, 1, channel_array); /* Continously convert and poll the temperature ADC. */ while (1) { /* * Since the injected sampling is triggered by the timer, it gets * updated automatically, we just need to periodically read out the value. * It would be better to check if the JEOC bit is set, and clear it following * so that you do not read the same value twice, especially for a slower * sampling rate. */ temperature = adc_read_injected(ADC1,1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) /* * That's actually not the real temperature - you have to compute it * as described in the datasheet. */ my_usart_print_int(USART2, temperature); gpio_toggle(GPIOA, GPIO8); /* LED2 on */ } return 0; }
int main(void) { u8 channel_array[16]; rcc_clock_setup_in_hse_12mhz_out_72mhz(); gpio_setup(); usart_setup(); timer_setup(); irq_setup(); adc_setup(); gpio_set(GPIOA, GPIO8); /* LED1 on */ gpio_set(GPIOC, GPIO15); /* LED2 on */ /* Send a message on USART1. */ usart_send_blocking(USART2, 's'); usart_send_blocking(USART2, 't'); usart_send_blocking(USART2, 'm'); usart_send_blocking(USART2, '\r'); usart_send_blocking(USART2, '\n'); /* Select the channel we want to convert. 16=temperature_sensor. */ channel_array[0] = 16; /* Set the injected sequence here, with number of channels */ adc_set_injected_sequence(ADC1, 1, channel_array); /* Continously convert and poll the temperature ADC. */ while (1) { /* * Since sampling is triggered by the timer and copying the value * out of the data register is handled by the interrupt routine, * we just need to print the value and toggle the LED. It may be useful * to buffer the adc values in some cases. */ /* * That's actually not the real temperature - you have to compute it * as described in the datasheet. */ my_usart_print_int(USART2, temperature); gpio_toggle(GPIOA, GPIO8); /* LED2 on */ } return 0; }
static void adc_setup(void) { int i; rcc_periph_clock_enable(RCC_ADC1); /* Make sure the ADC doesn't run during config. */ adc_power_off(ADC1); /* We configure everything for one single timer triggered injected conversion with interrupt generation. */ /* While not needed for a single channel, try out scan mode which does all channels in one sweep and * generates the interrupt/EOC/JEOC flags set at the end of all channels, not each one. */ adc_enable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); /* Generate the ADC1_2_IRQ */ adc_enable_eoc_interrupt_injected(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); /* Select the channels we want to convert. * 16=temperature_sensor, 17=Vrefint, 13=ADC1, 10=ADC2 */ channel_array[0] = 16; channel_array[1] = 17; channel_array[2] = 13; channel_array[3] = 10; adc_set_injected_sequence(ADC1, 4, channel_array); adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop"); adc_reset_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); //added this check adc_calibration(ADC1); while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); //added this check }
/** * Enable selected channels on specified ADC. * Usage: * * adc_init_single(ADC1, 1, 1, 0, 0); * * ... would enable ADC1, enabling channels 1 and 2, * but not 3 and 4. */ static inline void adc_init_single(uint32_t adc, uint8_t chan1, uint8_t chan2, uint8_t chan3, uint8_t chan4) { uint8_t num_channels, rank; uint8_t channels[4]; // Paranoia, must be down for 2+ ADC clock cycles before calibration adc_off(adc); /* enable adc clock */ if (adc == ADC1) { #ifdef USE_AD1 num_channels = NB_ADC1_CHANNELS; ADC1_GPIO_INIT(); #endif } else if (adc == ADC2) { #ifdef USE_AD2 num_channels = NB_ADC2_CHANNELS; ADC2_GPIO_INIT(); #endif } /* Configure ADC */ /* Explicitly setting most registers, reset/default values are correct for most */ /* Set CR1 register. */ /* Clear AWDEN */ adc_disable_analog_watchdog_regular(adc); /* Clear JAWDEN */ adc_disable_analog_watchdog_injected(adc); /* Clear DISCEN */ adc_disable_discontinuous_mode_regular(adc); /* Clear JDISCEN */ adc_disable_discontinuous_mode_injected(adc); /* Clear JAUTO */ adc_disable_automatic_injected_group_conversion(adc); /* Set SCAN */ adc_enable_scan_mode(adc); /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */ adc_enable_eoc_interrupt_injected(adc); /* Clear AWDIE */ adc_disable_awd_interrupt(adc); /* Clear EOCIE */ adc_disable_eoc_interrupt(adc); /* Set CR2 register. */ /* Clear TSVREFE */ adc_disable_temperature_sensor(adc); /* Clear EXTTRIG */ adc_disable_external_trigger_regular(adc); /* Clear ALIGN */ adc_set_right_aligned(adc); /* Clear DMA */ adc_disable_dma(adc); /* Clear CONT */ adc_set_single_conversion_mode(adc); rank = 0; if (chan1) { adc_set_sample_time(adc, adc_channel_map[0], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[0]; rank++; } if (chan2) { adc_set_sample_time(adc, adc_channel_map[1], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[1]; rank++; } if (chan3) { adc_set_sample_time(adc, adc_channel_map[2], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[2]; rank++; } if (chan4) { adc_set_sample_time(adc, adc_channel_map[3], ADC_SMPR1_SMP_41DOT5CYC); channels[rank] = adc_channel_map[3]; } adc_set_injected_sequence(adc, num_channels, channels); #if USE_AD_TIM4 #pragma message "Info: Using TIM4 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO); #elif USE_AD_TIM1 #pragma message "Info: Using TIM1 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO); #else #pragma message "Info: Using default TIM2 for ADC" adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO); #endif /* Enable ADC<X> */ adc_power_on(adc); /* Enable ADC<X> reset calibaration register */ adc_reset_calibration(adc); /* Check the end of ADC<X> reset calibration */ while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0); /* Start ADC<X> calibaration */ adc_calibration(adc); /* Check the end of ADC<X> calibration */ while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0); } // adc_init_single
static inline void adc_init_single(uint32_t adc, uint8_t nb_channels, uint8_t* channel_map) { // Paranoia, must be down for 2+ ADC clock cycles before calibration adc_off(adc); /* Configure ADC */ /* Explicitly setting most registers, reset/default values are correct for most */ /* Set CR1 register. */ /* Clear AWDEN */ adc_disable_analog_watchdog_regular(adc); /* Clear JAWDEN */ adc_disable_analog_watchdog_injected(adc); /* Clear DISCEN */ adc_disable_discontinuous_mode_regular(adc); /* Clear JDISCEN */ adc_disable_discontinuous_mode_injected(adc); /* Clear JAUTO */ adc_disable_automatic_injected_group_conversion(adc); /* Set SCAN */ adc_enable_scan_mode(adc); /* Enable ADC<X> JEOC interrupt (Set JEOCIE) */ adc_enable_eoc_interrupt_injected(adc); /* Clear AWDIE */ adc_disable_awd_interrupt(adc); /* Clear EOCIE */ adc_disable_eoc_interrupt(adc); /* Set CR2 register. */ /* Clear TSVREFE */ #if defined(STM32F1) adc_disable_temperature_sensor(adc); #elif defined(STM32F4) adc_disable_temperature_sensor(); #endif /* Clear EXTTRIG */ adc_disable_external_trigger_regular(adc); /* Clear ALIGN */ adc_set_right_aligned(adc); /* Clear DMA */ adc_disable_dma(adc); /* Clear CONT */ adc_set_single_conversion_mode(adc); //uint8_t x = 0; //for (x = 0; x < nb_channels; x++) { // adc_set_sample_time(adc, channel_map[x], ADC_SAMPLE_TIME); //} adc_set_sample_time_on_all_channels(adc, ADC_SAMPLE_TIME); adc_set_injected_sequence(adc, nb_channels, channel_map); #if USE_AD_TIM4 PRINT_CONFIG_MSG("Info: Using TIM4 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM4_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #elif USE_AD_TIM1 PRINT_CONFIG_MSG("Info: Using TIM1 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM1_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #else PRINT_CONFIG_MSG("Info: Using default TIM2 for ADC") #if defined(STM32F1) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO); #elif defined(STM32F4) adc_enable_external_trigger_injected(adc, ADC_CR2_JEXTSEL_TIM2_TRGO, ADC_CR2_JEXTEN_BOTH_EDGES); #endif #endif /* Enable ADC<X> */ adc_power_on(adc); #if defined(STM32F1) /* Enable ADC<X> reset calibaration register */ adc_reset_calibration(adc); /* Check the end of ADC<X> reset calibration */ while ((ADC_CR2(adc) & ADC_CR2_RSTCAL) != 0); /* Start ADC<X> calibaration */ adc_calibration(adc); /* Check the end of ADC<X> calibration */ while ((ADC_CR2(adc) & ADC_CR2_CAL) != 0); #endif return; } // adc_init_single
void accel_highg_init() { uint8_t channel_array[16]; gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0 | GPIO1 | GPIO2); adc_set_dual_mode(ADC_CR1_DUALMOD_RSM); /* ADC1 + ADC2 dual mode */ adc_set_dual_mode(ADC_CR1_DUALMOD_ISM); adc_enable_external_trigger_injected(ADC1, ADC_CR2_JEXTSEL_TIM1_TRGO); adc_enable_external_trigger_injected(ADC3, ADC_CR2_JEXTSEL_TIM1_TRGO); adc_enable_dma(ADC1); adc_enable_dma(ADC3); adc_power_on(ADC1); adc_power_on(ADC2); adc_power_on(ADC3); adc_stab_sleep(); adc_reset_calibration(ADC1); adc_reset_calibration(ADC2); adc_reset_calibration(ADC3); adc_calibration(ADC1); adc_calibration(ADC2); adc_calibration(ADC3); memset(channel_array, 0, sizeof(channel_array)); channel_array[0] = 10; adc_set_injected_sequence(ADC1, 1, channel_array); channel_array[0] = 11; adc_set_injected_sequence(ADC2, 1, channel_array); channel_array[0] = 12; adc_set_injected_sequence(ADC3, 1, channel_array); timer_reset(TIM1); timer_enable_irq(TIM1, TIM_DIER_UIE); timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); /* 500Hz */ timer_set_prescaler(TIM1, 64); timer_set_period(TIM1, 2250); /* Generate TRGO */ timer_set_master_mode(TIM1, TIM_CR2_MMS_UPDATE); dma_set_peripheral_address(DMA1, DMA_CHANNEL5, (uint32_t) &ADC1_DR); dma_set_read_from_memory(DMA1, DMA_CHANNEL5); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL5); dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_32BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_32BIT); dma_set_priority(DMA1, DMA_CHANNEL5, DMA_CCR_PL_HIGH); dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t) &ADC3_DR); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6); dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_16BIT); dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL5); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL6); }