In this example we use the last exercise with a little changes for example the DMA was configured to manage data of 8 bits. Timer added, to trigger the ADC request. Timer 4 is added to trigger a request for the DMA, was configured to trigger when counter up reach its maximum value every 500ms. To configure the trigger it is necessary to use another handler TIM_MasterConfigTypeDef that allows configure the type of timer event to launch the trigger. ADC was modified to send a request when timer event occurs.

#include "bsp.h"
#include <stdio.h>

extern void initialise_monitor_handles(void);

#define BUFFER1_SIZE 1

uint8_t buffer1[ BUFFER1_SIZE ];
uint8_t conversionComplete;

/* Handler for DMA1 channel 1 */
DMA_HandleTypeDef Dma1HandlerCh1;

/* Handler for ADC1 */
ADC_HandleTypeDef AdcHandler;

/* Handler for ADC1 Channel 0*/
ADC_ChannelConfTypeDef AdcChannelConfig;

/* Timer to execute the DMA whitout CPU intervention */
TIM_HandleTypeDef TimHandle;

/* Handler to configure trigger to activate DMA */
TIM_MasterConfigTypeDef sMasterConfig;

int main( void )
{
    /* Initialize HAL */
    HAL_Init( );

    /* Initialize semihosting */
    initialise_monitor_handles();
    printf("Hello!!!\n");

    /* Enable Clocks for DMA1, ADC, TIM4 */
    __HAL_RCC_DMA1_CLK_ENABLE();
    __HAL_RCC_TIM4_CLK_ENABLE();

    /* Configuration of Timer to generate a trigger each 500ms
       Time = 1 / (Tfrec / Preescaler / Period)
       Time = 1 / (16MHz /    64000   /  1000 ) = 0.5s */
    TimHandle.Instance                  = TIM4;                     /* TIM4 Selected to trigger a signal */
    TimHandle.Init.Period               = 1000;                     /* Selection of period */
    TimHandle.Init.Prescaler            = 8000;                     /* Selection of Prescaler */
    TimHandle.Init.ClockDivision        = TIM_CLOCKDIVISION_DIV1;   /* Divisor of 1 to not modify the frecuency */
    TimHandle.Init.CounterMode          = TIM_COUNTERMODE_UP;       /* Counter up selection */
    TimHandle.Init.RepetitionCounter    = 0x00;                     /* Value of 0 to activate the trigger when count reach the maximum value */
    HAL_TIM_Base_Init( &TimHandle );

    /* Config the timer to set a trigger */
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;                    /* Set a trigger an update event of the timer 4 */
    sMasterConfig.MasterSlaveMode     = TIM_MASTERSLAVEMODE_DISABLE;        /* Master / Slave mode disable */
    HAL_TIMEx_MasterConfigSynchronization( &TimHandle, &sMasterConfig ); 

    /* Configure DMA 1 Channel 1 */
    Dma1HandlerCh1.Instance                 = DMA1_Channel1;         /* DMA1 Channel 1                                     */
    Dma1HandlerCh1.Init.Request             = DMA_REQUEST_ADC1;      /* Peripheral ADC1 request                            */
    Dma1HandlerCh1.Init.Direction           = DMA_PERIPH_TO_MEMORY;  /* Data will be transferred from peripheral to memory */
    Dma1HandlerCh1.Init.PeriphInc           = DMA_PINC_DISABLE;      /* Increment source address is disabled               */
    Dma1HandlerCh1.Init.MemInc              = DMA_MINC_ENABLE;       /* Increment destination address is enabled           */
    Dma1HandlerCh1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;   /* Source data is 8-bit width                         */
    Dma1HandlerCh1.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;   /* Destination data is 8-bit width                    */
    Dma1HandlerCh1.Init.Mode                = DMA_CIRCULAR;          /* After finishing last transfer, go to first element */
    Dma1HandlerCh1.Init.Priority            = DMA_PRIORITY_LOW;      /* This DMA channel request config as low priority    */
    HAL_DMA_Init( &Dma1HandlerCh1 );

    /* Enable DMA interrupts */
    HAL_NVIC_SetPriority( DMA1_Channel1_IRQn, 2, 0 );
    HAL_NVIC_EnableIRQ( DMA1_Channel1_IRQn );

    /* Configure ADC */
    __HAL_LINKDMA( &AdcHandler, DMA_Handle, Dma1HandlerCh1 );                 /* Link DMA Handler to ADC Handler              */
    AdcHandler.Instance                   = ADC1;                             /* Use ADC1 Peripheral                          */
    AdcHandler.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV2;         /* APB clock divided by two                     */
    AdcHandler.Init.Resolution            = ADC_RESOLUTION8b;                 /* 8 bit resolution                             */
    AdcHandler.Init.ScanConvMode          = ADC_SCAN_SEQ_FIXED;               /* Scan ADC channels ordered from 0 to 16       */
    AdcHandler.Init.DataAlign             = ADC_DATAALIGN_RIGHT;              /* Right aligned conversion result              */
    AdcHandler.Init.SamplingTimeCommon1   = ADC_SAMPLETIME_1CYCLE_5;          /* Sampling time of 1.5 clock cycles            */
    AdcHandler.Init.ExternalTrigConv      = ADC_EXTERNALTRIG_T4_TRGO;         /* External trigger of Tim4 selected            */
    AdcHandler.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;  /* Risisng Edge of signal trigger               */
    AdcHandler.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;              /* Flag for single conversion                   */
    AdcHandler.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;         /* Data will be overwriten in case was not read */
    AdcHandler.Init.DMAContinuousRequests = ENABLE;                           /* Unlimited DMA transfers for continuous mode  */
    HAL_ADC_Init( &AdcHandler );

    AdcChannelConfig.Channel      = ADC_CHANNEL_0;                      /* Use ADC Channel 0                             */
    AdcChannelConfig.Rank         = ADC_RANK_CHANNEL_NUMBER;            /* Rank 0 for Ch0, rank 1 for Ch1 ...            */
    AdcChannelConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;          /* Use sampling time common 1 (1.5 clock cycles) */
    HAL_ADC_ConfigChannel( &AdcHandler, &AdcChannelConfig );

    HAL_ADCEx_Calibration_Start( &AdcHandler ); 
    HAL_TIM_Base_Start( &TimHandle );
    
    /* Start DMA1 Channel 1 transfer all elements from Source1 array to destination Buffer1 */
    HAL_ADC_Start_DMA( &AdcHandler, (uint32_t*)buffer1, BUFFER1_SIZE );

    while(1)
    {
        /*we do not need to ask for a flag to indicate if the convertion is done
        we can benefir from the fact the information is already in a variable
        but we need to disable interrupts to avoid reading information when DMA
        is writting in the same memory address*/
        __enable_irq(); 
        printf( "Pot value: %d\r\n", buffer1[ 0u ] );
        __disable_irq(); 
        
    }

    return 0u;
}

/*just like the previous example you can use the callback to notify the
application the moment the convertion is ready (if you like)*/
void HAL_ADC_ConvCpltCallback( ADC_HandleTypeDef *hadc )
{
}

msps.c

void HAL_ADC_MspInit( ADC_HandleTypeDef* hadc )
{
    __GPIOA_CLK_ENABLE();
    __ADC_CLK_ENABLE();
    GPIO_InitTypeDef AnalogInput;

    AnalogInput.Pin = GPIO_PIN_0;
    AnalogInput.Mode = GPIO_MODE_ANALOG;
    AnalogInput.Pull = GPIO_NOPULL;
    HAL_GPIO_Init( GPIOA, &AnalogInput );
}

ints.c

extern DMA_HandleTypeDef Dma1HandlerCh1;

void DMA1_Channel1_IRQHandler(void)
{
    HAL_DMA_IRQHandler( &Dma1HandlerCh1 );
}