Forum: Mikrocontroller und Digitale Elektronik STM32F4 Probleme mit USART


von Johannes J. (jhne92)


Lesenswert?

Ich möchte Daten zws. STM32F429 DiscoveryBoard und USB TLL Adapter 
austauschen.
Hierfür verwende ich USART3 (C10/c11) vom STM
1
#include "stm32f4xx.h"
2
#include "stm32f4xx_usart.h"
3
#include "stm32f4xx_gpio.h"
4
#include "stm32f4xx_rcc.h"
5
#define STDIN_FILENO 2
6
void IO_Initialize(void) {
7
  
8
  RCC->AHB1ENR  |= (1UL << 6);
9
  
10
  GPIOG->MODER  &= 0x00000000;
11
  GPIOG->MODER  |= 0x55555555;
12
  GPIOG->OTYPER &= 0x0000;
13
  GPIOG->PUPDR  &= 0x00000000;
14
  GPIOG->OSPEEDR|= 0xFFFFFFFF;  
15
  
16
  /*BTN*/
17
  GPIOA->MODER    &= ~((3UL << 2*0)  );      /* PA.0 is input                 */
18
  GPIOA->OSPEEDR  &= ~((3UL << 2*0)  );      /* PA.0 is 50MHz Fast Speed      */
19
  GPIOA->OSPEEDR  |=  ((2UL << 2*0)  ); 
20
  GPIOA->PUPDR    &= ~((3UL << 2*0)  );      /* PA.0 is no Pull up            */
21
}
22
23
void Usart3Init(void){
24
25
   GPIO_InitTypeDef GPIO_InitStructure;
26
27
   USART_InitTypeDef USART_InitStructure;
28
29
   USART_InitStructure.USART_BaudRate = 19200;
30
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
31
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
32
   USART_InitStructure.USART_Parity = USART_Parity_No;
33
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
34
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
35
36
   //   GPIO_InitTypeDef GPIO_InitStructure;
37
38
   //configure clock for USART
39
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
40
    //configure clock for GPIO
41
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
42
    //configure AF
43
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3);
44
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3);
45
46
    //configure ports, &GPIO_InitStructure);
47
48
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
49
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
50
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
51
52
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
53
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
54
    GPIO_Init(GPIOC, &GPIO_InitStructure);
55
56
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
57
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
58
    GPIO_Init(GPIOC, &GPIO_InitStructure);
59
60
    USART_Init(USART3, &USART_InitStructure);
61
62
     /* Enable USART */
63
     USART_Cmd(USART3, ENABLE);
64
}
65
66
void SendUart (uint8_t byte) {
67
  while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);  
68
  USART_SendData(USART3, byte);    
69
}
70
71
int main() {
72
  uint8_t test=0;
73
  //Initialisierung
74
  IO_Initialize();
75
  Usart3Init();
76
  
77
  SendUart(10001101);
78
}

Wenn ich folgende 8-Bits sende, kommt das in den Klammern am Laptop an:
00 00 00 00 = (00 00 00 00)
10 00 00 01 = (10 00 00 01)
11 10 00 01 = (01 10 00 01) -> erster Fehler
11 00 11 00 = (00 00 11 00) -> zweiter Fehler

Woran kann das liegen?

von le compileur (Gast)


Lesenswert?

Woher weiss der Compiler, ob er eine Dezimalzahl oder Dualzahl 
vorfindet?
> SendUart(10001101);
:-*

von Johannes (Gast)


Lesenswert?

le compileur schrieb:
> :-*

Meinst du der Compiler erkennt die 8 Zahlen nicht als Bits?
Sollte ich statt dessen senden: SendUart(141);

Hätte gedacht das kann der C Compiler...müsste man dann noch was vor die 
8 Bits schreiben, wenn man wirklich "Bits" schreiben möchte?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
> Meinst du der Compiler erkennt die 8 Zahlen nicht als Bits?

Nö, wie denn? 10001101 ist erstmal die Zahl 
Zehnmillioneneintausendeinhundertundeins.

Für Zahlenformate kannst Du außer der Dezimalsystemschreibweise:

    0123      führende Null -> Oktahlzahl
    0x1234    führendes 0x  -> Hexadezimalzahl

verwenden.

Für den gcc wurde mal die Erweiterung

    0b010101   führendes 0b -> Dualzahl

eingebaut. Soviel ich weiß, ist das aber kein Standard.

> Sollte ich statt dessen senden: SendUart(141);

Ja. Oder halt 0b10001101

> Hätte gedacht das kann der C Compiler...

Ist er ein Hellseher? Wie soll ich denn dann 
Zehnmillioneneintausendeinhundertundeins schreiben?

> müsste man dann noch was vor die
> 8 Bits schreiben, wenn man wirklich "Bits" schreiben möchte?

Ja, siehe oben.

Ich empfehle Dir die Lektüre eines guten C-Buchs. Du hast schon Lücken 
in den Grundlagen.

von Johannes (Gast)


Lesenswert?

Naja ein Hellseher müsste er ja nicht sein, ich gebe ihm 8 Zahlen für 
eine uint8_t

