Forum: Mikrocontroller und Digitale Elektronik STM32F03 > USART1 > keine Lebenszeichen


von Jan H. (janiiix3)


Lesenswert?

Nabend,

aktuell versuche ich eine Debug Möglichkeit über die USART1 von meinem 
STM32F030xx8 zu schaffen.

Leider bis jetzt ohne Erfolg. Mein UART <-> TTL Adapter funktioniert 
(habe ich getestet).

Wenn man die Taktquellen vom M0 nicht weiter berührt (sprich default), 
taktet er doch intern mit 8MHz oder?.

Habe ich was bei der Initalisierung vergessen?!.

Als Terminal benutze ich aktuell "TeraTerm".
1
  GPIOInitPort( GPIOA ); // Clock enabled
2
  GPIOInitPort( GPIOC );
3
  GPIOInitPort( GPIOB );
4
5
  GPIOSetOutputType( GPIOA, PIN_9, OUTPUT_PUSH_PULL );
6
  GPIOSelectPinMode( GPIOA, PIN_9, ALTFUNC ); // USART1_TX
7
8
  GPIOSetOutputType( GPIOA, PIN_10, INPUT );
9
  GPIOSelectPinMode( GPIOA, PIN_10, ALTFUNC ); // USART1_RX
10
11
  GPIOSelectAltFunc( GPIOA, PIN_9, GPIO_ALT_FUNC_1 );
12
  GPIOSelectAltFunc( GPIOA, PIN_10, GPIO_ALT_FUNC_1 );
13
14
 // Hier wird aktuell nur USARTx->BRR = 0x341UL @8MHz (9600) geschrieben
15
        USARTInit( USART1, USART_BAUDRATE_9600 );
16
17
// RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
18
        USARTClkOn( USART1 );
19
20
// pUsart->CR1 |= ( USART_CR1_UE | USART_CR1_RE | USART_CR1_TE );
21
        USARTEnable( USART1 );

von M. Н. (Gast)


Lesenswert?

Jan H. schrieb:
> USARTClkOn( USART1 );

Clock einschalten, bevor

Jan H. schrieb:
> USARTInit( USART1, USART_BAUDRATE_9600 );

Ohne Clock wird die Registerbank nicht getaktet.

Jan H. schrieb:
> GPIOSetOutputType( GPIOA, PIN_10, INPUT );

Kannst du dir sparen, wird durch die ALTFUC Einstellung eh 
zurückgesetzt.

von Jan H. (janiiix3)


Lesenswert?

M. H. schrieb:
> Jan H. schrieb:
>> USARTClkOn( USART1 );
>
> Clock einschalten, bevor
>
> Jan H. schrieb:
>> USARTInit( USART1, USART_BAUDRATE_9600 );
>
> Ohne Clock wird die Registerbank nicht getaktet.
>
> Jan H. schrieb:
>> GPIOSetOutputType( GPIOA, PIN_10, INPUT );
>
> Kannst du dir sparen, wird durch die ALTFUC Einstellung eh
> zurückgesetzt.

Das mit dem Takt macht Sinn, funktioniert aber immer noch nicht.
Und die config für den Input habe ich raus genommen.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Wenn man die Taktquellen vom M0 nicht weiter berührt (sprich default),
> taktet er doch intern mit 8MHz oder?.

Die L0 Serie taktet per default mit 2 MHz. Wie es bei der F0 Serie ist, 
weiß ich nicht. Steht das nicht in deinem Referenzhandbuch?

> Leider bis jetzt ohne Erfolg.
> funktioniert aber immer noch nicht.

Woran machst du das fest? Ich sehe keinen Code, wo du etwas sendest. DU 
musst schon mehr zeigen - viel mehr. Auch den Schaltplan und welches 
Board du verwendest.

Ich würde erstmal LED an die beiden Pins anschließen und blinken lassen. 
Danach kannst du sie mal seriell benutzen, aber mit niedriger Baudrate 
denn dann kannst du die LED blinken sehen.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>> Wenn man die Taktquellen vom M0 nicht weiter berührt (sprich default),
>> taktet er doch intern mit 8MHz oder?.
>
> Die L0 Serie taktet per default mit 2 MHz. Wie es bei der F0 Serie ist,
> weiß ich nicht. Steht das nicht in deinem Referenzhandbuch?
>
Also laut Datenblatt lese ich 8Mhz raus.

