USART1 an STM32F411CEU

OP #7849428
Lesenswert?

Abend,

Gegeben:

1
void USART1_Init(void)
2
{
3
  RCC->APB2ENR |= (1<<4);
4
  RCC->AHB1ENR |= (1<<0);
5
  // GPIOA-> AFR[0] = (7<<8); // ? Angleichen an PA9
6
  GPIOA->AFR[0]  |=  (1U<<8);
7
  GPIOA->AFR[0]  |=  (1U<<9);
8
  GPIOA->AFR[0]  |=  (1U<<10);
9
  GPIOA->AFR[0]  &=   ~(1U<<11);
10
  
11
  GPIOA->MODER |= (1<<19);
12
  
13
  USART1->BRR = 0x0683;  // 9600 at 16MHz
14
  USART1->CR1 |= (1<<3);
15
  USART1->CR1 |= (1<<13);
16

17
}
18

19
void USART1_Write(int ch)
20
{
21
  while(!(USART1-> SR & (1<<7)));
22
  USART1->DR = (ch & 0xFF);
23
  
24
}

Dennoch erhalte ich kein Signal an TTL/USB-Adapter (Aufbau siehe Foto unten).

Mache ich etwas bei der Zuweisung der Alternativfunktionen zu Port A (PA9) falsch)?

Angehängte Dateien:
Beitrag #7849438 wurde von einem Moderator gelöscht.
OP #7849446
Lesenswert?

1
#include "stm32f4xx.h"
2

3
//
4
// sandipmaurya030@gmail.com for USART2 solution
5
//
6

7

8
void delayMS(int delay);
9
void USART1_Init(void);
10
void USART1_Write(int ch);
11

12

13
int main (void){
14
  
15
  USART1_Init();
16

17
  while(1){
18
    
19
    USART1_Write('H');
20
    USART1_Write('E');
21
    USART1_Write('L');
22
    USART1_Write('L');
23
    USART1_Write('O');
24
    USART1_Write('\n');
25
    delayMS(100);
26
    
27
  }
28
  
29
}
30

31
void USART1_Init(void)
32
{
33
  RCC->APB2ENR |= (1<<4);
34
  RCC->AHB1ENR |= (1<<0);
35
  GPIOA-> AFR[0] = (7<<8); // ? Angleichen an PA9
36
  // GPIOA->AFR[0]  |=  (1U<<8);
37
  // GPIOA->AFR[0]  |=  (1U<<9);
38
  // GPIOA->AFR[0]  |=  (1U<<10);
39
  // GPIOA->AFR[0]  &=   ~(1U<<11);
40
  
41
  GPIOA->MODER |= (1<<19);
42
  
43
  USART1->BRR = 0x0683;  // 9600 at 16MHz
44
  USART1->CR1 |= (1<<3);
45
  USART1->CR1 |= (1<<13);
46

47
}
48

49
void USART1_Write(int ch)
50
{
51
  while(!(USART1-> SR & (1<<7)));
52
  USART1->DR = (ch & 0xFF);
53
  
54
}
55

56

57
void delayMS(int delay)
58
{
59
  int i;
60
  for( ;delay>0; delay--)
61
     for(i= 0; i<=3195; i++);
62
  
63
  
64
}

Was könnte es sein, dass mein USB/TTL Adapter nix empfängt... Alternativfunktionen?

#7849504
Lesenswert?

Timbo schrieb:

Jedoch gerne "Input" zum Anschalten der einzelnen Bits gewünscht ...

Wie bereits erwähnt, so bitte nicht. Bitte!

Anbei ein Grundgerüst zum Programmieren mit dem Blackpill für das/die Cube IDE mit Verwendung der LL-Libraries.

  • Grundlegende Initialisierung des UART1
  • Testausgabe "Hello world..." (115200 Baud)
  • HEX-Datei direkt ausführbar
  • blinkende LED signalisiert Aktivität des Controllers
  • durch anklicken des *.ioc-Files startet CubeMX und kann das Ganze bequem erweitern und konfigurieren ohne das schon Geschriebene zu verlieren.
