Forum: Mikrocontroller und Digitale Elektronik STM32 F0 über UART senden zum PC


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 Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin relativ neu in der STM32 Umgebung und bin schon teilweise 
wirklich an meine Verständnis Grenzen gestoßen. ^^ Ich wollte zum 
Debuggen über GPIOA PA2 und PA3 Nachrichten zu meinen PC auf Putty 
senden. Der Code gibt keine Compilefehler aber ebenso kommt auch nichts 
auf meinem PC an.

Der Code sieht wie folgt aus:
1
#include "CMSIS\stm32f0xx.h"
2
#include "STM32F0xx\stm32f0xx_hal_conf.h"
3
#include "STM32F0xx\stm32f0xx_hal.h"
4
#include "STM32F0xx\stm32f0xx_hal_tim.h"
5
6
7
GPIO_InitTypeDef GPIO_struct;
8
UART_HandleTypeDef UART_Struct;
9
10
uint8_t Transmitbuffer[8] = {1,2,3,4,5,7,8};
11
12
void GPIO_Initialise_USART()
13
{
14
  // Aktivieren der Peripherien
15
  __HAL_RCC_GPIOA_CLK_ENABLE();
16
  __HAL_RCC_USART2_CLK_ENABLE();
17
18
19
        //PA3 als receive
20
  GPIO_struct.Pin = GPIO_PIN_3; // RX -> PA3 input
21
  GPIO_struct.Mode = GPIO_MODE_INPUT;
22
  GPIO_struct.Alternate = GPIO_AF1_USART2;
23
  HAL_GPIO_Init(GPIOA, &GPIO_struct);
24
25
26
        //PA2 als transmit
27
  GPIO_struct.Pin = GPIO_PIN_2; // TX -> output
28
  GPIO_struct.Mode = GPIO_MODE_AF_PP;
29
  GPIO_struct.Pull = GPIO_NOPULL;
30
  GPIO_struct.Speed = GPIO_SPEED_HIGH;
31
  GPIO_struct.Alternate = GPIO_AF1_USART2;
32
  HAL_GPIO_Init(GPIOA, &GPIO_struct);
33
34
  UART_Struct.Instance = USART2; // USART2 aktivieren
35
36
  UART_Struct.Init.BaudRate = 38400; // Baudrate auf 38400 BPS
37
  UART_Struct.Init.Mode = UART_MODE_TX_RX; //Empfangen/Senden
38
  UART_Struct.Init.Parity = UART_PARITY_NONE; 
39
  UART_Struct.Init.WordLength = UART_WORDLENGTH_8B; // 8Bit Wortlänge
40
  UART_Struct.Init.StopBits = UART_STOPBITS_1;
41
  UART_Struct.Init.HwFlowCtl = UART_HWCONTROL_NONE; // Kein HW
42
43
  UART_Struct.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; 
44
        // keine erweiterte Initialisierung
45
46
  
47
        //UART initialisieren
48
  HAL_UART_Init(&UART_Struct);
49
50
  //UART aktivieren
51
  __HAL_UART_ENABLE(&UART_Struct);
52
53
}
54
55
56
57
58
59
int main(void)
60
{
61
  GPIO_Initialise_USART();
62
63
  while(1)
64
        {
65
66
        // Datenübertragung über USART2
67
        HAL_UART_Transmit(&UART_Struct, Transmitbuffer, transmitBufferSize, 0xFFF);
68
        }
69
}

Wie gesagt, kein Compiler-Fehler. Bei Putty kommt gar nichts an, welches 
aber auch richtig konfiguriert ist - COM4 wie es im Geräte Manager unter 
STLink virtuell steht, ebenso gleiche Baudrate eingestellt. Weiß jemand 
woran es evtl harpern könnte? Ich bin für jede Hilfe dankbar.

