Forum: Mikrocontroller und Digitale Elektronik stm32 harte nuß !


von Reiner D. (dollreiner)


Lesenswert?

Hallo,

ich beginne mit dem stm32f4 discovery. em::blocks als ide, mit dem 
avr-gcc compiler ("bare metal").

folgendes progrämmchen läuft prima :
1
#include <stddef.h>
2
#include <stdlib.h>
3
#include "stm32f4xx.h"
4
5
volatile u8 sysTickCounter=0;
6
7
void initApplication()
8
{
9
  SysTick_Config(SystemCoreClock/100);
10
11
  // GPIOD Periph clock enable
12
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
13
14
  GPIO_InitTypeDef  GPIO_InitStructure;
15
16
  // Konfigurire PD15 als Ausgang
17
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
18
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
19
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
20
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
21
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
22
  GPIO_Init(GPIOD, &GPIO_InitStructure);
23
24
  //  Konfiguriere PA0
25
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
26
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
27
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
28
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
29
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
30
  GPIO_Init(GPIOA, &GPIO_InitStructure);
31
32
}
33
34
int main(void)
35
{
36
  SystemInit();
37
  initApplication();
38
  do
39
    {
40
        if (GPIOA->IDR & 0x0001)
41
        {
42
            GPIO_SetBits(GPIOD,GPIO_Pin_15);
43
            //GPIO_ResetBits(GPIOD,GPIO_Pin_15);
44
        }
45
        else
46
        {
47
            //GPIO_SetBits(GPIOD,GPIO_Pin_15);
48
            GPIO_ResetBits(GPIOD,GPIO_Pin_15);
49
        }
50
    }
51
  while (1);
52
  return 0;
53
}

aber jetzt kommts : wenn ich die leuchtlogik umdrehe (set <-> reset, wie 
in den kommentarzeilen) geht nichts !

auch wenn ich ne blinkschleife einbaue : nichts !!

ich werd wahnsinnig ...

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Und was passiert bei

  GPIO_WriteBit(GPIOD, GPIO_Pin_15, SET);

bzw.

  GPIO_WriteBit(GPIOD, GPIO_Pin_15, RESET);

?

von Dr. Sommer (Gast)


Lesenswert?

Reiner Doll schrieb:
> RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
Vielleicht auch mal den Takt für GPIOA einschalten...

von Jay (Gast)


Lesenswert?

Hi,

was bedeutet die Zeile:
if (GPIOA->IDR & 0x0001)
?

von Jay (Gast)


Lesenswert?

... vergesst es. Ich hab den Quellcode nicht komplett gelesen.

von Dr. Sommer (Gast)


Lesenswert?

Jay schrieb:
> if (GPIOA->IDR & 0x0001)
Abfragen ob der Pin PA0 auf '1' gesetzt ist.

von Reiner D. (dollreiner)


Lesenswert?

hallo dr. sommer,

aber warum gehts dann so wie im text ??

egal. verzeih die dummy-frage : wie schalt ich den gpioa an den takt ?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Reiner Doll schrieb:
> egal. verzeih die dummy-frage : wie schalt ich den gpioa an den takt ?

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Reiner Doll schrieb:
> wie schalt ich den gpioa an den takt ?
Wie schaltest du denn den GPIO Port D an den Takt? Mein erster Versuch 
wäre, die Zeile zu kopieren und das D durch ein A zu ersetzen...

Oder eine kurze Google Umfrage zu starten:
https://www.google.de/search?q=RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO

: Bearbeitet durch Moderator
von Dr. Sommer (Gast)


Lesenswert?

Reiner Doll schrieb:
> aber warum gehts dann so wie im text ??
Vielleicht ein Zufall. Wenn man Controller außerhalb der Spezifikation 
betreibt passieren komische Dinge. Außerdem hast du ja gar nicht gesagt, 
was "geht nichts" und "läuft prima" bedeutet.

Reiner Doll schrieb:
> egal. verzeih die dummy-frage : wie schalt ich den gpioa an den takt ?
Genauso wie bei GPIOD, und da hast du es ja schon erfolgreich gemacht. 
Hier bitte Transferleistung erbringen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> bitte Transferleistung erbringen
Es gibt 2 Arten von Menschen:
1. solche, die aus unvollständigen Daten extrapolieren können.

von Reiner D. (dollreiner)


Lesenswert?

;-)

  // GPIOD, GPIOA Periph clock enable
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

bringt nix, geht genausowenig ...

von Dr. Sommer (Gast)


Lesenswert?