>> Leider bis jetzt ohne Erfolg.
>
> Woran machst du das fest? Ich sehe keinen Code, wo du etwas sendest. DU
> musst schon mehr zeigen - viel mehr. Auch den Schaltplan und welches
> Board du verwendest.

Ich verwende das STM32F030-Discovery.

Gesendet wird hiermit:
1
void         USARTSendData( USART_TypeDef *pUsart , uint8_t uiTx )
2
{
3
    while(!(pUsart->CR1 & USART_ISR_TXE));
4
    pUsart->TDR = uiTx;
5
}

Wenn ich hier den ganzen Code rein haue wird es zu unübersichtlich..

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich würde erstmal LED an die beiden Pins anschließen und blinken lassen.
> Danach kannst du sie mal seriell benutzen, aber mit niedriger Baudrate
> denn dann kannst du die LED blinken sehen.

Das Oszi. zeigt mir keinerlei Bewegung an.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Also laut Datenblatt lese ich 8Mhz raus.

Ich auch

Jan H. schrieb:
> Wenn ich hier den ganzen Code rein haue wird es zu unübersichtlich..

Du kannst die Dateien anhängen, gerne auch als ZIP.

Solange du weder den relevanten Code noch die Schaltung zeigst, können 
wir nur dumm herum raten. Das führt zu unnötigem Frust.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>
>> Also laut Datenblatt lese ich 8Mhz raus.
>
> Ich auch
> Jan H. schrieb:
>
>> Wenn ich hier den ganzen Code rein haue wird es zu unübersichtlich..
>
> Du kannst die Dateien anhängen, gerne auch als ZIP.
> Solange du weder den relevanten Code noch die Schaltung zeigst, können
> wir nur dumm herum raten. Das führt zu unnötigem Frust.

Ja das stimmt.
Leider habe ich aktuell nicht die Möglichkeit eine ZIP zu erstellen.

https://www.dropbox.com/sh/bmcwesnp0qkhwu6/AABg2HfZRNAyKzky1DSJCTrZa?dl=0

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Leider habe ich aktuell nicht die Möglichkeit eine ZIP zu erstellen.

????????

Wenn dir gar nichts besseres einfällt, dann klicke mal in deiner Dropbox 
auf "Herunterladen" und staune, was dann passiert.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>
>> Leider habe ich aktuell nicht die Möglichkeit eine ZIP zu erstellen.
>
> ????????
> Wenn dir gar nichts besseres einfällt, dann klicke mal in deiner Dropbox
> auf "Herunterladen" und staune, was dann passiert.

Das gab es mal.. Jetzt muss man auf Premium Upgraden.. Diese Option mit 
dem Download habe ich in der App nicht mehr.

von Stefan F. (Gast)


Lesenswert?

1
void USARTSendData( USART_TypeDef *pUsart , uint8_t uiTx )
2
{
3
    while(!(pUsart->CR1 & USART_ISR_TXE));
4
    pUsart->TDR = uiTx;
5
}

Hier fragst du das Register USART->CR1 ab, benutzt aber eine Bitmaske 
die zum USART->ISR Register gehört. Die Maske hat den Wert 0x80, damit 
fragst du also effektiv das Bit "TXEIE: interrupt enable" ab.

Du willst da doch abfragen, ob der Sende-Puffer frei ist. Dazu musst du 
schreiben:
1
while(!(pUsart->ISR & USART_ISR_TXE));

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Jan H. schrieb:
> Das gab es mal.. Jetzt muss man auf Premium Upgraden.. Diese Option mit
> dem Download habe ich in der App nicht mehr.

Warum sehe ich das dann? Ich habe überhaupt keinen Dropbox Account und 
auch keine App.

Und warum kannst du kein ZIP erstellen? Das kann doch jedes 
Linux/Windows im ganz normalen Dateimanager.

von Stefan F. (Gast)


Lesenswert?

Wenn du das Programm Zeile für Zeile im Debugger ausführen würdest, dann 
würdest du auch sehen, dass es in der while Schleife festhängt.

Oder einfach starten und dann auf pause klicken. Auch dann wird es auch 
in der while Schleife stehen.

Bevor du dich noch weiter mit Register befasst scheint es besser zu 
sein, du übst erst einmal, deine Arbeitsmittel zu benutzen.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>
>> Das gab es mal.. Jetzt muss man auf Premium Upgraden.. Diese Option mit
>> dem Download habe ich in der App nicht mehr.
>
> Warum sehe ich das dann? Ich habe überhaupt keinen Dropbox Account und
> auch keine App.
> Und warum kannst du kein ZIP erstellen? Das kann doch jedes
> Linux/Windows im ganz normalen Dateimanager.