Da könnte man vermuten ich möchte Bits senden,
Aber habe ich jetzt verstanden.
Aber er hätte mir stattdessen wenigstens eine Warnung ausgeben können, 
dass er die Zahl Zehnmillioneneintausendeinhundertundeins nicht in eine 
uint8 schreiben kann;)


Vielen Dank für die Hilfe :)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
> Da könnte man vermuten ich möchte Bits senden,

Wenn ein Compiler "vermutet", dann ist man als Programmierer verratzt 
und verkauft. Es gibt klare Standards, die erklären, wie ein C-Compiler 
sich verhalten muss.

> Aber er hätte mir stattdessen wenigstens eine Warnung ausgeben können,
> dass er die Zahl Zehnmillioneneintausendeinhundertundeins nicht in eine
> uint8 schreiben kann;)

Er kann durchaus Zehnmillioneneintausendeinhundertundeins in ein uint8_t 
schreiben. Es werden dann nur die untersten 8 Bit der Zahl gespeichert.
Das ist so beabsichtigt und C-Standard. Ich sagte ja: Dir fehlen 
wichtige Grundlagen.

Eine Warnung erhältst Du aber beim gcc, wenn Du die Option -Wall 
benutzt:

   warning: large integer implicitly truncated to unsigned type

: Bearbeitet durch Moderator
von Johannes (Gast)


Lesenswert?

Ok jetzt habe ich es verstanden...

kannst du mir eine lektüre zu genau dem Thema Bits & Co empfehlen?
Ich denke mit normalen Grundlagenbüchern werde ich keine Freude haben.
Ich lerne seit 3 Semestern C und seit 2 C++ an der Hochschule.

Das mit den Bits war bisher das einzige was mir gefehlt hat.
Und auch hier war es denk nur ein Denkfehler.

Gibt es eine Seite die sich mit dem Thema Bits beschäftigt?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:

> Ich denke mit normalen Grundlagenbüchern werde ich keine Freude haben.
> Ich lerne seit 3 Semestern C und seit 2 C++ an der Hochschule.

Das heisst nichts. Es gibt Leute, die programmieren seit Jahren in C und 
lernen immer noch dazu.

> Das mit den Bits war bisher das einzige was mir gefehlt hat.

Das glaubst Du! Du wirst noch merken, dass Du tausende von Sachen noch 
nicht weisst. ;-)

> Gibt es eine Seite die sich mit dem Thema Bits beschäftigt?

Artikel Bitmanipulation wäre ein Anfang.

http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/006_c_operatoren_005.htm#mj8665462fba73385942e5ef4e23cddef6

http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/006_c_operatoren_005.htm#mjb9ea9c15a1d99fb02047978f41459bcd

http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/007_c_typumwandlung_001.htm#mj5c5e497ac2ab4367fe9df0ffd218cfca

http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/005_c_basisdatentypen_019.htm#mjb5d32a7c3c1c65c6a1658a8ab25ba0cb

Aber das ist nur ein Anriss der Thematik, die in Deinem kleinen 
"Problem" steckt.

Allgemein kann man natürlich immer das Standard-Werk

  Kernighan/ Ritchie "Programmieren in C" 2. Auflage

empfehlen - auch wenn das schon ein wenig angestaubt ist.

: Bearbeitet durch Moderator
von Christian J. (Gast)


Lesenswert?

Es gibt eine Seite im Nettz, die massenweise nützliche "Bit Routinen" 
und Makros bereit stellt, wie zb Spiegeln eines Bytes, rotieren über 64 
Bit usw. Habe mich nur leider danach tot gesucht die wieder zu finden.

>>Das heisst nichts. Es gibt Leute, die programmieren seit Jahren in C und
>>lernen immer noch dazu

Seit über 20 Jahren und trotzdem immer wieder was Neues :-)

von Johannes Jaeger (Gast)


Lesenswert?

Christian J. schrieb:
> Es gibt eine Seite im Nettz, die massenweise nützliche "Bit
> Routinen"
> und Makros bereit stellt, wie zb Spiegeln eines Bytes, rotieren über 64
> Bit usw. Habe mich nur leider danach tot gesucht die wieder zu finden.
>
>>>Das heisst nichts. Es gibt Leute, die programmieren seit Jahren in C und
>>>lernen immer noch dazu
>
> Seit über 20 Jahren und trotzdem immer wieder was Neues :-)

Ich hab ja noch lange Zeit in meinem Leben :D
Ich denke nur immer, Learning by Doing ist besser als sich 100 Bücher 
durchzulesen...

Wäre cool wenn jemand die Seite kennt und sie hier reinstellt.
Würde denk für Viele hilfreicht sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes Jaeger schrieb:
> Ich denke nur immer, Learning by Doing ist besser als sich 100 Bücher
> durchzulesen...

Das halte ich für einen Irrglauben. Die Grundlagen sollte man sich schon 
systematisch aneignen. Dann kann man ja auf die Spielwiese gehen. Aber 
solange die Grundlagen nicht sitzen, kannst Du das Potential (gerade bei 
C) überhaupt nicht voll nutzen. Die Zeit, die Du fürs Lernen verbringst, 
holst Du dann später locker wieder raus.

