Skip to main content
Visitor II
September 22, 2024
Solved

STM32f407 Triple regular simultaneously mode only: no output in ADC_CDR register

  • September 22, 2024
  • 8 replies
  • 3333 views

I'm trying to acquire data from 3 sensor simultaneously using Triple Mode. Im using TIM 2 TRGO as a trigger for starting ADC. my data are getting correctly generated in the respective DR registers of ADCs but not in Common register ADC->CDR where it is supposed to have the data

 

void adc_init(void){

// Enable clock

RCC -> AHB1ENR |= (1U << 0); //Clock For GPIOA

RCC -> AHB1ENR |= (1U << 22); //Clock for DMA2

RCC -> APB2ENR |= (1U << 8); //Clock for ADC1

RCC -> APB2ENR |= (1U << 9); //Clock for ADC2

RCC -> APB2ENR |= (1U << 10); //Clock for ADC3

//Config GPIO

GPIOA -> MODER |= (1U << 2) | (1U <<3); //Analog mode PA1

GPIOA -> MODER |= (1U << 4) | (1U <<5); //Analog mode PA2

GPIOA -> MODER |= (1U << 6) | (1U << 7); //Analog mode PA3

//Triple Mode ADC1, ADC2, ADC3

ADC->CCR |= (0x0016); // Triple Regular Simultaneous Mode

//ADC1 Config

//Select channel

ADC1 -> SQR3 &= ~( (1U << 1) | (1U << 2) | (1U << 3) | (1U << 4));

ADC1 -> SQR3 |= (1U << 0);

ADC1->SMPR2 |= (1U << 0);

ADC1 -> CR2 |= (1U << 28); //Enable External trigger

ADC1 -> CR2 &= ~(1U << 29);

ADC1 -> CR2 |= ( 1U << 28 ); // Enable external trigger on rising edge for ADC1

ADC1 -> CR2 |= ( 1U << 29 );


ADC1 -> CR2 &= ~(1U << 24); // Select TIM2 TRGO event for external trigger

ADC1 -> CR2 |= (1U << 25);

ADC1 -> CR2 |= (1U << 26);

ADC1 -> CR2 &= ~(1U << 27);

ADC1 -> CR2 |= (1U << 0);


// ADC1 -> CR2 |= (1U << | (1U << 9); // Select to use DMA


//ADC2 Config

//Select channel

ADC2 -> SQR3 &= ~( (1U << 0) | (1U << 2) | (1U << 3) | (1U << 4));

ADC2 -> SQR3 |= (1U << 1);

ADC2->SMPR2 |= (1U << 0);

ADC2 -> CR2 |= (1U << 0);



//ADC3 Config

ADC3 -> SQR3 &= ~( (1U << 2) | (1U << 3) | (1U << 4));

ADC3 -> SQR3 |= (1U << 0) | (1U << 1);

ADC2->SMPR2 |= (1U << 0);

ADC3 -> CR2 |= (1U << 0);



/* CONFIG TIMER FOR TRIGGER */

RCC -> APB1ENR |= ( 1U << 0); // Enable clock for TIM2

TIM2 -> PSC = (8400 - 1); // Set prescaler for 10000Hz timer frequency

TIM2 -> ARR = (1000-1); // Set auto reload value

TIM2 -> CR2 &= ~(( 1U << 4) | ( 1U << 6)); // Select update event for TRGO
TIM2 -> CR2 |= ( 1U << 5);

}

