STM32 USART sendet 3 anstatt 1 byte

OP #2630090
Lesenswert?

Guten Abend zusammen...

Ich versuche derzeit den USART beim STM32F105RB zu konfigurieren.

Das Problem. wenn ich z.B. ein A sende, kommt (hex) 00 1C 00 an.
wenn ich 0 sende als hex kommt auch 0 an.

Ich weiss, dass es beim STM32 sehr viele Clock einstellungen und PLLs 
gibt.
Doch meines wissens macht diese Einstellungen die StdPeriphLib selbst.
Ist das korrekt?

Ich steppe den Code durch. es wird also nicht ununterbrochen gesendet.

Mein Quarz ist 8MHz deshalb das define.

Danke schonmal

Hier mal mein Code:
1
#define HSE_VALUE 8000000
2

3

4
#include <stddef.h>
5
#include "stm32f10x.h"
6

7

8
int main(void)
9
{
10

11
  //SystemInit();
12

13

14
  GPIO_InitTypeDef GPIO_InitStructure;
15

16
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
17
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
18
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
19

20
  /* Configure USART2 Tx as alternate function push-pull */
21
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
22
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
23
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
24
  GPIO_Init(GPIOA, &GPIO_InitStructure);
25

26

27
  USART_InitTypeDef USART_InitStructure;
28
  USART_InitStructure.USART_BaudRate = 38400;
29
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
30
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
31
  USART_InitStructure.USART_Parity = USART_Parity_No;
32
  USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
33
  USART_InitStructure.USART_Mode = USART_Mode_Tx;
34
  USART_Init(USART1, &USART_InitStructure);
35
  USART_Cmd(USART1, ENABLE);
36

37

38

39

40
  while (1)
41
  {
42

43
  USART_SendData(USART1, 'A');
44

45
  }
46

47
}
OP #2630383
Lesenswert?

Danke euch allen...

Habe den Fehler gefunden!

Ich verwende hier ja einen ConnectivityLine Controller.
Deshalb ist STM32F10X_CL definiert.

Dies führt im File stm32f10x.h zu folgendem "Problem"
1
#if !defined  HSE_VALUE
2
 #ifdef STM32F10X_CL   
3
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
4
 #else 
5
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
6
 #endif /* STM32F10X_CL */
7
#endif /* HSE_VALUE */

Hier wird dann ein 25MHz HSE (Quarz) definiert.
Ich verwende jedoch einen 8MHz Quarz.

Dies war mir jedoch schon vorher bewusst, deswegen habe ich VOR dem 
includieren der stm32f10x.h Datei folgende Zeile hinzugefügt:
1
#define HSE_VALUE ((uint32_t)8000000)

Nach dem Compilieren wurde nun der Abschnitt welcher den 25MHz Quarz 
definiert hatte ausgegraut. Ich ging also davon aus, dass ich korrekt 
den neuen Wert gesetzt hatte.

Die gesamte StdPeriphLib brechnet Ihre Taktspezifischen Werte mit dem 
HSE_Value

Doch leider klappte die definition des 8MHz Quarzes nicht.
Obwohl diese Stelle nun Grau war, war das define HSE_Value an allen Code 
Stellen 25MHz. Erst ein entfernen meiner definition vor dem Inkludieren 
und ein anpassen des Files brachte abhilfe.
1
#if !defined  HSE_VALUE
2
 #ifdef STM32F10X_CL   
3
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
4
 #else 
5
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
6
 #endif /* STM32F10X_CL */
7
#endif /* HSE_VALUE */

Kann mir jemand dieses Verhalten erklären?

Es wird in den Comments auf folgendes hingwiesen:
1
/* Tip: To avoid modifying this file each time you need to use different HSE, you
2
        can define the HSE value in your toolchain compiler preprocessor. */

Doch wo liegt hier der Unterschied zu meinem vorgehen?

Danke schonmal :)

P.S. nach dem ändern des Abschnitts auf 8000000 funktionierte der USART 
problemlos.
#2631367
Lesenswert?

Hi,

wo ist die Funktion USART_Init() definiert? Wenn die z.B. in einer Datei 
USART.c definiert ist, die stm32f10x.h inkludiert, dann hat es keine 
Auswirkung wenn du in main.c (oder wie du sie halt genannt hast) einen 
anderen HSE_VALUE wert definierst.
Wenn der Compiler USART.c erstellt, holt er sich den Wert aus aus der 
stm32f10x.h, und deshalb ist das immer noch der "alte" Wert. Nur wenn er 
main.c erstellt, ist der Wert richtig definiert.

Um das Problem zu lösen kannst du, wie schon gemacht, die stm32f10x.h 
oder USART.c ändern. Das hat aber den Nachteil dass du die Datei(en) 
potentiell für jedes Projekt neu anpassen musst. Idealerweise bleibt die 
Datei stm32f10x.h aber unangetastet. Deshalb kannst du deinem Compiler 
schon vorher sagen dass du das Symbol HSE_VALUE entsprechend definiert 
haben willst (siehe die von dir zitierten Comments). Wie das in deiner 
Entwicklungsumgebung konkret aussieht kann ich leider nicht sagen. Nur 
so als Vergleich, bei Visual Studio sieht die Dokumentation dazu so aus:
http://msdn.microsoft.com/en-us/library/hhzbb5c8%28v=vs.100%29.aspx

Gruß
Reinhard
Gast #2631623
Lesenswert?

Claudio Hediger schrieb:
> Es wird in den Comments auf folgendes hingwiesen:
> /* Tip: To avoid modifying this file each time you need to use different HSE, 
you
>         can define the HSE value in your toolchain compiler preprocessor. */


Das heißt soviel wie:
Du kannst die Headerdatei in Ruhe lassen.

das HSE_VALUE gehört in den Compileroptionen definiert. Bei Atollic bspw 
ist das unter
Project -> Properties
C/C++ General -> Paths And Symbols -> Symbols

dort ein neues Symbol anlegen das HSE_VALUE heisst und den Wert 8000000 
hat, für alle Konfigurationen (Debug, Release,...)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren