Blue Pill - ADC

Table des matières

TL;DR

Conversion en continu et interruption.

Le matériel

Un potentiomètre (10K dans mon cas). Le projet consiste à faire clignoter la LED de la carte en fonction du potentiomètre.

le principe

Configurer l'ADC en mode CONTinous, générer une interruption à l'issue de la conversion et mettre à jour la valeur du compteur SysTick. Il faut faire attention à ne pas faire clignoter la LED trop vite au risque de ne rien voir (et surtout de provoquer une tempête d'interruption).

Le code

#define ADC_MAX_VALUE         4096  // 2^12
#define SYSTICK_LOAD_MAX  16000000  // 0.625s @24 MHz
#define SYSTICK_LOAD_MIN   1200000  // 0.050s @24 MHz
#define SYSTICK_LOAD_STEP  ((SYSTICK_LOAD_MAX - SYSTICK_LOAD_MIN) / ADC_MAX_VALUE)

uint16_t adc_value = ADC_MAX_VALUE / 2;

int
main (void) {
    clock_hse();                     // 8 MHz
#ifdef USE_PLL
    clock_pll(RCC_CFGR_PLLMULL3, 0); // 24 MHz, ADC 12 MHz
#endif
    SystemCoreClockUpdate();         // Update globale variable SystemCoreClock

    RCC->APB2ENR |= ADC_APB2EN | CFG_APB2EN;

    gpio_pin_init(ONBOARD_LED_GPIO, ONBOARD_LED_PIN, O02_GP_PP);

    adc_init(POTENTIOMETER_ADC, POTENTIOMETER_CR2 | ADC_CR2_CONT); // software start & CONTinous mode
    adc_init_channel(POTENTIOMETER_ADC, POTENTIOMETER_CHANNEL, ADC_239_5);
    POTENTIOMETER_ADC->SQR3 |= POTENTIOMETER_CHANNEL << 0;
    POTENTIOMETER_ADC->CR1  |= ADC_CR1_EOSIE; // End Of Sequence Interrupt Enable
    __disable_irq();
    NVIC_EnableIRQ(ADC1_2_IRQn);
    __enable_irq();

    systick_delay_irq(SystemCoreClock / 2); // 0.5 s @24 MHz
    POTENTIOMETER_ADC->CR2 |= ADC_CR2_ADON;
    POTENTIOMETER_ADC->CR2 |= ADC_CR2_SWSTART;

    return 0;
}

void
ADC1_2_IRQHandler(void) {
    adc_value = (uint16_t)POTENTIOMETER_ADC->DR;
}

void
SysTick_Handler(void) {
    ONBOARD_LED_GPIO->ODR ^= 1 << ONBOARD_LED_PIN; // toggle state
    SysTick->LOAD = SYSTICK_LOAD_MIN + (adc_value * SYSTICK_LOAD_STEP);
}
Comme souvent avec les interruptions on ne trouve pas de boucle infinie (et ça me laisse sur le cul à chaque fois).

Le code complet: https://gitlab.com/dsx/blue-pill/-/tree/master/stm32f103c8t6/04_adc_irq

Consommation

En configuration de base (HSE à 8 MHz, ADC à 4 MHz), j'ai noté une consommation de 8.4 mA, 13.2 mA avec la version haute vitesse (PLL à 24 MHz, ADC à 12 MHz).

A suivre

Conversions multiples et DMA.