Reiner Doll schrieb:
> bringt nix, geht genausowenig ...
Erlätuere doch mal genau, was das heißt. Und auch, was in der 1. 
Variante funktioniert. Zwischen den Tests mal das Board komplett vom 
Strom trennen, um einen "echten" Neustart des Controllers zu 
garantieren.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Reiner Doll schrieb:
> bringt nix, geht genausowenig ...

Ohne zu wissen, was Dein (...->IDR &0x0001) überhaupt macht, prüfst Du 
doch, ob der User-Button benutzt wurde, oder?

Prbiere mal folgenden Code:
1
#define BUTTON_PERIPH   RCC_AHB1Periph_GPIOA
2
#define BUTTON_PORT     GPIOA
3
#define BUTTON_PIN      GPIO_Pin_0
4
5
void button_init (void)
6
{
7
    GPIO_InitTypeDef gpio;
8
9
    RCC_AHB1PeriphClockCmd(BUTTON_PERIPH, ENABLE);
10
11
    // Config als Digital-Eingang
12
    gpio.GPIO_Mode = GPIO_Mode_IN;
13
    gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
14
    gpio.GPIO_Pin = BUTTON_PIN;
15
    GPIO_Init(BUTTON_PORT, &gpio);
16
}
17
18
int button_pressed (void)
19
{
20
    if (GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN) == Bit_RESET)
21
    {
22
        return 0;
23
    }
24
    return 1;
25
}

und ersetze Deine Abfrage durch:

   if (button_pressed ())
   ....

P.S.
Auch für die LED kann man solche schönen Funktionen schreiben, z.B. so:
1
#define LED_PORT    GPIOD
2
#define LED_PERIPH  RCC_AHB1Periph_GPIOD
3
4
#define LED_GREEN   GPIO_Pin_12
5
#define LED_ORANGE  GPIO_Pin_13
6
#define LED_RED     GPIO_Pin_14
7
#define LED_BLUE    GPIO_Pin_15
8
9
void
10
led_init (void)
11
{
12
    GPIO_InitTypeDef gpio;
13
14
    RCC_AHB1PeriphClockCmd(LED_PERIPH, ENABLE);     // enable clock for PortD
15
16
    gpio.GPIO_Pin   = (LED_BLUE|LED_RED|LED_ORANGE|LED_GREEN);
17
    gpio.GPIO_Mode  = GPIO_Mode_OUT;
18
    gpio.GPIO_OType = GPIO_OType_PP;
19
    gpio.GPIO_PuPd  = GPIO_PuPd_NOPULL;
20
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
21
22
    GPIO_Init(LED_PORT, &gpio);
23
}
24
25
void
26
led_on (uint16_t led)
27
{
28
    GPIO_WriteBit(LED_PORT, led, SET);
29
}
30
31
void
32
led_off (uint16_t led)
33
{
34
    GPIO_WriteBit(LED_PORT, led, RESET);
35
}

Dann reduziert sich Deine main() auf:
1
    button_init();
2
    led_init();
3
4
    while (1)
5
    {
6
        if (button_pressed())
7
           led_on (LED_BLUE);
8
        else
9
           led_off (LED_BLUE);
10
    }
11
}

Ist doch wesentlich lesbarer, oder?

: Bearbeitet durch Moderator
von Reiner D. (dollreiner)


Lesenswert?

habs ausprobiert.

der code von frank macht das gleiche wie meiner : auf knopfdruck wird 
die blaue led geschalten. in der "frank-variante" :

        if (button_pressed ())
        {
            GPIO_ResetBits(GPIOD,GPIO_Pin_15);
            //GPIO_SetBits(GPIOD,GPIO_Pin_15);
        }
        else
        {
            GPIO_SetBits(GPIOD,GPIO_Pin_15);
            //GPIO_ResetBits(GPIOD,GPIO_Pin_15);
        }


so gehts. druck auf den schwarzen taster -> blaue led aus.

aber so :


        if (button_pressed ())
        {
            //GPIO_ResetBits(GPIOD,GPIO_Pin_15);
            GPIO_SetBits(GPIOD,GPIO_Pin_15);
        }
        else
        {
            //GPIO_SetBits(GPIOD,GPIO_Pin_15);
            GPIO_ResetBits(GPIOD,GPIO_Pin_15);
        }

gehts eben nicht. es passiert gar nix. (ob : RCC_AHB1Periph_GPIOA, 
ENABLE gesetzt ist, ändert auch nix. hab ich jetzt natürlich, danke 
dafür nochmal)

