Forum: Mikrocontroller und Digitale Elektronik stm32f303RE - initialisierungen verbeissen sich


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von bingo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi @all
Es sieht mehr aus als es ist, so bitte lasst euch nicht vom langen Code 
abschrecken.
Ich habe ein kleines Problem und zwar habe ich definiert:
1
typedef struct TIMxPIN{
2
  GPIO_TypeDef* port;
3
  uint16_t pin;
4
} TIMxPIN_t;
5
6
// ADC definitions
7
#define ADC1_Channel_IN1                        (TIMxPIN_t){GPIOC, GPIO_PIN_0}
8
#define ADC1_Channel_IN2                        (TIMxPIN_t){GPIOC, GPIO_PIN_1}
9
#define ADC1_Channel_IN3                        (TIMxPIN_t){GPIOC, GPIO_PIN_2}
10
#define ADC1_Channel_IN4                        (TIMxPIN_t){GPIOC, GPIO_PIN_3}
11
#define ADC1_Channel_IN7                        (TIMxPIN_t){GPIOA, GPIO_PIN_2}
12
#define ADC1_Channel_IN8                        (TIMxPIN_t){GPIOA, GPIO_PIN_3}
13
#define ADC1_Channel_IN9                        (TIMxPIN_t){GPIOA, GPIO_PIN_4}
14
#define ADC1_Channel_IN10                       (TIMxPIN_t){GPIOA, GPIO_PIN_5}
15
#define ADC1_Channel_IN11                       (TIMxPIN_t){GPIOA, GPIO_PIN_6}
16
#define ADC1_Channel_IN12                       (TIMxPIN_t){GPIOA, GPIO_PIN_7}
17
#define ADC1_Channel_IN16                       (TIMxPIN_t){GPIOB, GPIO_PIN_1}
18
19
// Board Button Definition
20
#define PushButton                              (TIMxPIN_t){GPIOC, GPIO_PIN_13}

dazu habe ich eine Funktion geschrieben, die mir ein Array nach dem 
Drücken des Buttons ausliest:
1
void ReadOutIntArray()
2
{
3
  if (HAL_GPIO_ReadPin(PushButton.port, PushButton.pin)==0){
4
    for (uint16_t i = 0; i <= 1027; i++)
5
    {        
6
      adcValue = dma0_buffer[i];
7
      USART_Transmit_Int(adcValue);
8
      USART_sendChar('\n');
9
      for (count = 0; count <= 50000; count++);
10
   }
11
  }   
12
}
1
   /**ADC1 GPIO Configuration  */
2
    GPIO_InitStruct.Pin = ADC1_Channel_IN1.pin;
3
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
4
    GPIO_InitStruct.Pull = GPIO_NOPULL;
5
    HAL_GPIO_Init(ADC1_Channel_IN1.port, &GPIO_InitStruct);
6
    
7
    GPIO_InitStruct.Pin = ADC1_Channel_IN2.pin;
8
    HAL_GPIO_Init(ADC1_Channel_IN2.port, &GPIO_InitStruct);
9
    
10
    GPIO_InitStruct.Pin = ADC1_Channel_IN3.pin;
11
    HAL_GPIO_Init(ADC1_Channel_IN3.port, &GPIO_InitStruct);
12
    
13
    GPIO_InitStruct.Pin = ADC1_Channel_IN4.pin;
14
    HAL_GPIO_Init(ADC1_Channel_IN4.port, &GPIO_InitStruct);
15
16
//    GPIO_InitStruct.Pin = ADC1_Channel_IN7.pin ;
17
//    HAL_GPIO_Init(ADC1_Channel_IN7.port, &GPIO_InitStruct);
18
19
    GPIO_InitStruct.Pin = ADC1_Channel_IN8.pin;
20
    HAL_GPIO_Init(ADC1_Channel_IN8.port, &GPIO_InitStruct);
21
22
    GPIO_InitStruct.Pin = ADC1_Channel_IN9.pin;
23
    HAL_GPIO_Init(ADC1_Channel_IN9.port, &GPIO_InitStruct);
24
    
25
    GPIO_InitStruct.Pin = ADC1_Channel_IN10.pin;
26
    HAL_GPIO_Init(ADC1_Channel_IN10.port, &GPIO_InitStruct);
27
28
    GPIO_InitStruct.Pin = ADC1_Channel_IN11.pin;
29
    HAL_GPIO_Init(ADC1_Channel_IN11.port, &GPIO_InitStruct);
30
31
    GPIO_InitStruct.Pin = ADC1_Channel_IN12.pin;
32
    HAL_GPIO_Init(ADC1_Channel_IN12.port, &GPIO_InitStruct);
