STM32 USART muss künstlich verlangsamt werden?

OP #4725384
Guten Abend,

ich arbeite mich gerade in den USART des STM32F103 ein. Übertragung von 
Daten funktioniert soweit, allerdings bin ich auf etwas seltsames 
Verhalten gestoßen. Und zwar zeigt mir mein Terminal Window (ich benutze 
das von Atmel Studio) nur die zu erwartenden Wörter an, wenn ich nach 
jedem übertragenen Zeichen einen Delay einlege, fällt der Weg, zeigt das 
Terminal nur noch bruchstückhafte Zeichen an. Das hier ist meine 
USART-Initialisierung:
1
void initUART(){
2
  RCC->APB2ENR |= (1<<2); //Port A clock enable
3

4
  GPIOA->CRH |= (0xB << 4); //Pin A9 as Alternative PP & 50MHz Output mode
5

6
  RCC->APB2ENR |= (1<<14); //USART1 Clock enable
7

8
  USART1->CR1 |= (1<<13); //Enable UART
9
  USART1->BRR = 72000000 / 14400; //72MHZ / 14400 BAUD
10
  USART1->CR1 |= (1<<3); //Enable Transmitter
11
}

So sehen die Funktionen zum Senden von Zeichen aus:
1
void sendChar(char c){
2
  while(USART1->SR & (0<<7)){ //Wait until data is transferred to shift register
3
    ;
4
  }
5
  USART1->DR = c;
6
  while(USART1->SR & (0<<6)){ //Wait until transmission is complete
7
    ;
8
  }
9
  delay(4500); //dieses Delay!
10
}
11

12
void sendString(const char *str){
13
  while(*str){
14
    sendChar(*str++);
15
  }
16
}

Hier findet sich auch das eben genannte Delay wieder. Die Funktion dazu 
sieht so aus:
1
void delay(long cycles){
2
  while(cycles > 0)
3
    cycles--;
4
}

So wird beispielsweise ein String gesendet:
1
char buffer[50];
2
uint32_t adcVal = getADCTempValue(16);
3
itoa((int)adcVal,buffer,10);
4
sendString(buffer);

Ich benutze 1 Start bit und 8 Datenbits, parity control ist deaktiviert. 
Ich bin für jeden Tipp dankbar!
Max M. schrieb:
> while(USART1->SR & (0<<7)){ //Wait until data is transferred to shift
> register
>     ;
>   }
>   USART1->DR = c;
>   while(USART1->SR & (0<<6)){ //Wait until transmission is complete
>     ;
>   }

Hallo!

Das sollte wohl jeweils (1<<6) oder (1<<7) sein, eine Null schieben 
bleibt ja Null (ich hab die Registerdefinitionen nicht überprüft).

Heiko
OP
Heiko G. schrieb:
> Das sollte wohl jeweils (1<<6) oder (1<<7) sein, eine Null schieben
> bleibt ja Null (ich hab die Registerdefinitionen nicht überprüft).

Ich überprüfe dort den Zustand des Bits, zum Beispiel würde der Zustand 
0 des 6. Bits im SR-Register "Data is not transferred to shift 
register" entsprechen (das bedeutet für mich: Das Bit steckt noch fest, 
jetzt kann ich noch kein weiteres Datenpaket ins DR-Register laden). Ich 
hätte natürlich auch schreiben können:
1
while(!(USART1->SR & (1<<6)){
2
}

Das dürfte sich doch gleich bleiben, oder?

Edit: Okay, das ist nicht egal. Kam mir auch gerade beim überlegen.
Es funktioniert jetzt, danke Heiko für die schnelle Lösung!
Gast
>Das dürfte sich doch gleich bleiben, oder?

Nein.

>   while(USART1->SR & (0<<6)){ //Wait until transmission is complete

0 << 6 ist 0.
USART1->SR & 0 ist 0.

Die Schleife wird abgebrochen bevor alle Bits gesendet wurden.
Nur das Delay sorgt noch dafür das korrekt gesendet wird.
(Firma: matzetronics)
Max M. schrieb:
> Das dürfte sich doch gleich bleiben, oder?

Nö. Du musst trotzdem mit (1 << 6) die Maske bilden, die dann verundet 
wird mit dem Register.
Eine Maske aus (0 << 6) ist immer null - der verundete Ausdruck wird 
immer null sein.

Max M. schrieb:
> while(!(USART1->SR & (1<<6)){
> }

Das hingegen funktioniert wie erwartet. Wenn Bit 6 im USART0->SR 
Register  null ist, wird die Klammer wahr.
Hallo!

Das ist nicht dasselbe, (0<<6) ist immer noch 0 (alle Bits auf 0), damit 
maskiert das 'Und' alle Bits weg, und die while-Schleifen werden gar 
nicht erst ausgeführt. Die Lösung mit dem !-Not sollte aber richtig 
sein.

Heiko

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.