Forum: Mikrocontroller und Digitale Elektronik STM32 F051 ADC Abtastrate


von public (Gast)


Lesenswert?

Hallo zusammen,

ich habe folgendes Setup:

1. Timer2 triggered ADC, gleichzeitig lasse ich mir dessen Takt 
ausgeben. Hier der Code
1
  int iTIMPeriod = 48;
2
3
/* Time base configuration */
4
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
5
  TIM_TimeBaseStructure.TIM_Prescaler               = 0;
6
  TIM_TimeBaseStructure.TIM_Period                  = iTIMPeriod;
7
  TIM_TimeBaseStructure.TIM_ClockDivision           = 0;
8
  TIM_TimeBaseStructure.TIM_CounterMode             = TIM_CounterMode_Up;
9
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
10
  
11
  //TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
12
  
13
  TIM_OCStructInit(&TIM_OCInitStructure);
14
  TIM_OCInitStructure.TIM_OCMode                    = TIM_OCMode_Toggle; 
15
  TIM_OCInitStructure.TIM_OutputState               = TIM_OutputState_Enable;                
16
  TIM_OCInitStructure.TIM_Pulse                     = iTIMPeriod; 
17
  TIM_OCInitStructure.TIM_OCPolarity                = TIM_OCPolarity_High;
18
  TIM_OC2Init(TIM2, &TIM_OCInitStructure);
19
  
20
21
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC2Ref);   /* Send the OC2REF signal to the TRGO output */
22
23
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
24
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

2. Der ADC (14MHz HSI) triggered den DMA im Circular Mode, auch hier der 
Code
1
ADC_InitStruct.ADC_Resolution             = ADC_Resolution_12b;
2
ADC_InitStruct.ADC_ContinuousConvMode     = DISABLE;
3
ADC_InitStruct.ADC_ExternalTrigConvEdge   = ADC_ExternalTrigConvEdge_RisingFalling;
4
ADC_InitStruct.ADC_ExternalTrigConv       = ADC_ExternalTrigConv_T2_TRGO;
5
ADC_InitStruct.ADC_DataAlign              = ADC_DataAlign_Right;
6
  
7
ADC_Init(ADC1, &ADC_InitStruct);
8
  
9
ADC_ChannelConfig(ADC1, ADC_Channel_6, ADC_SampleTime_1_5Cycles);
10
  
11
ADC_OverrunModeCmd(ADC1, ENABLE);  
12
ADC_DMACmd(ADC1, ENABLE);  
13
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
14
15
//ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
16
  
17
ADC_Cmd(ADC1, ENABLE);                                          
18
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

3. Der DMA speichert 32 Werte und stoppt dann im Interrupt den Timer2
1
  DMA_InitStruct.DMA_PeripheralBaseAddr   = DMA_ADC1_PERIPHERAL_ADRESS;                  /* destination peripheral adress: ADC  */
2
  DMA_InitStruct.DMA_MemoryBaseAddr       = Sensor_GetADC1MemoryAdress();              /* source memory adress  */
3
  DMA_InitStruct.DMA_DIR                  = DMA_DIR_PeripheralSRC;                      /* direction source -> destination */  
4
  DMA_InitStruct.DMA_BufferSize           = Sensor_DMA_ADC1_MEMORY_BUFFERSIZE;          /* amount of samples */  
5
  DMA_InitStruct.DMA_PeripheralInc        = DMA_PeripheralInc_Disable;                  /* increment peripheral adress yes/no? */  
6
  DMA_InitStruct.DMA_MemoryInc            = DMA_MemoryInc_Enable;                        /* increment memory adress yes/no? */  
7
  DMA_InitStruct.DMA_PeripheralDataSize   = DMA_PeripheralDataSize_HalfWord;            /* data size to transfer to peripheral */  
8
  DMA_InitStruct.DMA_MemoryDataSize       = DMA_MemoryDataSize_HalfWord;                /* data size to transfer from memory */  
9
  DMA_InitStruct.DMA_Mode                 = DMA_Mode_Circular;                          /* normal (one shot) or circular */  
10
  DMA_InitStruct.DMA_Priority             = DMA_Priority_High;                          /* priority: very high, high, normal, low */  
11
  DMA_InitStruct.DMA_M2M                  = DMA_M2M_Disable;                            /* data transfer from memory to memory? */
12
  
13
  DMA_Init(DMA1_Channel1, &DMA_InitStruct);                                              /* DMA1_Channel1 + DMA1_Channel2 belong to ADC1 */
14
  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1 | DMA1_IT_HT1 , ENABLE);  //| DMA1_IT_TE1| DMA1_IT_HT1
15
  
16
  DMA_Cmd(DMA1_Channel1, ENABLE);

Jetzt meine Probleme. So wie ich die Konfiguration Timer, ADC, DMA 
gemacht habe funktioniert alles, bis auf die Samplezeit des ADC.

Laut Datenblatt müssten maximal 1MHz (1000ns, siehe Referenz Manual 
S.188) drin sein.

Wie oben ersichtlich Lade ich das Auto-Reload-Register auf 48, bei einem 
Takt von 48MHz ergibt das 500kHz (Toggle-Mode, abstand 2er positiver 
Flanken also 2x 48).

Da ich den ADC auf rising + falling edge eingestellt habe, müsste ich 
doch vielleicht mit etwas Jitter nahe an die 1000ns für den ADC kommen. 
Zum füllen des Buffers benötige ich aber die doppelte Zeit und kann 
diese auch nicht durch Verkleinerung der Auflöung verbessern.

Kann mir jemand helfen, oder wurde der Fehler gar schon entdeckt?

Besten Gruß
public

von public (Gast)


Lesenswert?

Hey kann mir wirklich keiner Helfen?

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

schau dir mal an auf welchem clock der adc/timer rennt.. hab das grad 
nicht im kopf wie das beim f0 ist... hatte schonmal das vergnügen mit 
einem timer wo nix stimmte weil die source-clock nicht die war die ich 
dachte ;)

73

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.