Forum: Mikrocontroller und Digitale Elektronik STM32 USART sendet 3 anstatt 1 byte


von C. H. (hedie)


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
}

von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

Habe das Problem gefunden

jedoch nicht die Lösung dazu...

Der USART sendet kein Startbit (siehe Anhang)

Hat jemand eine Idee woran das liegen könnte?

Im Anhang hat der USART 0x01 gesendet.

von Helfer (Gast)


Lesenswert?

Claudio Hediger schrieb:
> Im Anhang hat der USART 0x01 gesendet.

Sieht für mich eher nach einem Startbit (low) und einem Datenbit (high) 
aus, gefolgt von etlichen weiteren 0-bits...

von Sascha W. (sascha-w)


Lesenswert?

so wie ich das sehe sendet der LSB-First, <3255> Startbit, <3255> Bit 0, 
<22765> Bit 1..7 (7*3255=22765)

Sascha

von Jan (Gast)


Lesenswert?

Hmm wie oft durchläufst du denn die while Schleife während das A einmal 
gesendet wurde?
Gibts ne Interrupt Routine fürs Transmit Buffer clear in deinem 
Programm?

mfg Jan

von C. H. (hedie)


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.

von C.H. (Gast)


Lesenswert?

Hat jemand noch eine Idee weshalb dass es mit meiner definition nicht 
geklappt hat?

Danke :)

von Reinhard R. (reinhardr)


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

von Reinhard R. (reinhardr)


Lesenswert?


von Phantomix (Gast)


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,...)

von C. H. (hedie)


Lesenswert?

Vielen Dank für eure Antworten :)

Da hab ich wieder was dazugelernt :)

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.