Forum: Mikrocontroller und Digitale Elektronik ADC Werte sind null


von Tobias (Gast)


Lesenswert?

Mein ADC dauert 3,41 us.
Ich habe einen Timer der jede 30us aktiv ist.
Hallo,
ich habe ein Problem mit dem ADC.

Wenn ich 512 mal Werte mit dem ADC_GetConversionValue(ADC) hole , sind 
200 Werte vom ADC3  0 , vom ADC2 sind 139 Werte 0 und beim ADC1 sind 56 
Werte 0.

Was ist das Problem ?
Wieso kommen 0 Werte ?

1
01.void TIM2_IRQHandler(void)
2
02.{
3
03. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
4
04. {        
5
05.   if(calibration < calibration_counter)
6
06.  {             
7
07.   array1 =ADC_GetConversionValue(ADC1);        
8
08.   array2 =ADC_GetConversionValue(ADC2);          
9
09.   array3 =ADC_GetConversionValue(ADC3);          
10
10.   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);              //Update Interrupt
11
11.  }
12
12. }
13
13.}

: Bearbeitet durch User
von TX (Gast)


Lesenswert?

Du hast ein Fehler in Zeile 42!

von Rolf Magnus (Gast)


Lesenswert?

Außerdem empfielt es sich, Seite 47 Zeile 11 im Datenblatt anzusehen.

von Tobias (Gast)


Lesenswert?

Mit Zeile 42 meinst du was genau ?

von TX (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Tobias schrieb:
> Mit Zeile 42 meinst du was genau ?

Auf Deutsch:
Mit deinen Angaben kann man nichts anfangen. Das kann alles und jedes 
sein.
Dass du einen Aufruf von ADC_GetConversionValue hinkriegst, glaubt dir 
auch so jeder. Was immer diese Funktiona auch macht, auf welchem µC Typ 
du auch immer benutzt.
Aber da beim Aufruf steckt höchst wahrscheinlich auch nicht das Problem. 
Das ist ganz wo anders.

Zum Bespiel finde ich es überaus spannend, dass du hier
1
  array1 =ADC_GetConversionValue(ADC1);
Variablen hast, die 'array' heissen. Da kommt man als Programmierer ins 
Grübeln. Denn wenn da wirklich Arrays dahinter stecken, wieso ist da 
dann keine Index-Operation?
Es könnte natürlich auch ein Pointer sein. Aber dann würde man da wohl 
einen Pointer-Inkrement erwarten.
Es kann aber auch alles ganz anders sein. Wer weiß das schon? Es ist, 
wie wenn du bei einem Verkehrsflugzeug (dessen Typ du nicht verrätst) du 
einen Motorausfall diagnostizieren sollst und alles was du präsentierst 
ist eine Beilagscheibe. Nicht sehr hilfreich. Denn die Beilagscheibe ist 
sehr wahrscheinlich nicht das Problem.

: Bearbeitet durch User
von Udo S. (urschmitt)


Lesenswert?

Was dir die beiden mitzuteilen versuchen:
Es gibt nur einen µC und genau ein Typ von ADC im gesamten Universum.
Siehe auch Netiquette bzgl. Problembeschreibung.

: Bearbeitet durch User
von Tobias (Gast)


Lesenswert?

Meine AD Config:
1
01.void Config_ADC(GPIO_InitTypeDef *GPIO_InitStructure)
2
02.{
3
03.    RCC_ADCCLKConfig(RCC_PCLK2_Div6);                                                                                    //clock for ADC  ADCCLK = PCLK2/6 = 72/6 = 12MHz*/
4
04. 
5
05.    // enable ADC system clock
6
06.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);
7
07.  
8
08.     /* Configure PC.01, PC.02 and PC.03 (ADC Channel 11, ADC Channel 12, ADC Channel 13) as analog input */
9
09.    GPIO_InitStructure->GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;                    // PC.01, PC.02 and PC.03
10
10.    GPIO_InitStructure->GPIO_Mode = GPIO_Mode_AIN;                                                               // Input-Mode
11
11.    GPIO_InitStructure->GPIO_Speed = GPIO_Speed_50MHz;                                                     // Speed of port
12
12.    GPIO_Init(GPIOC, GPIO_InitStructure);                                                                                // apply configuration on PortC
13
13.  
14
14.}
15
16
17
01.  ADC_InitStructure->ADC_ContinuousConvMode = ENABLE;                                                      //ster next convert automatically
18
02.  ADC_InitStructure->ADC_DataAlign = ADC_DataAlign_Right;                                              //put left/right adjusted in register
19
03.  ADC_InitStructure->ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;                     //choose which extern signal should start convert
20
04.  ADC_InitStructure->ADC_Mode = ADC_Mode_Independent;
21
05.  ADC_InitStructure->ADC_NbrOfChannel = 1;
22
06.  ADC_InitStructure->ADC_ScanConvMode = DISABLE;
23
07.   
24
08.  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5);  
25
09.ADC_Init(ADC1, ADC_InitStructure);                                                                                      //set config of ADC1
26
10.   
27
11.  ADC_Cmd(ADC1, ENABLE); 
28
29
30
1.//start-callibration
31
2.ADC_ResetCalibration(ADC1);                                                  /* Enable ADC1 reset calibration register */
32
3.while(ADC_GetResetCalibrationStatus(ADC1));                  /* Check the end of ADC1 reset calibration register (Reset previous calibration)*/
33
4.ADC_StartCalibration(ADC1);                                                  /* Start ADC1 calibration */
34
5.while(ADC_GetCalibrationStatus(ADC1));                           /* Check the end of ADC1 calibration */
35
6.//End-callibration
36
7. 
37
8.ADC_SoftwareStartConvCmd(ADC1, ENABLE);

