STM32 USART muss künstlich verlangsamt werden?

OP #4725384
Lesenswert?

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!
#4725393
Lesenswert?

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 #4725401
Lesenswert?

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 #4725411
Lesenswert?

>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) #4725412
Lesenswert?

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.

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