STM32 F051 ADC Abtastrate

Gast #3210003
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
(Firma: Wilhelm.Consulting)
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.