Ja ich bin aktuell unterwegs und habe nur dad Handy. Über den Browser 
geht es nach wie vor. Habe ich auch gerade gemerkt.
Es funktioniere auch mal über die App, diese Funktion ist aber Anscheind 
jetzt kostenpflichtig geworden.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Oder einfach starten und dann auf pause klicken. Auch dann wird es auch
> in der while Schleife stehen.

Muss ich mal schauen.
Was heißt denn stehen? Ruft er die sende Routine gar nicht auf?
Schaue ich mir morgen mal mit dem Debugger an.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Ja ich bin aktuell unterwegs und habe nur dad Handy.

Ach so. Interessante arbeitsweise. Ich war davon ausgegangen, dass du 
vorm Rechner sitzt. Naja, meine Kinder machen auch viel mehr mobil, als 
ich.

Jan H. schrieb:
> Was heißt denn stehen? Ruft er die sende Routine gar nicht auf?

Er führt die while Schleife immer wieder endlos oft aus

> while(!(pUsart->CR1 & USART_ISR_TXE));

weil das (falsche) Bit niemals auf 1 geht. Die Zeile darunter, wird 
daher niemals ausgeführt:

> pUsart->TDR = uiTx;

Und dann ist auch klar, warum sich an der txD Leitung nichts tut.

> Muss ich mal schauen.

Mache das. Der Debugger ist sehr nützlich. Ein paar Hinweise dazu:
http://stefanfrings.de/stm32/cube_ide.html
http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf#page=27

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>
>> Ja ich bin aktuell unterwegs und habe nur dad Handy.
>
> Ach so. Interessante arbeitsweise. Ich war davon ausgegangen, dass du
> vorm Rechner sitzt. Naja, meine Kinder machen auch viel mehr mobil, als
> ich.
> Jan H. schrieb:
>
>> Was heißt denn stehen? Ruft er die sende Routine gar nicht auf?
>
> Er führt die while Schleife immer wieder endlos oft aus
>> while(!(pUsart->CR1 & USART_ISR_TXE));
>
> weil das (falsche) Bit niemals auf 1 geht. Die Zeile darunter, wird
> daher niemals ausgeführt:
>> pUsart->TDR = uiTx;
>
> Und dann ist auch klar, warum sich an der txD Leitung nichts tut.
>> Muss ich mal schauen.
>
> Mache das. Der Debugger ist sehr nützlich. Ein paar Hinweise dazu:
> http://stefanfrings.de/stm32/cube_ide.html
> 
http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf#page=27

Ich habe die Abfrage des Registers geändert, wie von Dir weiter oben 
angemerkt.

Laut Debugger beschreibt er das Daten Register auch mit dem richtigen 
Wert.
Habe vorsichtshalber mal ein paar mehr Zeichen gesendet.

Es passiert leider nach wie vor nichts am TxD.
Als wenn er keinen Takt hätte...
Aber wenn die Peripherie keinen Takt hat, können die Register ja auch 
nicht beschrieben werden bzw. arbeiten nicht richtig..

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Aber wenn die Peripherie keinen Takt hat, können die Register ja auch
> nicht beschrieben werden bzw. arbeiten nicht richtig..

Das denke ich auch. Vor allem könntest du dann maximal 2 bytes ausgeben, 
danach ist Schluss, weil das Sende-Register niemals leer wird.

Gehe nochmal einen Schritt zurück und lasse eine LED an dem Pin blinken. 
Kontrolliere damit auch das Oszilloskop, damit die sicher bist, dass die 
Verkabelung OK ist.

von Jan H. (janiiix3)


Lesenswert?

Muss man denn den entsprechenden GPIOs die diese alternative Funktion 
unterstützen noch weiter konfigurieren, sprich z.B den Ausgangs Type?

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Muss man denn den entsprechenden GPIOs die diese alternative Funktion
> unterstützen noch weiter konfigurieren, sprich z.B den Ausgangs Type?

Das hats du doch schon gemacht, laut Eröffnungsbeitrag.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>> Muss man denn den entsprechenden GPIOs die diese alternative Funktion
>> unterstützen noch weiter konfigurieren, sprich z.B den Ausgangs Type?
>
> Das hats du doch schon gemacht, laut Eröffnungsbeitrag.