von fbi (Gast)


Lesenswert?

Johannes Jaeger schrieb:
> Wäre cool wenn jemand die Seite kennt und sie hier reinstellt.
Die hier?
https://graphics.stanford.edu/~seander/bithacks.html
http://bits.stephan-brumme.com/

von Johannes Jaeger (Gast)


Lesenswert?

Perfekt Vielen Dank!:)

von Klaus W. (mfgkw)


Lesenswert?

Johannes schrieb:
> Aber er hätte mir stattdessen wenigstens eine Warnung ausgeben können,
> dass er die Zahl Zehnmillioneneintausendeinhundertundeins nicht in eine
> uint8 schreiben kann;)

Wenn ich das kompiliere:
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <stdint.h>
4
5
6
void f( uint8_t i )
7
{
8
  printf( "%u\n", (unsigned)i );
9
}
10
11
12
int main( int nargs, char **args )
13
{
14
  f( 10010001 );
15
16
  return 0;
17
}

bekomme ich:
1
klwa4731@eso1188 ~ $ gcc t.c
2
t.c: In Funktion »main«:
3
t.c:14:3: Warnung: Große Ganzzahl implizit auf vorzeichenlosen Typen abgeschnitten [-Woverflow]
4
klwa4731@eso1188 ~ $ gcc -v
5
Es werden eingebaute Spezifikationen verwendet.
6
COLLECT_GCC=gcc
7
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
8
Ziel: x86_64-linux-gnu
9
Konfiguriert mit: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
10
Thread-Modell: posix
11
gcc-Version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 
12
klwa4731@eso1188 ~ $

von Johannes Jaeger (Gast)


Lesenswert?

Keil hatte mir glaub keine Warnung ausgespuckt.
Ich versuche es heute Abend nochmal.

von le compileur (Gast)


Lesenswert?

Johannes schrieb:
> Ich denke mit normalen Grundlagenbüchern werde ich keine Freude haben.
> Ich lerne seit 3 Semestern C und seit 2 C++ an der Hochschule.

Du solltest an der Vorlesung und den Seminaren teilnehmen. Die 5 
Semester im Bistro schaffen keine Grundlagen.

Und wenn C++ zur Verfügung steht, solltest du es auch benutzen. Der 
schluckt auch C code, hat aber eine Typ Prüfung. Genau das, was du 
brauchst.

Johannes schrieb:
>
> Hätte gedacht das kann der C Compiler...müsste man dann noch was vor die
> 8 Bits schreiben, wenn man wirklich "Bits" schreiben möchte?

Und das ist Komedy vom Feinsten. :'(

von drama (Gast)


Lesenswert?

le compileur schrieb:
> Und wenn C++ zur Verfügung steht, solltest du es auch benutzen. Der
> schluckt auch C code, hat aber eine Typ Prüfung. Genau das, was du
> brauchst.

Jemandem der grundlegendes an C nicht verstanden hat, würde ich jetzt 
nicht unbedingt C++ andrehen. Das ist immerhin eine der komplexesten und 
verworrensten Programmiersprachen überhaupt. Da gibt es so viele 
Fallstricke, die kann man kaum noch zählen.

Und es ist auch recht kühn zu behaupten C hätte gar keine Typsicherheit. 
Grundlegende Typsicherheit gibt es doch. Darüber hinaus warnen viele 
Compiler vor gefährlich anmutenden Konstrukten.

Also wie auch immer, meine Empfehlung lautet: erstmal richtig C lernen. 
:)

von le compileur (Gast)


Lesenswert?

@drama
D e r  C++  C o p i l e r  ü b e r s e t z t  a u c h  C  c o d e. Und 
er hat eine T y p e p r ü f u n g.

Bei C++ kommt man auch nicht auf die Idee, dass der Compiler was 
schätzt. ;-)

von drama (Gast)


Lesenswert?

le compileur schrieb:
> D e r  C++  C o p i l e r  ü b e r s e t z t  a u c h  C  c o d e.

Leider nicht so richtig. Da gibt es eben doch einige elementare 
Unterschiede, die C-Code inkompatibel zu C++ machen können. Gerade wenn 
man auch die neueren C-Standards wie C99 und C11 einbezieht.

C-Code einfach so mit einem C++-Compiler zu übersetzen ist ein Hack.

von le compileur (Gast)


Lesenswert?

Du bist der Meister! :-)

@Joe
Übersetze seien erste Version mal mit C++. Du wirst es dann sehen.

von Jo (Gast)


Lesenswert?

Also ich werde jetzt mal mit C weitermachen ;)
Schlagt euch nicht die Köpfe ein ;)

Achja, im Bistro ware ich bisher nie während der Informatik Vorlesung ;)

von le compileur (Gast)


Lesenswert?

Jo schrieb:
> Also ich werde jetzt mal mit C weitermachen ;) Schlagt euch nicht
> die Köpfe ein ;)
>
> Achja, im Bistro ware ich bisher nie während der Informatik Vorlesung ;)

Ja, mach mit C weiter, aber lass den C code über den C++ Compiler 
laufen.
Es kann nur besser werden. ;-)

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.