#7849512
Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:

Offensichtlich möchte Timbo seinen Mikrocontroller ohne HAL und ohne LL programmieren. Ich glaube, dass Tipps bezüglich dieser Bibliotheken ihm dabei wenig helfen.

Nach dem was sein gepostetes Bild stark vermuten lässt hat er ja noch einiges vor, nicht nur ein paar Zeichen auf UART ausgeben. Da wird er mit Bare Metal Programmierung nicht weit kommen bzw. sich sehr bald im Dschungel wiederfinden.

Früher oder später wird die Erkenntnis einkehren. Aber: wie sagt der Engländer so schön: cha­cun à son goût.

Gast #7849517
Lesenswert?

Wastl schrieb:

Da wird er mit Bare Metal Programmierung nicht weit kommen bzw. sich sehr bald im Dschungel wiederfinden.

Das mag sein. Für das Verständnis hilft es aber am Anfang, den Mikrocontroller mit möglichst wenig Abstraktion kennen zu lernen. Die LL ist da freilich viel näher dran, als HAL.

#7849519
Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:

Offensichtlich möchte Timbo seinen Mikrocontroller ohne HAL und ohne LL programmieren. Ich glaube, dass Tipps bezüglich dieser Bibliotheken ihm dabei wenig helfen.

Dann macht man es z. B. so (ist jetzt für einen G0xx, aber...):

1
#define GPIO_ALT(pin, alt, opendrain, speed, pupd) {                                                        \
2
    pin ## _GPIO_Port->OTYPER = (pin ## _GPIO_Port->OTYPER & ~(GPIO_OTYPER_OT0_Msk << (pin ## _Pin))) |     \
