logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

STM32F3 - ADC + DMA = próbki z "kosmosu"

mongoł2000 20 Mar 2013 11:23 2628 2
REKLAMA
  • #1 12086271
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Witam,
    skonfigurowałem ADC które wyzwalane jest timerem 2(to działa dobrze). DMA wypełnia bufor 70 próbkami jednak:
    - większość probek jest ok, ale np gdy na wejście podam sinusa...to np co 15(w praktyce jest to losowa próbka) jest bitową reprezentacja jedynek obok siebie
    example: ..2345, 2345, 3f, 2344, 2421...

    Wydaje mi się że wina stoi po stronie ADC, bo jak wyłaczyłem wyzwalanie timerem, i ręcznie uruchamiałem START w rejestrach, to ADC również co jakiś czas podawało te dziwne próbki.

    Później podłączyłem na stałe 3.3V z Discovery do pinu ADC....o dziwo wszystkie wartości były dobre ;/

    Niestety brak mi pomysłów, więc czekam na sugestie.


    Konfiguracja:
    
    void	Config_ADC()
    {
    	ADC_InitTypeDef       ADC_InitStructure;
      ADC_CommonInitTypeDef ADC_CommonInitStructure;
      DMA_InitTypeDef       DMA_InitStructure;
      GPIO_InitTypeDef      GPIO_InitStructure;
    	NVIC_InitTypeDef 			NVIC_InitStructure;
    	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
      /* Enable the ADC1 gloabal Interrupt */
      NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    
    	
    	RCC_AHBPeriphClockCmd( RCC_AHBPeriph_ADC12 , ENABLE);
    	RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1 , ENABLE);
    	
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    	
    	 /* ADC Common Init **********************************************************/
      ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
      ADC_CommonInitStructure.ADC_Clock = ADC_Clock_SynClkModeDiv1;
     ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1 ;
    	ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;
      ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
      ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
    
      /* ADC1 Init ****************************************************************/
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
      ADC_InitStructure.ADC_AutoInjMode = DISABLE;
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
      ADC_InitStructure.ADC_NbrOfRegChannel = 1;
    	ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_3; //TIM2_CC2
    	ADC_InitStructure.ADC_ExternalTrigEventEdge =	ADC_ExternalTrigEventEdge_RisingEdge;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_OverrunMode = DISABLE;
      ADC_Init(ADC1, &ADC_InitStructure);
    
      /* ADC1 regular channel12 configuration *************************************/
      ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_181Cycles5 );
    	//ADC_ExternalTriggerConfig(ADC1, ADC_ExternalTrigConvEvent_3, ADC_ExternalTrigEventEdge_RisingEdge); 
    
    
    	
      /* Enable ADC1 */
      ADC_Cmd(ADC1, ENABLE);
    	ADC_DMAConfig(ADC1,ADC_DMAMode_Circular);
    	ADC_DMACmd(ADC1, ENABLE);
    	ADC_StartConversion(ADC1);
    	
    
    
    }

    DMA:
    
    void Reallocate_Memory()
    {
    	DMA_InitTypeDef           DMA_InitStructure;
    
    	/* Enable DMA1 Channel1 */
      DMA_Cmd(DMA1_Channel1, DISABLE);
    
    
      DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_ADDRESS;
      DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(Global_Buffer);
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
      DMA_InitStructure.DMA_BufferSize = Channel_1.PreTrigger_Memory;
    	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
      DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    	
    
    	
    	DMA_ITConfig(DMA1_Channel1 , 	DMA1_IT_TC1 , ENABLE);
    
      /* Enable DMA1 Channel1 */
      DMA_Cmd(DMA1_Channel1, ENABLE);
    
    } 
  • REKLAMA
  • Pomocny post
    #2 12087239
    Dexter77
    Poziom 28  
    Posty: 889
    Pomógł: 134
    Ocena: 19
    Ostatnio walczyłem z ADC w LPC1769. Miałem podobny problem. Próbki losowo miały dziwne wartości, głównie blisko maksymalnego poziomu, rzadziej minimalnego. Szperając w internecie znalazłem info że nie tylko ja mam takie kłopoty. Jako receptę na te dolegliwości podawano dorzucenie kondensatorów rzędu kilkuset pikofaradów na wejście ADC. I rzeczywiście pomogło. Zero próbek z kosmosu przez 48h testu (wczesniej ok.100 na godzine). Dorzucenie kondensatora ograniczy Ci częstotliwość maksymalną mierzonego sygnału i przesunie lekko fazę ale może warto spróbować jeżeli nie ma to znaczenia w Twoim projekcie.
  • #3 12088528
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Sprawdziłem, nic nie dalo ;/
    Problem wydaje się leżeć po stronie ADC, bo skonfigurowałem przerwanie od spadku wartości na ADC i również reaguje na te złe próbki.
REKLAMA