: Bearbeitet durch User
von Markus (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nimm doch einfach STM32Duino:
http://grauonline.de/wordpress/?page_id=1004

von Daniel V. (voda) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Nimm doch einfach STM32Duino:
> http://grauonline.de/wordpress/?page_id=1004

Eine Antwort die auch rein gar nichts mit der Fragestellung zu tun hat.

Prüfe ob der Takt für die Peripherie aktiviert ist.
Prüfe ob Du im CubeMX eine falsche Einstellung gemacht hast.
Gucke Dir die Flags im debugmode an.
Schaue mal alternativ mit HTerm dir die Schnittstelle an
Lese das Datenblatt.

Gruß
Daniel

von Patrick S. (pad)


Bewertung
1 lesenswert
nicht lesenswert
Moin,

PA2 und PA3 sind auch die UART-Pins die auf dem Nucleo an dem ST-Link 
dran sind?

von pegel (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Ist das die komplette main Funktion?

Wo wird der Takt eingestellt? HAL Init?

Sieh dir ein Beispiel an.

von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
@Daniel

Ich benutze kein CubeMX, initialisiere selber.
1
  __HAL_RCC_GPIOA_CLK_ENABLE();
2
  __HAL_RCC_USART2_CLK_ENABLE();

Sollte doch über RCC alle Peripherien aktivieren die ich benötige. Ich 
benutz Eclipse zum Programmieren, wo kann man dort denn die Flags 
betrachten?


@Patrick

Im Datenblatt unter USART Communication steht folgendes:

"The USART2 interface available on PA2 and PA3 of the STM32 
microcontroller can be connected to ST-LINK MCU, ST morpho connector or 
to Arduino connector. The choice can be changed by setting the related 
solder bridges. By default the USART2 communication
between the target STM32 and ST-LINK MCU is enabled, in order to support 
virtual COM port for mbed (SB13 and SB14 ON, SB62 and SB63 OFF)."

das hab ich daraus abgeleitet. ^^,

von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
@Pegel,

das hab ich schon. In den meisten wird auch kein Takt eingestellt und es 
funktioniert trotzdem. :/

von pegel (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Peter G. schrieb:
> In den meisten wird auch kein Takt eingestellt

Wo gibt es solche Beispiele? Nie gesehen.

Ich weiß nicht welchen F0 du hast, aber die mir bekannten Beispiele 
ähneln alle der main.c in der HAL Lib:

STM32Cube_FW_F0_V1.7.0/Projects/STM32F030R8-Nucleo/Examples/UART/UART_Tw 
oBoards_ComPolling/Src

von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
Mit Takt meinst du die SystemClockConfig?

Bsp:
https://www.youtube.com/watch?v=-ZHJ31Q_5i8

Er programmiert zwar einen F103 und das mit der Standart Periphal 
Libary. Hab das nur nicht als all zu schlimm gesehen, bin nur mit der 
HAL Libary eine Schicht näher an der Hardware oder seh ich das falsch? 
Hab nur versucht über HAL Funktionen dasselbe zu deklarieren und 
initialisieren wie er auch.

: Bearbeitet durch User
von pegel (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Mit einer Mischung aus Std und HAL habe ich mich nie beschäftigt.
Bei Nutzung der HAL Funktionen sollte aber mindestens ein HAL_Init() 
aufgerufen werden.

Mit der HAL bist du eine Schicht weiter weg von der Hardware, was die 
Sache einfacher macht - bei richtiger Anwendung.

CubeMX kennst du?

von Ingo L. (corrtexx)


Bewertung
1 lesenswert
nicht lesenswert
Peter G. schrieb:
> // Datenübertragung über USART2
>         HAL_UART_Transmit(&UART_Struct, Transmitbuffer,
> transmitBufferSize, 0xFFF);
>         }
Damit dürftest du deinen PC sowas von überlaufen... Überleg mal was dort 
an Daten rein kommt. Pack wenigstens irgendwie ein Delay von 200ms 
zwischen zwei Transaktionen.

Alternativ mal mitm Oszi gucken was ausm TXD rauskommt.

: Bearbeitet durch User
von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
@Ingo

Danke, das ergibt ziemlichen Sinn. x_x Werde einen Timer dafür verwenden 
um ein Delay zu erzeugen.

@pegel

Das HAL_INIT(); hatte ich vergessen aber dies resettet doch eh nur die 
Peripherien, oder?


* @brief  This function configures the Flash prefetch,
  *       Configures time base source, NVIC and Low level hardware
  * @note This function is called at the beginning of program after 
reset and before
  *       the clock configuration
  * @note The time base configuration is based on HSI clock when exiting 
from Reset.
  *       Once done, time base tick start incrementing.
  *       In the default implementation,Systick is used as source of 
time base.
  *       The tick variable is incremented each 1ms in its ISR.

: Bearbeitet durch User
von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
Das mit dem überlaufen hab ich provisorisch erst einmal so gelöst:
1
if (count == 300000)
2
    {
3
    HAL_UART_Transmit(&UART_Struct, Transmitbuffer, transmitBufferSize, 0xFFF);
4
    count = 0;
5
    }
6
    ++count;

daran lag es zumindestens nicht. :/

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Peter G. schrieb:
> Werde einen Timer dafür verwenden
> um ein Delay zu erzeugen.

Peter G. schrieb:
> * @brief  This function configures the Flash prefetch,
>   *       Configures time base source, NVIC and Low level hardware

Warum willst du dir das so schwer machen?
Zum ausprobieren ist das ja schön, aber wenn es einfach funktionieren 
soll würde ich doch den kürzesten Weg gehen.

von Daniel V. (voda) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Peter G. schrieb:
> Ich benutze kein CubeMX, initialisiere selber.

Ach so, warum benutzt Du dann die HAL? Installiere testhalber den CubeMX 
und konfiguiere deinen Controller. Im Video hat der Videoersteller die 
SPL genommen. Macht auch mehr Sinn wenn Du CubeMX nicht nimmst.

Sonst im Reference Manual den Clock-Tree anschauen und, wie ein 
Vorredner schon gesagt hat, mit einem Oszi mal messen ob überhaupt ein 
Signal da ist. Kommen denn mit HTerm die Signale an?

Gruß
Daniel

PS: Ich sehe gerade:
1
#include "CMSIS\stm32f0xx.h"
2
#include "STM32F0xx\stm32f0xx_hal_conf.h"
3
#include "STM32F0xx\stm32f0xx_hal.h"
4
#include "STM32F0xx\stm32f0xx_hal_tim.h"

Es müsste doch auch eine
1
#include "STM32F0xx\stm32f0xx_hal_usart.h"

geben, oder?

PPS:
Bustakt für APB/AHB fehlt auch. Bitte im Datenblatt nachlesen!!!

: Bearbeitet durch User
von Peter G. (trafel30)


Bewertung
0 lesenswert
nicht lesenswert
@Daniel

Danke für die Antwort, den Header von der usart hatte ich vergessen mit 
herauszuschreiben. Mein Code hat noch ein paar andere Funktionen. ^^,

Ich hab CubeMX, der generiert mir auch den Code,

Was meinst du mit Bustakt, ich weiß das man den RCC Takt konfigurieren 
kann... aber der hat doch auch eine Default Einstellung, oder?

Die Register werden doch durch die Funktionen aktiviert durch das RCC:

__HAL_RCC_GPIOA_CLK_ENABLE() sowie #define __HAL_RCC_USART2_CLK_ENABLE()
1
#define __HAL_RCC_GPIOA_CLK_ENABLE()   do { \
2
                                        __IO uint32_t tmpreg; \
3
                                        SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);\
4
                                        /* Delay after an RCC peripheral clock enabling */ \
5
                                        tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);\
6
                                        UNUSED(tmpreg); \
7
                                      } while(0)
8
9
10
11
12
#define __HAL_RCC_USART2_CLK_ENABLE()   do { \
13
                                        __IO uint32_t tmpreg; \
14
                                        SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
15
                                        /* Delay after an RCC peripheral clock enabling */ \
16
                                        tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\
17
                                        UNUSED(tmpreg); \
18
                                      } while(0)

@pegel, weil ich den Code verstehen wollte und selbst anwenden möchte 
bevor ich Hilfswerkzeug dazu verwende, aus Fehlern lernt man ja am 
besten, nur ist dieser echt komisch. Ich hab eben einen Kollegen darüber 
schauen lassen, der konnte kein Fehler entdecken, es sollte eigentlich 
funktionieren und dieser hat ein paar Jahre Berufserfahrung mit STM32. 
^^, Evtl... liegt der Fehler ganz woanders. x_x

: Bearbeitet durch User

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.