3
        ((opendrain ? GPIO_OTYPER_OT0_Msk : 0U) << (pin ## _Pin));                                          \
4
    pin ## _GPIO_Port->OSPEEDR = (pin ## _GPIO_Port->OSPEEDR &                                              \
5
        ~(GPIO_OSPEEDR_OSPEED0_Msk << (pin ## _Pin << 1))) | (GPIO_ ## speed << (pin ## _Pin << 1));        \
6
    pin ## _GPIO_Port->PUPDR = (pin ## _GPIO_Port->PUPDR & ~(GPIO_PUPDR_PUPD0_Msk << (pin ## _Pin << 1))) | \
7
        (GPIO_ ## pupd << (pin ## _Pin << 1));                                                              \
8
    pin ## _GPIO_Port->AFR[pin ## _Pin >> 3] = (pin ## _GPIO_Port->AFR[pin ## _Pin >> 3] &                  \
9
        ~(0xFU << ((pin ## _Pin & 0x7U) << 2))) | (GPIO_ ## alt << ((pin ## _Pin & 0x7U) << 2));            \
10
    pin ## _GPIO_Port->MODER = (pin ## _GPIO_Port->MODER & ~(GPIO_MODE << (pin ## _Pin << 1))) |            \
11
        (MODE_AF << (pin ## _Pin << 1));                                                                    \
12
}

und verwendet das in etwa so:

1
#define MotCh1_Pin 8
2
#define MotCh1_GPIO_Port GPIOA
3

4
GPIO_ALT(MotCh1, AF2_TIM1, false, SPEED_FREQ_LOW, NOPULL);

Heißt: PA8 wird als Timer1-Ausgang, Push/Pull usw. konfiguriert. Alles in einem Rutsch in einer Zeile ... Die #defines von AF2_TIM1, GPIO_SPEED_FREQ_LOW, GPIO_NOPULL etc. finden sich in den Headern von ST, die man einfach vorher inkludiert.

#7849650
Lesenswert?

Man könnte als konzeptionellen Gegenentwurf auch auf die Verwendung von Registernamen verzichten und stattdessen direkt deren Adressen verwenden. Das hat den großen Vorteil, daß man keine Headerdatei mit diesen Registernamen einbinden muss ...

Das wäre jedenfalls konsequent.

1
void USART1_Init(void)
2
{
3
  *(0xdeadbeef) |= (1<<4);
4
  *(0xdeadfeed) |= (1<<0);
5
  *(0xfeedc0de)  |=  (1U<<8);
6
  *(0xfeedc0de)  |=  (1U<<9);
7
  *(0xfeedc0de)  |=  (1U<<10);
8
  *(0xfeedc0de)  &=   ~(1U<<11);  
9
  *(0xbeefbeef) |= (1<<19);
10
  *(0xdeafbeef) = 0x0683;  // 9600 at 16MHz
11
  *(0xfeedbeef) = (1<<3);
12
  *(0xfeedbeef) |= (1<<13);
13
}

Das ist knapp, hübsch und übersichtlich, meint Ihr nicht auch?

(Der interessanten Frage, warum teilweise eine vorzeichenlose und andererseits eine vorzeichenbehaftete 1 verschoben wird, der stellen wir uns ein andernmal)

#7849716
Lesenswert?

Bruno V. schrieb:

wer da keine fette Warnung bekommt ist entweder mit Assembler in den 70ern großgeworden oder hoffnungslos verloren ;-)

Issas so?

1
#include <stdint.h>
2
int main(void) {
3
    uint32_t *p = (uint32_t *)0xfeedbeef;
4
    *p |= 020010;
5
    return 0;
6
}
7
//  gcc -Wall -Wextra -pedantic -std=c11 -save-temps -c "x.c" (im Verzeichnis: /home/norbert/tmp)
8
//  Kompilierung erfolgreich beendet.

Bruno V. schrieb:

ist entweder mit Assembler in den 70ern großgeworden

Den kann ich nicht leugnen…

…und einen kleinen zusätzlichen cast weiter kann man sich den Pointer auch sparen…

#7849723
Lesenswert?

Ich mag lieber so etwas:

1
void main()
2
{
3
   printf("Hello\n");
4

5
   while(true) {
6
   };
7
}

Das Registergewusel läuft auf einer anderen Ebene ab, die Anwendung soll nur Anwendungscode enthalten. Alles andere ist im System und lässt sich besser testen und kann damit leicht für andere Targets verwendet werden. Ohne Codegenerator.

#7849768
Lesenswert?

Bruno V. schrieb:

Jeder andere hält 020010 für eine Hexadezimalzahl

Die Grundlagen der verwendeten Programmiersprache sollte man schon kennen, und so obskur sie auch sein mögen, Oktalzahlen sind nach wie vor nicht nur Sprachstandard, sondern sogar auf manchen Betriebssystemen elementar bei bestimmten Operationen.

Man betrachte nur mal den numerischen Wert, der auf *nixoiden Betriebssystemen für /chmod/ verwendet wird ...

Und nicht nur die kennen oktale Zahlen, o nein, das tut sogar Windows:

1
C:\>ping 010.010.010.010
2

3
Ping wird ausgeführt für 8.8.8.8 mit 32 Bytes Daten:
4
Antwort von 8.8.8.8: Bytes=32 Zeit=12ms TTL=60
5
Antwort von 8.8.8.8: Bytes=32 Zeit=19ms TTL=60

Aber nicht nur das:

1
 % ping 010.010.010.010
2
PING 010.010.010.010 (8.8.8.8): 56 data bytes
3
64 bytes from 8.8.8.8: icmp_seq=0 ttl=60 time=13.936 ms
4
64 bytes from 8.8.8.8: icmp_seq=1 ttl=60 time=17.907 ms
#7849888
Lesenswert?

Harald K. schrieb:

Oktalzahlen sind nach wie vor nicht nur Sprachstandard

Das werden sie aller Voraussicht auch bleiben, da es ja durchaus verbreitet war, z.B. bei Strings.

Heute kennt das kaum jemand. Und es ist meist (wie hier) unmöglich zu raten, ob es ein Versehen oder Expertise war. Darum war (ist?) es bei Misra eine "required" rule, Oktalzahlen nicht zu verwenden (außer 0 natürlich). Praktisch mit der Notwendigkeit, dass Compiler oder ein anderer statischer Regelchecker das prüft und warnt/Fehler wirft.

#7849894
Lesenswert?

Bruno V. schrieb:

Darum war (ist?) es bei Misra eine "required" rule, Oktalzahlen nicht zu verwenden

Ich finde es erschütternd, dass man schon völlig normale Dinge verbieten muss, nur weil sich der Kenntnisstand anscheinend immer weiter in südlicher Richtung bewegt und demnächst – nach Einführung und Benutzung von AI – wohl schon ein erster Erdaushub für's Niveau fällig wird.

#7849908
Lesenswert?

Harald K. schrieb:

Hmm. Interessante Frage, ist eine alleinstehende 0 eine Oktalzahl? Eine alleinstehende 1 ist keine, weil die führende Null fehlt, das könnte man der alleinstehenden 0 also auch nachsagen.

Eine oktale Zahl wird in /C/ durch eine führende 0 dargestellt, braucht also mindestens zwei Ziffern. Per Definition kann demnach eine einzelne 0 keine oktale Zahl sein. Nähme man die führende 0 weg, bliebe nichts mehr zur Auswertung übrig. In Python ist man da etwas klarer:

1
#!python
2
print(0b11111111,0o377,255,0xff)
3
255 255 255 255

Hier haben wir – zur Unterscheidung von einer dezimalen Zahl – jeweils ein 0b,0o,0x voran gestellt.

#7849918
Lesenswert?

Mittlerweile bereue ich alles was ich zu diesem Thread gegeben habe. Vielleicht ergeht es manchem von euch auch so, wenn ihr diesen Thread gelesen habt:

Beitrag "Softwareseitige Diskussion mit Evaluation einer Schrittmotoransteuerung - stm32f103c8t6"

und insbesondere

Beitrag "Re: Softwareseitige Diskussion mit Evaluation einer Schrittmotoransteuerung - stm32f103c8t6"

Auch lässt sich erkennen - falls der TO kein Berufs-Troll ist - dass er aus früheren Postings keinerlei Lernfähigkeit zeigt was die Programmierung / Programmier-Stil betrifft.

Übliches Troll-Verhalten ist ja auch, dass man - ausser dem Eröffnungs-Beitrag - wenig bis gar nichts mehr hört.

#7850312
Lesenswert?

Norbert schrieb:

Ich finde es erschütternd, dass man schon völlig normale Dinge verbieten muss, nur weil sich der Kenntnisstand anscheinend immer weiter in südlicher Richtung bewegt und demnächst – nach Einführung und Benutzung von AI – wohl schon ein erster Erdaushub für's Niveau fällig wird.

Oktalzahlen sind halt aus der Zeit gefallen und (ab 8 Bit) durch Hex verdrängt. In der Praxis entstehen sie oft bei der Überarbeitung von Zahlen im Blocksatz. So wie Trigraphen ja meist auch nicht mehr benutzt werden sondern irrtümlich in Text auftauchen. Ganz ehrlich: Ich kenne nicht mal alle Trigraphen auswendig.

#7850313
Lesenswert?

Harald K. schrieb:

Interessante Frage, ist eine alleinstehende 0 eine Oktalzahl?

Ja.

6.4.4.1 Integer constants

Eine Oktalzahl beginnt mit einer 0 und kann danach "Octal digit"s haben.

Eine Dezimalzahl beginnt mit einer "nonzero digit" und kann danach "digit"s haben.

Es ändert zwar nichts, aber die (notwendige) Definition ist so recht einfach.

(Und die Ausnahme bei Misra darum nötig)

#7850350
Lesenswert?

Bruno V. schrieb:

Oktalzahlen sind halt aus der Zeit gefallen und (ab 8 Bit) durch Hex verdrängt.

Ich will dir ja nicht zu nahe treten, aber das ist Realsatire, richtig?

Schon mal mit einem unixoiden Betriebssystem gearbeitet? Ich stelle mir gerade vor was passieren würde, wenn jemand verkündete: Oktal ist soooo 20. Jahrhundert, ab jetzt arbeiten zB. ›chmod‹ und Konsorten in nur noch in Hex.

Nun muss ich schon selber lachen.

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