Meine Timer config
1
01.void Config_Timer_TIM2(TIM_TimeBaseInitTypeDef *TIM_TimeBaseStructure, NVIC_InitTypeDef *NVIC_InitStructure)
2
02.{
3
03.    // enable TIMER TIM2 system clock
4
04.  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
5
05.     
6
06.     
7
07. /* Enable the Timer2 Interrupt */
8
08.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
9
09.     
10
10.  NVIC_InitStructure->NVIC_IRQChannel = TIM2_IRQn;                       //  configure the Timer2 interrupts
11
11.  NVIC_InitStructure->NVIC_IRQChannelPreemptionPriority = 3;   //  sets the priority group of the TIMER2 interrupts
12
12.  NVIC_InitStructure->NVIC_IRQChannelSubPriority = 0;                    //  set the subpriority inside the group
13
13.  NVIC_InitStructure->NVIC_IRQChannelCmd = ENABLE;                       //  TIMER2 interrupts are globally enabled
14
14.  NVIC_Init(NVIC_InitStructure);       
15
15.     
16
16.    /* Configure Timer which is every 1 ms active*/
17
17.  TIM_DeInit(TIM2);
18
18.  TIM_TimeBaseStructInit(TIM_TimeBaseStructure);
19
19.  
20
20.  /* Time base configuration */
21
21.  TIM_TimeBaseStructure->TIM_Prescaler = 72 - 1; // 72 MHz / 72 = 1 Mhz
22
22.  TIM_TimeBaseStructure->TIM_Period = 30 - 1;    // (1/1Mhz) * 30 = 30 us;
23
23.  TIM_TimeBaseStructure->TIM_ClockDivision = TIM_CKD_DIV1;
24
24.  TIM_TimeBaseStructure->TIM_CounterMode = TIM_CounterMode_Up;
25
25.  TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure);
26
26.     
27
27.     
28
28.  /* Enable TIM2 Update Interrupt */
29
29.  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
30
30.  
31
31.  /* Enable TIM2 */
32
32.  TIM_Cmd(TIM2,ENABLE);        
33
33.}

und hier werden die AD Werte also im Timer Interrupt aufgerufen
1
01.void TIM2_IRQHandler(void)
2
02.{
3
03. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
4
04. {        
5
05.   if(calibration < calibration_counter)
6
06.  {             
7
07.   array1 =ADC_GetConversionValue(ADC1);        
8
08.   array2 =ADC_GetConversionValue(ADC2);          
9
09.   array3 =ADC_GetConversionValue(ADC3);          
10
10.   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);              //Update Interrupt
11
11.  }
12
12. }
13
13.}

von Tobias (Gast)


Lesenswert?

Ich benütze den STM3210E-Eval board mit dem Prozessor STM32F103ZG.
1
int array1[512] = {0};
2
int array2[512] = {0};
3
int array3[512] = {0};
4
5
void TIM2_IRQHandler(void)
6
{
7
  int static calibration =0
8
 if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
9
 {        
10
   if(calibration < 512)
11
  {             
12
   array1 =ADC_GetConversionValue(ADC1);        
13
   array2 =ADC_GetConversionValue(ADC2);          
14
   array3 =ADC_GetConversionValue(ADC3);    
15
   calibration++;  
16
   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);              //Update Interrupt
17
  }
18
}
19
}

