AnsweredAssumed Answered

ADC /DMA  Problem STM32F100

Question asked by M G on Sep 18, 2017
Latest reply on Sep 26, 2017 by M G

ADC1 converts  every 500us 5 analog channels ( ADC10/11/12/13/14) and write the result via DMA1 to internal SRAM  (ADResult[5]) in this order [ ADC10,ADC11,ADC12,ADC13,ADC14]. This works fine, but randomly after some houres or days the result order in memory is corrupted to [ADC14,ADC10,ADC11,ADC12,ADC13], shift at one Position  and stay in this wrong order all the time.

 

ADC1 is configured in Scan Mode, not continuous conversion:

 

// ADC Konfiguration (regular group = ADC10/11/12/13/14
  RCC->APB2ENR|=RCC_APB2ENR_ADC1EN;  //enable Clock for ADC1
  ADC1->SQR1=0x00400000;    //5 Kanäle
  ADC1->SMPR1=0x00ffffff;    
  ADC1->SMPR2=0x3fffffff;    //Abstastzeit der Kanäle auf 240 Zyklen
  ADC1->SQR3=0x1ee6b16a;    //Abtastreihenfolge festlegen 10/11/12/13/14
  ADC1->CR1=0x00000100;                 //use independant mode, SCAN mode
  ADC1->CR2=0x000e0100;     //use data align right,not continuous conversion
                                              // EXTSEL = SWSTART

 

DMA1 Configuration:

// DMA-Konfiguration für A/D-Wandler
  RCC->AHBENR|=RCC_AHBENR_DMA1EN;  // enable Clock for DMA1
  DMA1_Channel1->CMAR=(u32)ADValue;  // DMA-Zieladresse setzen
  DMA1_Channel1->CPAR=(u32)&(ADC1->DR); // DMA-Quelladresse setzen
  DMA1_Channel1->CNDTR=5;    // transmit 5 words
  DMA1_Channel1->CCR=0x00003580;  // DMA konfig. (0x00000580)
  DMA1_Channel1->CCR|=DMA_CCR1_EN;  // DMA Channel 1 enable

 

The ADC conversion is started in the  TIM2_IRQHandler(), which is called every 500us:

 

 

void TIM2_IRQHandler(void)

{ .......

.........

  TEST_PIN3(1);
   ADC1->SR&=~ADC_SR_EOC;       // Interrupt-Flag clear
   ADC1->CR2  |=  0x00500000;      // start A/D conversion (0x00500000)
   ADC1->CR1|=ADC_CR1_EOCIE;       // EOC-Interrupt enable
   TEST_PIN3(0);

.....

.....

}After the A/D conversion of this 5 Inputs is finished  ADC1_IRQHandler/() is called. Tme between start A/D conversion

and call of ADC1_IRQHandler() is 100us.

 

void ADC1_IRQHandler(void)
{
 .........

  TEST_PIN3(1);
  ADC1->SR&=~ADC_SR_EOC;     // Interrupt-Flag löschen
  ADC1->CR1&=~ADC_CR1_EOCIE;    // EOC-Interrupt sperren
  while(!(DMA1->ISR & 0x02UL));    // Warten auf Ende des DMA-Transfers
  DMA1->IFCR=0x02UL;      // Flag löschen
  //DMA-Transferzähler nachladen
  DMA1_Channel1->CCR&=~(1<<0);    // DMA Channel 1 disable
  DMA1_Channel1->CNDTR=5;     // transmit 5 words
  DMA1_Channel1->CCR|=(1<<0);    // DMA Channel 1 enable

 

........

}

 

Has anyone encountered a same Problem ?

Please help.

Outcomes