Ja das weiß ich selber. Die Frage war ja auch ob man das machen MUSS.

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Ja das weiß ich selber. Die Frage war ja auch ob man das machen MUSS.

Dir schon jemand eiter oben geschrieben, dass en unnötig ist.

Wenn du dennoch unsicher bist, probiere es aus oder gehe ein Tutorial 
zum Thema durch. Zum Beispiel das vom professor Latorre: 
http://www.pomad.fr/node/13

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>> Ja das weiß ich selber. Die Frage war ja auch ob man das machen MUSS.
>
> Dir schon jemand eiter oben geschrieben, dass en unnötig ist.
>
> Wenn du dennoch unsicher bist, probiere es aus oder gehe ein Tutorial
> zum Thema durch. Zum Beispiel das vom professor Latorre:
> http://www.pomad.fr/node/13

Ja okay.
Also den Tx Pin kann ich toggeln. Nur funktioniert nach wie vor der 
USART nicht warum auch immer..

von Jan H. (janiiix3)


Lesenswert?

Fehler gefunden und behoben.
Danke!

von Stefan F. (Gast)


Lesenswert?

Jan H. schrieb:
> Fehler gefunden und behoben.
> Danke!

Stopp, nicht so schnell! Nachdem wir dir geholfen haben solltest du uns 
wenigstens berichten, was der Knackpunkt war.

von Jan H. (janiiix3)


Lesenswert?

Stefan ⛄ F. schrieb:
> Jan H. schrieb:
>> Fehler gefunden und behoben.
>> Danke!
>
> Stopp, nicht so schnell! Nachdem wir dir geholfen haben solltest du uns
> wenigstens berichten, was der Knackpunkt war.

Na gut..
Also ich habe in meiner GPIOxx Lib einen kleinen Fehler in einer if 
Abfrage gehabt.
1
GPIO_RETURN_CODE_t   GPIOSelectAltFunc( GPIO_TypeDef *pPort , GPIO_PIN_NUMBER_t ePin, GPIO_ALT_FUNC_t eAltFunc )
2
{
3
  uint8_t uiPin;
4
5
  if ( GPIOVerifyPort( pPort ) != PORT_OK )
6
  {
7
    return PORT_UNKNOWN;
8
  }
9
10
  if ( GPIOVerifyPin( ePin ) != PIN_OK )
11
  {
12
    return PIN_UNKNOWN;
13
  }
14
15
  if ( eAltFunc >= __GPIO_ALT_FUNC_MAX__ )
16
  {
17
    return ALT_FUNC_UNKNOWN;
18
  }
19
20
  
21
  if ( ( GPIO_ALT_FUNC_t ) ePin <= GPIO_ALT_FUNC_7 )
22
  {
23
    pPort->AFR[0] &= ~( 0x0F << ( ePin * 4 ) );
24
    pPort->AFR[0] |= ( eAltFunc << ( ePin * 4 ) );
25
  }
26
  else if ( (GPIO_ALT_FUNC_t) ePin > GPIO_ALT_FUNC_7 )
27
  {
28
    uiPin = ePin - GPIO_ALT_FUNC_8;
29
    pPort->AFR[1] &= ~( 0x0F << ( uiPin  * 4 ) );
30
    pPort->AFR[1] |= ( eAltFunc << ( uiPin  * 4 ) );
31
  }
32
33
  return ALT_FUNC_OK;
34
}

Nachdem ich mir die Register mit dem Debugger mal genauer angeschaut 
habe, ist mir aufgefallen das er die alternativen Funktionen nicht 
wirklich an die richtige Stelle im Register schreibt da hier eine kleine 
Berechnung falsch war..
1
  if ( eAltFunc <= GPIO_ALT_FUNC_7 ) // eAltFunc ist hier falsch
2
  {
3
    pPort->AFR[0] &= ~( 0x0F << ( ePin * 4 ) );
4
    pPort->AFR[0] |= ( eAltFunc << ( ePin * 4 ) );
5
  }
6
  else if ( eAltFunc > GPIO_ALT_FUNC_7 ) // und hier auch..
7
  {
8
    uiPin = ePin - GPIO_ALT_FUNC_8;
9
    pPort->AFR[1] &= ~( 0x0F << ( uiPin  * 4 ) );
10
    pPort->AFR[1] |= ( eAltFunc << ( uiPin  * 4 ) );
11
  }

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.