von Tobias (Gast)


Lesenswert?

Tobias schrieb:
> array1 =ADC_GetConversionValue(ADC1);
>    array2 =ADC_GetConversionValue(ADC2);
>    array3 =ADC_GetConversionValue(ADC3);

die array sind natürlich mit index :


array1[calibration]
array2[calibration]
array3[calibration]

von Karl H. (kbuchegg)


Lesenswert?

Wieso ist das natürlich?

In dem Code, den du präsentiert hast, sind sie es nicht.

von Udo S. (urschmitt)


Lesenswert?

[ ] Du hast die Netiquette gelesen (und verstanden)?

: Bearbeitet durch User
von Tobias (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wieso ist das natürlich?
>
> In dem Code, den du präsentiert hast, sind sie es nicht.

Wenn ich den kompletten Code hier reinklatsche dann
a) list das keiner
b) müsste man immer hoch und runter scrollen
c) 80% davon wären nicht relevant für die Frage

Ich wollte es vereinfacht darstellen und im allgemeinen Fragen ob bei 
der AD Wandlung man mit dem ADC_GetConversionValue(ADC) Null Werte 
bekommen kann obwohl sich die Analoge Spannung nie 0 ist.

von Udo S. (urschmitt)


Lesenswert?

Tobias schrieb:
> und im allgemeinen Fragen ob bei
> der AD Wandlung man mit dem ADC_GetConversionValue(ADC) Null Werte
> bekommen kann obwohl sich die Analoge Spannung nie 0 ist.

Wenn der ADC richtig intialisiert und konfiguriert ist, der richtige 
Kanal ausgewählt, die entsprechenden sonstigen Voraussetzungen laut 
Datenblatt erfüllt sind, die Hardware korrekt angeschlossen ist und 
funktioniert dann
NEIN

von Bitflüsterer (Gast)


Lesenswert?

Mein Gutster, so wird das nichts. :-)

>Wenn ich den kompletten Code hier reinklatsche dann
>a) list das keiner
Deswegen steht in der Netiquette auch, dass Du ggf. das Programm so 
reduzieren sollst, dass das Problem gerade noch auftritt. Wenn Du zu dem 
gezeigten Code noch eine main-Funktion bastelst, dann sollte das ein 
erster guter Ansatz sein. (Immer voraussgesetzt das Problem tritt dann 
noch auf).

>b) müsste man immer hoch und runter scrollen
Du kannst den Code auch als Anhang posten.

>c) 80% davon wären nicht relevant für die Frage
Siehe a). Das ist aber an sich unvermeidbar. Das Problem ist eher, das 
Du nicht entscheiden kannst, welches 1% von dem 100%, das relevante ist. 
Deswegen sollst Du alles posten.

von Ralf G. (ralg)


Lesenswert?

Udo Schmitt schrieb:
> [ ] Du hast die Netiquette gelesen (und verstanden)?

Tobias schrieb:
> c) 80% davon wären nicht relevant für die Frage

Dann lässt du die weg. Änderst den Rest so, dass du's übersetzen kannst. 
Spielst das ganze auf den µC und wenn der Fehler dann immer noch da ist, 
dann fragst du noch mal.

Edit:
Bitflüsterer schrieb:
> Mein Gutster, so wird das nichts. :-)

... das meinte ich.

: Bearbeitet durch User
von Tobias (Gast)


Lesenswert?

Udo Schmitt schrieb:
> Tobias schrieb:
>> und im allgemeinen Fragen ob bei
>> der AD Wandlung man mit dem ADC_GetConversionValue(ADC) Null Werte
>> bekommen kann obwohl sich die Analoge Spannung nie 0 ist.
>
> Wenn der ADC richtig intialisiert und konfiguriert ist, der richtige
> Kanal ausgewählt, die entsprechenden sonstigen Voraussetzungen laut
> Datenblatt erfüllt sind, die Hardware korrekt angeschlossen ist und
> funktioniert dann
> NEIN

Super das war die Antwort auf die Frage

von Ingo (Gast)


Lesenswert?

Also manche Leute... ?

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.