33
34
    GPIO_InitStruct.Pin = ADC1_Channel_IN16.pin;
35
    HAL_GPIO_Init(ADC1_Channel_IN16.port, &GPIO_InitStruct);
Ich verstehe jetzt nicht, warum das Auslesen durch Drücken des Buttons 
nicht mehr funktioniert, wenn lediglich der
ADC1_Channel_IN7 aktiv ist. Wenn ich diesen im ADC_init auskommentiere, 
funktionierts wieder.
Könnte mir jemand weiterhelfen. Die Ports PA2 und PC13 haben miteinander 
auch nichts zu tun. Ich zumindest sehe keinen Fehler.

von Basic Programmer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wie gross ist dein dma0_buffer ?

von bingo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

zum Lösen des Problems denke ich ist das noch nützlich
1
void activateReadOutButton()
2
{
3
   GPIO_InitTypeDef GPIO_InitStruct;
4
5
  /* GPIO Ports Clock Enable */
6
  __HAL_RCC_GPIOC_CLK_ENABLE();
7
8
   /*Configure GPIO pin : B1_Pin */
9
  GPIO_InitStruct.Pin = PushButton.pin;
10
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
11
  GPIO_InitStruct.Pull = GPIO_NOPULL;
12
  HAL_GPIO_Init(PushButton.port, &GPIO_InitStruct); 
13
}

Der Buffer ist 1027 lang
1
#define DataLength                                 1027
2
uint16_t dma0_buffer[DataLength];

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Glaubst du nicht dass der Code für die DMA und ADC Initialisierung dafür 
relevant wäre?
Warum benutzt du kein Array für die ganzen TIMxPIN Instanzen, durch 
welches du dann einfach iterieren kannst anstatt den selben Code Zig mal 
zu kopieren?

von Basic Programmer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
bingo schrieb:
> Der Buffer ist 1027 lang
> #define DataLength    1027
> uint16_t dma0_buffer[DataLength];

Dann sollte dir hier was auffallen:

bingo schrieb:
> for (uint16_t i = 0; i <= 1027; i++)