von (prx) A. K. (prx)


Lesenswert?

Reiner Doll schrieb:
> so gehts. druck auf den schwarzen taster -> blaue led aus.

Und auch wieder retour, wenn Taster losgelassen?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Reiner Doll schrieb:
> so gehts. druck auf den schwarzen taster -> blaue led aus.

Auf den SCHWARZEN Taster?!?!?!?

Das ist der RESET-Button! :-))))))))))))

Du musst schon den blauen Taster nehmen.

Hahahahaaaa, der war echt gut!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Und auch wieder retour, wenn Taster losgelassen?

Klar doch, wenn er den Reset-Taster wieder loslässt ;-)

von Reiner D. (dollreiner)


Lesenswert?

das ist der knaller ...

es geht aber mit der blauen taste überhaupt nicht, beide varianten 
nicht.
wenn der schwarze reset macht, erklärt das meinen testfehler : das 
schaut genauso aus, als würde die eine variante funktionieren  .. 
während des reset ist die led aus.

also : es geht keines von meinen programmen. ;-((

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Reiner Doll schrieb:
> also : es geht keines von meinen programmen. ;-((

Das wundert mich aber. Die oben von mir skizzierten Funktionen habe ich 
selbst so ausprobiert und im Einsatz. Das kann ich aber erst heute abend 
testen.

von Matthias L. (Gast)


Lesenswert?

Du solltest hier anfangen:

http://www.diller-technologies.de/stm32.html#start

hat mir auch geholfen...

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Klar doch, wenn er den Reset-Taster wieder loslässt ;-)

Der war gut!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Matthias Lipinsky schrieb:
> Du solltest hier anfangen:
>
> http://www.diller-technologies.de/stm32.html#start

Genau da ist er doch gerade, nämlich beim Schalten von LEDs. Leider 
kann man das Diller-Beispiel genau hier nicht verwenden, weil die 
Port-Definitionen von der Numerierung her für den STM32F1 komplett 
anders sind.

Reiner hat das schon richtig gemacht. Er sollte aber trotzdem mal die
GPIO_WriteBit() Funktion nehmen.

von Reiner D. (dollreiner)


Lesenswert?

danke für den tipp mit diller. hatte ich schon probiert, wegen der nicht 
kompatilen libraries (f10) dann aber aufgegeben.

auch das habe ich schon probiert :

        if (button_pressed ())
        {
            //GPIO_ResetBits(GPIOD,GPIO_Pin_15);
            //GPIO_SetBits(GPIOD,GPIO_Pin_15);
            GPIO_WriteBit(GPIOD, GPIO_Pin_15, SET);
        }
        else
        {
            //GPIO_SetBits(GPIOD,GPIO_Pin_15);
            //GPIO_ResetBits(GPIOD,GPIO_Pin_15);
            GPIO_WriteBit(GPIOD, GPIO_Pin_15, RESET);
        }


... no go. (trotz gezieltem druck auf den BLAUEN taster ;-)

wahnsinn. ich habe vor nem jahr ungefähr mit dem atmega128 gespielt. da 
hat die einarbeitung genau einen nachmttag gedauert. das hier ist ne 
andere liga.

von Franz (Gast)


Lesenswert?

Weißt du was AVR oder STM32 sind?

Reiner Doll schrieb:
> ich beginne mit dem stm32f4 discovery. em::blocks als ide, mit dem
> avr-gcc compiler ("bare metal").

von Uwe B. (derexponent)


Lesenswert?

den gleichen Fehler hatten wir hier schonmal im Forum

diese Zeile ist schuld :

SysTick_Config(SystemCoreClock/100);


du schaltest den Timer ein, hast aber keine ISR dafuer
programmiert

ergo landet die CPU im HardFaultHandler und
macht eine while(1)

Gruss Uwe

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Reiner Doll schrieb:
> wahnsinn. ich habe vor nem jahr ungefähr mit dem atmega128 gespielt. da
> hat die einarbeitung genau einen nachmttag gedauert. das hier ist ne
> andere liga.

Ich spiele auch erst seit 2 Wochen mit dem STM32F4-Disco-Board herum. 
Wenn man einmal die (vermeintlichen) Einstiegshürden überwunden hat, 
dann fluppt es danach wesentlich einfacher als bei den AVRs. Hab etwas 
Geduld :-)

Schau Dir mal die einzelnen Projekte von

   http://mikrocontroller.bplaced.net/wordpress/?page_id=744

an... schön von oben nach unten. Das hat mir mehr als alles andere (div. 
Tutorials etc) gebracht. Eigentlich ist von allem, was das Disco-Board 
so bietet, etwas dabei.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Uwe B. schrieb:
> diese Zeile ist schuld :
>
> SysTick_Config(SystemCoreClock/100);

Upps, Du hast recht. Die Zeile muss wech.

von npn (Gast)


Lesenswert?

Reiner Doll schrieb:
> ich beginne mit dem stm32f4 discovery. em::blocks als ide, mit dem
> avr-gcc compiler ("bare metal").

Stimmt!
Franz hats gesehen... Wäre mir nicht gleich aufgefallen.
Stell mal statt dem AVR-GCC den STM32-Compiler ein (müßte "ARM-GCC" 
heißen).

von A. B. (funky)


Lesenswert?

probier doch erstmal die LED überhaupt blinken zu lassen ohne jegliche 
Benutzerinteraktion...

ne Schleife, Pausen und On/Off


desweiteren Beitrag "STM32F4 Taster"

schmeiss also mal dein systick_config rasu und schau was dann passiert.

Würde auch zu deiner Beschreibugn passen. Der Code läuft einmal durch 
und setzt die LED ohne Tastendruck, danach hängt das Ding in der Systick 
Schleife.

Änderst du den Code dahingeghend das die LED nach Tastendruck gesetzt 
wird, siehst du nix, da dein Code nach 100us in der Schleife hängt

Halt doch mal den Taster gedrückt bei Variante 2 und starte den uC dann. 
Theoretisch müsste die LED dann ja leuchten


Hat em::Blocks keinen Debugger Support?

von A. B. (funky)


Lesenswert?

Oh...Uwe B. war schneller. Hatte geschrieben und erst später abgeschickt

von Reiner D. (dollreiner)


Lesenswert?

da wär ich nie draufgekommen. danke !!

jetzt geht alles einwandfrei ;-)



@franz : avr/arm verwechselt oben (arm gcc), sorry.



jetzt mal blinken, dann ein wenig uart, dann a/d-wandler, das wird 
sicher heiter mit dem ding.

: Bearbeitet durch User
von Grobi (Gast)


Lesenswert?

Reiner ich kann dir das aktuellle emblocks und die aktuelle stm32cubef4 
von stm empfehlen sowie das cubemx. Nimmt einem doch schon was an Arbeit 
mit der ganzen initialisierung etc. und Ansteuerung der peripherie ab. 
Und wenn du ganz genau wissen möchtest wie das alles so funzt kannste 
dir auch immer noch den quellcode der libs anschauen, die Jungs von STM 
wissen doch schon eigentlich ganz gut was sie da tun... obwohl es immer 
noch ein paar "bugs" darin gibt, aber dazu findet sich genug in diversen 
foren etc.

von Dr. Sommer (Gast)


Lesenswert?

Grobi schrieb:
> die Jungs von STM
> wissen doch schon eigentlich ganz gut was sie da tun...
Ahaha, der war gut. Sobald die ST-Leute irgendwas mit Software 
anfassen, gehts schief. Die "Cube" Libraries sind da noch schlimmer als 
die alten "Standard Peripheral Libraries" - Struktur noch vermurkster, 
noch (unnötig!) ineffizienter...


Problem: "Das API unserer Library ist so umständlich und kompliziert"
Normale Programmierer: "Wir verbessern das API"
ST-Programmierer: "Wir bauen einen Code-Generator (STM32CubeMX), um die 
Library-Aufrufe zu generieren"

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> Grobi schrieb:
>> die Jungs von STM
>> wissen doch schon eigentlich ganz gut was sie da tun...
> Ahaha, der war gut. Sobald die ST-Leute irgendwas mit Software
> anfassen, gehts schief. Die "Cube" Libraries sind da noch schlimmer als
> die alten "Standard Peripheral Libraries" - Struktur noch vermurkster,

Ja? Finde ich nicht. meinem Eindruck nach wurde da etwas entschlackt.

> noch (unnötig!) ineffizienter...

Ok, darüber kann man reden :-)

> ST-Programmierer: "Wir bauen einen Code-Generator (STM32CubeMX), um die
> Library-Aufrufe zu generieren"

Den Generator finde ich nicht schlecht - auch weil man da sich sehr 
schön den passenden Chip raussuchen kann ohne sich durch die 
gehäusetypen wühlen zu müssen und direkt sieht, wo Pinbelegungen sich 
gegenseitig ausschließen.

ST zwingt einen ja auch nicht dazu, die Bibliotheken zu nutzen :-)

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.