User Tools

Site Tools


STM32 F103 ADC, injected and regular

Injected ADC

stm32adc.c
/* Author, Copyright: Oleg Borodin, 2018 */
 
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/dma.h>
 
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <wctype.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
 
void delay(uint32_t n) {
    for (volatile int i = 0; i < n; i++)
        __asm__("nop");
}
 
static void clock_setup(void) {
    rcc_clock_setup_in_hse_8mhz_out_72mhz();
    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_AFIO);
    rcc_periph_clock_enable(RCC_USART1);
    rcc_periph_clock_enable(RCC_DMA1);
    rcc_periph_clock_enable(RCC_ADC1);
}
 
void adc_setup(void) {
 
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
 
    adc_power_off(ADC1);
 
    adc_disable_scan_mode(ADC1);
    adc_set_single_conversion_mode(ADC1);
 
    adc_disable_discontinuous_mode_regular(ADC1);
    adc_enable_discontinuous_mode_injected(ADC1);
 
    adc_enable_external_trigger_injected(ADC1, ADC_CR2_JEXTSEL_JSWSTART);
    adc_set_right_aligned(ADC1);
 
    adc_enable_temperature_sensor();
    adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);
 
    adc_power_on(ADC1);
 
    delay(100);
 
    adc_reset_calibration(ADC1);
    adc_calibrate(ADC1);
 
    uint8_t channel_seq[16];
 
    channel_seq[0] = 0;
    channel_seq[1] = 1;
 
    adc_set_injected_sequence(ADC1, 2, channel_seq);
}
 
int main(void) {
    clock_setup();
    uart_setup();
    delay(80);
 
    adc_setup();
    adc_setup();
 
    while(1) {
        adc_start_conversion_injected(ADC1);
        while (!(adc_eoc_injected(ADC1)));
        ADC_SR(ADC2) &= ~ADC_SR_JEOC;   //clear injected end of conversion
 
        uint16_t j1 = adc_read_injected(ADC1, 1);
        uint16_t j2 = adc_read_injected(ADC1, 2);
 
        printf("ADC %6lu %6lu\r\n", j1, j2);
        delay(80000);
    }
    return 0;
}

Regular ADC with DMA

stm32radc.c
/* Author, Copyright: Oleg Borodin, 2018 */
 
void delay(uint32_t n) {
    for (volatile int i = 0; i < n; i++)
        __asm__("nop");
}
 
static void clock_setup(void) {
    rcc_clock_setup_in_hse_8mhz_out_72mhz();
    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_AFIO);
    rcc_periph_clock_enable(RCC_USART1);
    rcc_periph_clock_enable(RCC_DMA1);
    rcc_periph_clock_enable(RCC_ADC1);
}
 
volatile uint16_t adc_res[2];
 
void adc_setup(void) {
    uint8_t channel_seq[16];
 
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0);
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
 
    adc_power_off(ADC1);
 
    adc_enable_scan_mode(ADC1);
    adc_set_continuous_conversion_mode(ADC1);
    adc_disable_discontinuous_mode_regular(ADC1);
 
    adc_enable_external_trigger_regular(ADC1, ADC_CR2_EXTSEL_SWSTART);
    adc_set_right_aligned(ADC1);
    adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_7DOT5CYC);
 
    adc_power_on(ADC1);
 
    delay(10);
 
    adc_reset_calibration(ADC1);
    adc_calibrate(ADC1);
 
    channel_seq[0] = 0;
    channel_seq[1] = 1;
 
    adc_set_regular_sequence(ADC1, 2, channel_seq);
 
    adc_enable_dma(ADC1);
    delay(100);
    adc_start_conversion_regular(ADC1);
}
 
void dma_setup(void) {
    dma_disable_channel(DMA1, DMA_CHANNEL1);
 
    dma_enable_circular_mode(DMA1, DMA_CHANNEL1);
    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
 
    dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
    dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
 
    dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
    dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &ADC_DR(ADC1));
 
    dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) &adc_res);
    dma_set_number_of_data(DMA1, DMA_CHANNEL1, 2);
 
    dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
    dma_enable_channel(DMA1, DMA_CHANNEL1);
}
 
void dma1_channel1_isr(void) {
    dma_clear_interrupt_flags(DMA1, DMA_CHANNEL1, DMA_IFCR_CGIF1);
}
 
int main(void) {
    clock_setup();
    uart_setup();
    dma_setup();
    adc_setup();
 
    while(1) {
        printf("%6lu %6lu\r\n", adc_res[0], adc_res[1]);
 
        delay(80000);
    }
    return 0;
}

Back to overviewNext PageLast Page