von bingo (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Glaubst du nicht dass der Code für die DMA und ADC Initialisierung
> dafür
> relevant wäre?
> Warum benutzt du kein Array für die ganzen TIMxPIN Instanzen, durch
> welches du dann einfach iterieren kannst anstatt den selben Code Zig mal
> zu kopieren?

Hi Dr. Sommer
Ich dachte, dass dies nicht relevant wäre. Entschuldigen Sie mich für 
den Irrtum. Die Dateien habe ich angehängt.

Basic Programmer schrieb:
> bingo schrieb:
>> Der Buffer ist 1027 lang
>> #define DataLength    1027
>> uint16_t dma0_buffer[DataLength];
>
> Dann sollte dir hier was auffallen:
>
> bingo schrieb:
>> for (uint16_t i = 0; i <= 1027; i++)

Gleich nach deiner Frage habe ich den Fehler korrigiert und es zu i < 
1027 abgeändert. Leider kein Erfolg

von bingo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Glaubst du nicht dass der Code für die DMA und ADC Initialisierung
> dafür
> relevant wäre?
> Warum benutzt du kein Array für die ganzen TIMxPIN Instanzen, durch
> welches du dann einfach iterieren kannst anstatt den selben Code Zig mal
> zu kopieren?

Uebrigens, ich finde deinen Ansatz eine sehr gute Idee, aber wenn ich 
bereits eine Schleife drin gehabt hätte, hätte ich wahrscheinlich nicht 
einmal erkannt, dass der Fehler am ADC Kanal IN7 liegt.

Ich optimiere den Code aber gerne, wenn dieser funktioniert.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Welche deiner drei ADC-Initialisierungen ist denn jetzt relevant, 
Init_ADC1 oder Init_ADC1_Test_single oder Init_ADC1_Test_differential?
1
sConfig.Channel = ADC1_Channel_IN1.pin | ADC1_Channel_IN2.pin | ADC1_Channel_IN3.pin | ADC1_Channel_IN4.pin | ADC1_Channel_IN7.pin | ADC1_Channel_IN8.pin | ADC1_Channel_IN11.pin | ADC1_Channel_IN12.pin;

Das ist doch verkehrt. Du kannst hier einen einzelnen Channel 
übergeben, also z.B. ADC_CHANNEL_1. Das ist eine Channel -Nummer, und 
keine Pin -Nummer. Wo ist dein DMA-Interrupt wo du auf Fertigstellung 
reagierst?
1
 ADC1->CFGR &= ~ADC_CFGR_DMACFG;
Du schaltes den Continuous Mode aus, d.h. es werden alle Channels nur 
einmal konvertiert? Warum greifst du überhaupt direkt auf die 
Konfigurations-Register zu, wenn du vorher die HAL genutzt hast?
1
ADC1->SQR1 &= ~ADC_SQR1_L_0;
Du stellst 2 Channels ein, wo du doch vorher offensichtlich (aber 
falsch) versuchst 8 Channels zu nutzen? Aber du setzt dennoch
1
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
 um doch nur einen Channel zu konvertieren?
1
ADC1->CR &= ~ADC_CR_ADSTART;
Du schaltest den ADC aus aber nicht wieder an?

Deine ADC-Konfiguration ist derart vermurkst, es ist ein Wunder dass da 
überhaupt was passiert. Das hat auf jeden Fall nichts mit eventuellen 
Problemen in deinem Anfangs-Code zu tun. Vielleicht solltest du dir 
erstmal Gedanken machen was du genau machen willst, welche Abläufe dein 
Programm nimmt, und das hier genau erläutern.

von bingo (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Dr. Sommer

Dr. Sommer schrieb:
> Welche deiner drei ADC-Initialisierungen ist denn jetzt relevant,
> Init_ADC1 oder Init_ADC1_Test_single oder Init_ADC1_Test_differential?
> sConfig.Channel = ADC1_Channel_IN1.pin | ADC1_Channel_IN2.pin |
> ADC1_Channel_IN3.pin | ADC1_Channel_IN4.pin | ADC1_Channel_IN7.pin |
> ADC1_Channel_IN8.pin | ADC1_Channel_IN11.pin | ADC1_Channel_IN12.pin;
> Das ist doch verkehrt. Du kannst hier einen einzelnen Channel
> übergeben, also z.B. ADC_CHANNEL_1. Das ist eine Channel -Nummer, und
> keine Pin -Nummer. Wo ist dein DMA-Interrupt wo du auf Fertigstellung
> reagierst?

Sie haben völlig Recht. Ich habe die Änderungen vorgenommen und das File 
nochmals angehängt.

>  ADC1->CFGR &= ~ADC_CFGR_DMACFG;Du schaltes den Continuous Mode aus,
> d.h. es werden alle Channels nur
> einmal konvertiert? Warum greifst du überhaupt direkt auf die
> Konfigurations-Register zu, wenn du vorher die HAL genutzt hast?

Ich hatte etwas probiert und war mir nicht sicher warum die Bits nicht 
gesetzt wurden. Das Problem hat sich danach irgendwie selbst gelöst.
Ich habe die Zeilen auch nun entfernt.
Jedoch, um zB die Länge im SQR1 Register festzulegen, müsste ich auf 
Registerebene zurückgreifen, auch wenn ich die HAL zuvor verwendet habe. 
Dafür gibt es ja keine Funktion.

> ADC1->SQR1 &= ~ADC_SQR1_L_0;Du stellst 2 Channels ein, wo du doch vorher
> offensichtlich (aber
> falsch) versuchst 8 Channels zu nutzen? Aber du setzt
> dennochhadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; um doch nur einen
> Channel zu konvertieren?
> ADC1->CR &= ~ADC_CR_ADSTART;Du schaltest den ADC aus aber nicht wieder
> an?

Ich benötige den One Shot mode. Ich konvertiere immer nur einen Wert. 
Der ADC wird getriggert, da ich diesen nur zu bestimmten Zeiten 
benötige.
Stimmt die Länge benötige ich nicht, da Scanconvmode disabled ist.
Ich habe den Code entsprechend angepasst.
Den ADC starte ich später, wenn ich ihn benötige. Dies geschieht anfangs 
im Main und später in den jeweiligen Interrupts etc.

>
> Deine ADC-Konfiguration ist derart vermurkst, es ist ein Wunder dass da
> überhaupt was passiert. Das hat auf jeden Fall nichts mit eventuellen
> Problemen in deinem Anfangs-Code zu tun. Vielleicht solltest du dir
> erstmal Gedanken machen was du genau machen willst, welche Abläufe dein
> Programm nimmt, und das hier genau erläutern.

Kurz: Der ADC wird getriggert, nach jeder einzelnen Conversion sollte 
die DMA die Daten wegschaufeln. Das funktioniert soweit.

Ich weiss schon was ich möchte, ich kann Ihnen leider nicht die ganze 
Story erklären. Ich denke, es ist einfacher, wenn Sie mir die Fragen 
direkt stellen. Ansonsten wird das hier nur eine Prosa.
Ich weiss schon, was ich tue und benötige. Die Einstellungen des ADC 
jedoch ist eine andere Sache, aber ich habe da auch wieder dazugelernt.

Obwohl ich aber die Änderungen vorgenommen habe, scheint das mit dem 
Button immer noch nicht zu funktionieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.