void adc_start(void){

TIM2 -> CR1 |= ( 1U << 0); // Enable TIM2

}

 

 

    This topic has been closed for replies.
    Best answer by vis11

    This code is working as expected for DMA mode1, where the data are transferred to a adc_data[3], adc_data[0] = ADC1 value and so on. it is also working for higher sampling frequency 1 or 2 KHz. Also working when using other DMA mode

    @waclawek.janthank you for your insights and help

     

     

     

    /*
     * adc.c
     *
     * Created on: Sep 21, 2024
     * Author: Vishnu
     */
    
    #include <adc.h>
    
    volatile uint32_t adc_data[3];
    volatile uint16_t dma2_status;
    
    
    void adc_init(void){
    
    	/* Enable Clock */
    	RCC -> AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    	RCC -> AHB1ENR |= RCC_AHB1ENR_DMA2EN;
    	RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC1EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC3EN;
    
    	/* Set PA1, PA2, PA3, as Analog port */
    	GPIOA -> MODER |= (GPIO_MODER_MODER1_0) | (GPIO_MODER_MODER1_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER2_0) | (GPIO_MODER_MODER2_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER3_0) | (GPIO_MODER_MODER3_1);
    
    	/* Configure ADC */
    	//ADC1
    	ADC1 -> SQR3 |= (0X01); // Select Ch 1
    	ADC1 -> CR2 |= (ADC_CR2_EXTEN_1); // Enable External trigger
    	ADC1 -> CR2 &= ~(ADC_CR2_EXTEN_0);
    	ADC1 -> CR2 &= ~( (ADC_CR2_EXTSEL_0) | (ADC_CR2_EXTSEL_3)); // Select TIM2 TRGO event
    	ADC1 -> CR2 |= (ADC_CR2_EXTSEL_1) | (ADC_CR2_EXTSEL_2);
    	ADC1 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC2
    	ADC2 -> SQR3 |= (0X02); // Select Ch 2
    	ADC2 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC3
    	ADC3 -> SQR3 |= (0X03); // Select Ch 3
    	ADC3 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    
    
    	/* Config DMA2 */
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_EN); //Disable DMA
    	while(( (DMA2_Stream0 -> CR) & (DMA_SxCR_EN) )){} // Wait till stream is disable
    
    	//Select Ch0
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_CHSEL_0) | (DMA_SxCR_CHSEL_1) | (DMA_SxCR_CHSEL_2) );
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PL_0) | (DMA_SxCR_PL_1); // Set very high Priority level
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_MSIZE_0); //Set MSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_MSIZE_1);
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_PSIZE_0); //Set PSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PSIZE_1);
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_MINC); //Enable Memory Inc
    	DMA2_Stream0 -> CR |= (DMA_SxCR_CIRC); //Enable circular mode
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_DIR_0) | (DMA_SxCR_DIR_1)); //Set transfer direction
    	DMA2_Stream0 -> NDTR = 3; //Set no.of data register
    	DMA2_Stream0 -> PAR = (uint32_t) (&(ADC -> CDR)); //Set Peri Address
    	DMA2_Stream0 -> M0AR = (uint32_t) (&adc_data); //Set Mem Address
    
    	// Enable DMA transfer complete interrupt
    	DMA2_Stream0 -> CR |= DMA_SxCR_TCIE; // Enable transfer complete interrupt
    	// Enable DMA interrupt in NVIC
    	NVIC_EnableIRQ(DMA2_Stream0_IRQn);
    
    	/* CONFIG TIMER FOR TRIGGER */
    
    	TIM2 -> PSC = (8400 - 1); // Set prescaler for 10000Hz timer frequency
    	TIM2 -> ARR = (100-1); // Set auto reload value
    
    	TIM2 -> CR2 &= ~((TIM_CR2_MMS_0) | (TIM_CR2_MMS_2)); // Select update event for TRGO
    	TIM2 -> CR2 |= (TIM_CR2_MMS_1);
    
    	/* Triple ADC mode */
    	ADC -> CCR |= (ADC_CCR_DDS); //Set Contin DMA Request
    	ADC -> CCR |= (ADC_CCR_DMA_0); //Set DMA Mode
    	ADC -> CCR |= (0x0016); // Enable Dual Mode
    
    
    }
    
    
    void adc_start(void){
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_EN); // Enable DMA
    	TIM2 -> CR1 |= ( TIM_CR1_CEN); // Enable TIM2
    
    }
    
    // Interrupt Service Routine for DMA2 Stream 0
    void DMA2_Stream0_IRQHandler(void) {
     // Check for DMA transfer complete interrupt flag
     if(DMA2->LISR & DMA_LISR_TCIF0) {
     // Clear the interrupt flag
     DMA2->LIFCR |= DMA_LIFCR_CTCIF0;
    
     dma2_status = 1;
    
    
     }
    }

     

     

    8 replies

    Super User
    September 22, 2024

    How do you know? You don't read DR or CDR anywhere in the code shown.

    By "not output" do you mean that it reads as 0?

    vis11Author
    Visitor II
    September 22, 2024

    This is just configuration I've done for Adc. I tracked the status of CDR register through debugging. It always stays 0. The CCR has the valu 0x016 has CSR updates according to ADC status. The Data are available in the ADCx DR registers but not in CDR

    Super User
    September 22, 2024

    Maybe it's not obvious from the description of that register, but ADC_CDR is intended to be read out by DMA, thus it is not "populated" until you set ADC_CCR.DMA to other than 0b00. 

    For Triple Regular simultaneous mode only, you are supposed to set it to 0b01, according to the narrative, and then use DMA accordingly; although it appears to work somehow also with 0b10 and also when polling fast enough (if you know which flag(s) to poll).

    As with "single" ADC usage, you have to pick the data timely, otherwise it will overflow and stop converting.

    JW

     

    vis11Author
    Visitor II
    September 23, 2024

    Which ADC's DMA controller should i use. If i use ADC1 DMA stream can i use it fetch data from ADC_CDR. Also do i have to enable all the ADCs for DMA transfer

    Super User
    September 23, 2024

    0. When posting code, use the "</>" icon at top of the editor

    1. Enable DMA clock

    RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;

    2. Make sure the adc_data[] array is not located in the CCMRAM (ie. it's in RAM, above 0x2000'0000)

    3. Make sure DMA2_Stream0 -> NDTR is set to the size of adc_data array (and don't OR into this register, write to it directly )

    4. Uncomment setting of memory increment, DMAx_Streamx_CR.MEMC bit:

    DMA2_Stream0 -> CR |= (DMA_SxCR_MINC); //Enable Mem Inc

    5. Comment out/remove enabling DMA individually in ADC1_CR2 and ADC2_CR2.

    JW

    Technical Moderator
    September 23, 2024

    Hello @vis11 and welcome to the community,

    First, use </> button to paste your code. Read the following tips on how to post a thread in this community.

    Second, please don't duplicate threads for the same subject.

    Thank you for your understanding.

    vis11Author
    Visitor II
    September 23, 2024

    my apologies for the mistakes as its my first time here and i was not familiar with the rules

     

    vis11Author
    Visitor II
    September 23, 2024

    now when i use the DAM Mode 1 in ADC_CCR register, the ADC_CDR is only getting the ADC3 values but if i use DMA Mode 2 ALL values are generating by pairs on ADC_CDR register. I've tried to debug but can't seems to find the problems. The code is given below:

    /*
     * adc.c
     *
     * Created on: Sep 21, 2024
     * Author: Vishnu
     */
    
    #include <adc.h>
    
    volatile uint32_t adc_data;
    volatile uint16_t dma2_status;
    
    
    void adc_init(void){
    
    	//Enable Clock
    	RCC -> AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    	RCC -> AHB1ENR |= RCC_AHB1ENR_DMA2EN;
    	RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC1EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC3EN;
    
    	//Set PA1, PA2, PA3, as Analog port
    	GPIOA -> MODER |= (GPIO_MODER_MODER1_0) | (GPIO_MODER_MODER1_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER2_0) | (GPIO_MODER_MODER2_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER3_0) | (GPIO_MODER_MODER3_1);
    
    	// Configure ADC
    
    	//ADC1
    	ADC1 -> SQR3 = (0X01); // Select Ch 1
    	ADC1 -> CR2 |= (ADC_CR2_EXTEN_0); // Enable External trigger
    	ADC1 -> CR2 &= ~(ADC_CR2_EXTEN_1);
    
    	ADC1 -> CR2 &= ~( (ADC_CR2_EXTSEL_0) | (ADC_CR2_EXTSEL_3)); // Select TIM2 TRGO event
    	ADC1 -> CR2 |= (ADC_CR2_EXTSEL_1) | (ADC_CR2_EXTSEL_2);
    
    	ADC1 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC2
    	ADC2 -> SQR3 |= (0X02); // Select Ch 2
    	ADC2 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC3
    	ADC3 -> SQR3 |= (0X03); // Select Ch 3
    	ADC3 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    
    
    	// Config DMA2
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_EN); //Disable DMA
    	while(( (DMA2_Stream0 -> CR) & (DMA_SxCR_EN) )){} // Wait till stream is disable
    	//Select Ch0
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_CHSEL_0) | (DMA_SxCR_CHSEL_1) | (DMA_SxCR_CHSEL_2) );
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PL_0) | (DMA_SxCR_PL_1); // Set very high Priority level
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_MSIZE_0); //Set MSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_MSIZE_1);
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_PSIZE_0); //Set PSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PSIZE_1);
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_CIRC); //Enable circular mode
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_DIR_0) | (DMA_SxCR_DIR_1)); //Set transfer direction
    
    	DMA2_Stream0 -> NDTR |= 1; //Set no.of data register
    	DMA2_Stream0 -> PAR = (uint32_t) (&(ADC -> CDR)); //Set Peri Address
    	DMA2_Stream0 -> M0AR = (uint32_t) (&adc_data); //Set Mem Address
    
    	// Enable DMA transfer complete interrupt
    	DMA2_Stream0 -> CR |= DMA_SxCR_TCIE; // Enable transfer complete interrupt
    
    	// Enable DMA interrupt in NVIC
    	NVIC_EnableIRQ(DMA2_Stream0_IRQn);
    
    	/* CONFIG TIMER FOR TRIGGER */
    	TIM2 -> PSC = (8400 - 1); // Set prescaler for 10000Hz timer frequency
    	TIM2 -> ARR = (10000-1); // Set auto reload value
    
    	TIM2 -> CR2 &= ~(( 1U << 4) | ( 1U << 6)); // Select update event for TRGO
    	TIM2 -> CR2 |= ( 1U << 5);
    
    	ADC -> CCR |= (ADC_CCR_DDS); //Set Contin DMA Request
    	ADC -> CCR |= (ADC_CCR_DMA_0); //Set DMA Mode 1
    	ADC -> CCR |= (0x016); // Enable Dual Mode
    
    
    }
    
    
    void adc_start(void){
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_EN); // Enable DMA
    	TIM2 -> CR1 |= ( TIM_CR1_CEN); // Enable TIM2
    
    }
    
    // Interrupt Service Routine for DMA2 Stream 0
    void DMA2_Stream0_IRQHandler(void) {
     // Check for DMA transfer complete interrupt flag
     if(DMA2->LISR & DMA_LISR_TCIF0) {
     // Clear the interrupt flag
     DMA2->LIFCR |= DMA_LIFCR_CTCIF0;
     // Set flag to indicate that the transfer is complete
     dma2_status = 1;
    
     }
    }

     

    Super User
    September 23, 2024

    I don't quite see how would the "common" ADC data register output ADC3 result in Dual Mode (which involves only ADC1 and ADC2).

    Why don't you make the adc_data a relatively large array, for example 300 words - and then set DMA's NDTR to 300, too. That would allow you to observe a longer sequence of data at once.

    JW

    vis11Author
    Visitor II
    September 23, 2024

    Now I've configured for triple mode and one thing i noticed is that if increase the sampling rate using TIM2 trigger the all ADCs stops and OVERRUN bit is getting set.

    I'll try with larger array and update

    thank you

    Super User
    September 23, 2024

    > Still the DMA mode 1 is not working as before.

    What do you observe and how, and how is it different from your expectations?

    > DMA Mode 2 works only when we increase the time of the TIM2 trigger.

    TIM2 triggers once per second with the settings above (PSC=8400-1, ARR=10000-1, assuming 168MHz system clock). I don't believe this prevents DMA mode 2 from working. So again, what do you do exactly, what are the observations and what are the results?

    JW

    vis11Author
    Visitor II
    September 23, 2024

    In DMA mode 1 the the CDR register is only getting values from ADC3 in the 16 bit LSB where as the MSB always stays 0.

    DMA Mode 2:

    For 1Hz trigger it's working as expected but when i increase thee tigger for example like  1KHz or 500Hz the ADCs stops after like 1or2 conversion and OVERRUN Flag sets

    I disabled DDS in ADC_CCR and used a array of 30 for saving data

    In Dual ADC mode for DMA mode 1 is sama as in triple Mode expect instead of ADC 3 data in 16bit LSB its ADC2 data. The DMA mode 2 is working as expected even with higher sampling rate 1 or 2 KHz only in DUAL mode

    vis11AuthorAnswer
    Visitor II
    September 24, 2024

    This code is working as expected for DMA mode1, where the data are transferred to a adc_data[3], adc_data[0] = ADC1 value and so on. it is also working for higher sampling frequency 1 or 2 KHz. Also working when using other DMA mode

    @waclawek.janthank you for your insights and help

     

     

     

    /*
     * adc.c
     *
     * Created on: Sep 21, 2024
     * Author: Vishnu
     */
    
    #include <adc.h>
    
    volatile uint32_t adc_data[3];
    volatile uint16_t dma2_status;
    
    
    void adc_init(void){
    
    	/* Enable Clock */
    	RCC -> AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    	RCC -> AHB1ENR |= RCC_AHB1ENR_DMA2EN;
    	RCC -> APB1ENR |= RCC_APB1ENR_TIM2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC1EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC2EN;
    	RCC -> APB2ENR |= RCC_APB2ENR_ADC3EN;
    
    	/* Set PA1, PA2, PA3, as Analog port */
    	GPIOA -> MODER |= (GPIO_MODER_MODER1_0) | (GPIO_MODER_MODER1_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER2_0) | (GPIO_MODER_MODER2_1);
    	GPIOA -> MODER |= (GPIO_MODER_MODER3_0) | (GPIO_MODER_MODER3_1);
    
    	/* Configure ADC */
    	//ADC1
    	ADC1 -> SQR3 |= (0X01); // Select Ch 1
    	ADC1 -> CR2 |= (ADC_CR2_EXTEN_1); // Enable External trigger
    	ADC1 -> CR2 &= ~(ADC_CR2_EXTEN_0);
    	ADC1 -> CR2 &= ~( (ADC_CR2_EXTSEL_0) | (ADC_CR2_EXTSEL_3)); // Select TIM2 TRGO event
    	ADC1 -> CR2 |= (ADC_CR2_EXTSEL_1) | (ADC_CR2_EXTSEL_2);
    	ADC1 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC2
    	ADC2 -> SQR3 |= (0X02); // Select Ch 2
    	ADC2 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    	//ADC3
    	ADC3 -> SQR3 |= (0X03); // Select Ch 3
    	ADC3 -> CR2 |= (ADC_CR2_ADON); //Enable ADC1
    
    
    
    	/* Config DMA2 */
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_EN); //Disable DMA
    	while(( (DMA2_Stream0 -> CR) & (DMA_SxCR_EN) )){} // Wait till stream is disable
    
    	//Select Ch0
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_CHSEL_0) | (DMA_SxCR_CHSEL_1) | (DMA_SxCR_CHSEL_2) );
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PL_0) | (DMA_SxCR_PL_1); // Set very high Priority level
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_MSIZE_0); //Set MSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_MSIZE_1);
    
    	DMA2_Stream0 -> CR &= ~(DMA_SxCR_PSIZE_0); //Set PSize 32-bit
    	DMA2_Stream0 -> CR |= (DMA_SxCR_PSIZE_1);
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_MINC); //Enable Memory Inc
    	DMA2_Stream0 -> CR |= (DMA_SxCR_CIRC); //Enable circular mode
    	DMA2_Stream0 -> CR &= ~( (DMA_SxCR_DIR_0) | (DMA_SxCR_DIR_1)); //Set transfer direction
    	DMA2_Stream0 -> NDTR = 3; //Set no.of data register
    	DMA2_Stream0 -> PAR = (uint32_t) (&(ADC -> CDR)); //Set Peri Address
    	DMA2_Stream0 -> M0AR = (uint32_t) (&adc_data); //Set Mem Address
    
    	// Enable DMA transfer complete interrupt
    	DMA2_Stream0 -> CR |= DMA_SxCR_TCIE; // Enable transfer complete interrupt
    	// Enable DMA interrupt in NVIC
    	NVIC_EnableIRQ(DMA2_Stream0_IRQn);
    
    	/* CONFIG TIMER FOR TRIGGER */
    
    	TIM2 -> PSC = (8400 - 1); // Set prescaler for 10000Hz timer frequency
    	TIM2 -> ARR = (100-1); // Set auto reload value
    
    	TIM2 -> CR2 &= ~((TIM_CR2_MMS_0) | (TIM_CR2_MMS_2)); // Select update event for TRGO
    	TIM2 -> CR2 |= (TIM_CR2_MMS_1);
    
    	/* Triple ADC mode */
    	ADC -> CCR |= (ADC_CCR_DDS); //Set Contin DMA Request
    	ADC -> CCR |= (ADC_CCR_DMA_0); //Set DMA Mode
    	ADC -> CCR |= (0x0016); // Enable Dual Mode
    
    
    }
    
    
    void adc_start(void){
    
    	DMA2_Stream0 -> CR |= (DMA_SxCR_EN); // Enable DMA
    	TIM2 -> CR1 |= ( TIM_CR1_CEN); // Enable TIM2
    
    }
    
    // Interrupt Service Routine for DMA2 Stream 0
    void DMA2_Stream0_IRQHandler(void) {
     // Check for DMA transfer complete interrupt flag
     if(DMA2->LISR & DMA_LISR_TCIF0) {
     // Clear the interrupt flag
     DMA2->LIFCR |= DMA_LIFCR_CTCIF0;
    
     dma2_status = 1;
    
    
     }
    }