Hallo Leute,
ich versuche gerade mit dem USART meines STM32VL_Discovery Boards zu
arbeiten. Ich habe auch bereits des öfteren erfolgreich eine Verbindung
zum Computer aufbauen können, doch jetzt scheint irgendetwas nicht zu
stimmen. Ich habe ein Minimalprogramm geschrieben, welches ein Zeichen
vom Computer empfängt und schaut ob es sich bei dem Zeichen um eine 1
handelt. Falls ja, dann schickt der STM32 eine 2 an den Computer
zurueck. Das Problem ist, dass er nun immer ein flasches Zeichen
empfängt. Wenn ich eine 1 am Computer sende, dann empfängt das STM32 das
ASCii-Zeichen 103. Wenn ich dann einstelle, dass er ueberpruefen soll ob
es sich bei dem empfangenen Zeichen um eine 103 handelt, dann
funktioniert alles einwandfrei, nur das am Computer statt einer 2 ein ?
ankommt. Hier ist mein Quellcode:
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//Hardware flow control disabled (RTS and CTS signals)
63
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//Receive and transmit enabled
64
65
//Configure USART
66
USART_Init(USART2,&USART_InitStructure);
67
68
//Enable USART
69
USART_Cmd(USART2,ENABLE);
70
}
71
else
72
// If there is a failure, then return 2 to flash error led
73
return2;
74
75
// If it is all okay
76
return0;
77
}
Zur Verbindung mit dem Computer nutze ich uebrigens einen USB zu RS232
Converter von Digitus. Aber wie gesagt, dass hat alles schon mal
funktioniert. Ich bin leider fuer die nächsten Wochen nicht zu hause und
habe somit keinen Zugriff auf meine Programm zu hause (sonst wuerde ich
da nachschauen). Ich bin mir aber sicher das es so schonmal funktioniert
hat.
Am Computer nutze ich Tera Term Pro mit den entsprechenden Einstellungen
fuer die Baudrate etc.
Bastler schrieb:>>if(data == '1')> if(data == "1")
bockmist, das fragt ab ob das empfangene Byte gleich einem Pointer
ist, der in den Flash zeigt, an dem sich ein Byte mit 49 befindet. Der
Vergleich auf '1' war schon richtig, der mit 0x31 ist dasselbe.
Bastler schrieb:> USART_SendData(USART2, "2");
Hier gilt ebenfalls, das er wahrscheinlich keinen Pointer in den Flash
umherschicken will. '2' war richtig. Bitte C lernen...
Das Problem ist wohl eher in der UART-Konfiguration zu suchen. Also
Baudrate (kann die überhaupt von der Hardware produziert werden oder
wird da fröhlich gerundet??), Clock-Source (hoffentlich nicht RC-Osc).
Bevor ich dieses Programm getest habe und feststellen musste, dass ich
immernoch ein falsches Zeichen empfange, hatte ich noch eine weitere
Zeile eingefuegt, in welcher ich mir selbst die 1 sende. Dann habe ich
einen Kurzschlussstecker auf den USART2 gesteckt und siehe da es
funktionierte.
Jedes Mal wenn ich eine 1 am Computer sende kommt ein g an. Ich habe
gerade auch mal den direkten COM-Port des Computers ausprobiert,
allerdings mit dem gleichen Ergebnis
Werde ich nachher mal ausprobieren. Das witzige ist ja: Sende ich am PC
eine 1 und empfange die gleich wieder, so empfange ich eine 1. Sende ich
am mikroprozessor eine 1 und empfange die gleich wieder, dann empfange
ich eine 1. Sende ich aber vom Computer zum Mikroprozerssor oder vom
Mikroprozessor zum Computer, dann empfängt der Partner jeweils ein g.
Jens K. schrieb:> Werde ich nachher mal ausprobieren. Das witzige ist ja: Sende ich am PC> eine 1 und empfange die gleich wieder, so empfange ich eine 1. Sende ich> am mikroprozessor eine 1 und empfange die gleich wieder, dann empfange> ich eine 1. Sende ich aber vom Computer zum Mikroprozerssor oder vom> Mikroprozessor zum Computer, dann empfängt der Partner jeweils ein g.
Die Frage ist eher was für eine 1 du sendest ... dez oder ascii
Ich habe das Problem nun gelöst. Fuer alle die ebenfalls auf der Suche
nach einer Lösung sind, hier nun die Lösung:
Zur Festlegung der Baudrate hatte ich folgende Befehlzeile eingefuegt:
1
USART_InitStructure.USART_BaudRate=9600;
Diese Anweisung scheint sich auf einen System-Takt zu beziehen, welcher
sich irgendwo in den Tiefen irgendeines Header-Files befindet.
Nach endlosem Suchen auf unzähligen Seiten im Internet habe ich folgende
Anweisung gefunden:
1
USART1->BRR=(SystemCoreClock/9600);
Diese Anweisung bezieht sich auf den aktuellen tatsächlichen Systemtakt
und kann daher auch auf jedem STM32 genutzt werden, unabhängiog vom
System-Takt.
Also einfach obige Anweisung durch die andere ersetzen und es
funktioniert.
War ja klar dass es mal wieder an der Baudrate lag :-)
Jens K. schrieb:> USART1->BRR = (SystemCoreClock / 9600)
Die SystemCoreClock ist eine ordinäre globale C-Variable, die von dem
Clock Setup Code (der aus einem Excel-"Programm" aus generiert wird)
gesetzt wird, der zB in ST's Beispielcodes verwendet wird. Also wie zu
Beginn vermutet verkorkste Baudrate. So eine Zeile befindet sich auch in
den ST-Beispielcodes zum UART...
Diese Zeile funktioniert natürlich auch nur, wenn der UART direkt aus
dem Haupttakt versorgt wird; da die STM32 aber eine ganze Reihe von
Takten und variablen Prescalern haben, muss das gar nicht der Fall sein.
Dazu gibts ein schönes Diagramm im Reference Manual im Abschnitt "RCC".
Eine eigene Frage?
Dieser Thread ist über 13 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.