Hallo,
ich arbeite normalerweise nur mit den Atmel-CPUs, und komme mit denen
auch perfekt zurecht. Nun muss ich ein Projekt mit dem STM32 machen. Ich
nutze EMBitz mit CubeMX und CMSIS.
Ich habe das Problem bei der Uart. Ich möchte Uart einbinden mit RX
Interrupt.
1
voidMX_USART_UART_Init(void)
2
{
3
wifi_uart.Instance=USED_UART;
4
wifi_uart.Init.BaudRate=128000;
5
wifi_uart.Init.WordLength=UART_WORDLENGTH_8B;
6
wifi_uart.Init.StopBits=UART_STOPBITS_1;
7
wifi_uart.Init.Parity=UART_PARITY_NONE;
8
wifi_uart.Init.Mode=UART_MODE_TX_RX;
9
wifi_uart.Init.HwFlowCtl=UART_HWCONTROL_NONE;
10
wifi_uart.Init.OverSampling=UART_OVERSAMPLING_16;
11
12
USART_ITConfig(USED_UART,USART_IT_RXNE,ENABLE);//USART_IT_RXNE unknown?! Need for the parse wifi sub, optionally make in main loop
13
NVIC_EnableIRQ(USED_UART_IRQ);
14
15
HAL_UART_Init(&wifi_uart);
16
}
Das ist der Init code (so wie ich das verstanden habe, sollte das uart
init sein mit interrupt rx).
Das Problem ist, der findet "USART_IT_RXNE" nicht. Er sagt es ist nicht
definiert, genauso wie "USART_FLAG_TC" und "USART_FLAG_RXNE".
Ich verstehe nicht, was ich da falsch mache, oder ob mir da (und wenn ja
welche) eine Library fehlt.
Die letzten beiden Flags sind wenn ich bspw. was senden/empfangen will,
dann frage ich ab ob das Bit gesetzt ist oder nicht.
Des Weitern möchte ich einen einfachen Timer mit ISR Interrupt haben.
Hier verstehe ich allerdings 0 wie ich diesen initialisiere und welche
ISR Routine ich nehmen muss. Ich wollte einfach einen Timer der jede ms
einen Interrupt erzeugt.
1
voidMX_TIM1_Init(void)
2
{
3
TIM_SlaveConfigTypeDefsSlaveConfig;
4
TIM_MasterConfigTypeDefsMasterConfig;
5
6
htim1.Instance=TIM1;
7
htim1.Init.Prescaler=0;
8
htim1.Init.CounterMode=TIM_COUNTERMODE_UP;
9
htim1.Init.Period=1749;
10
htim1.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
11
htim1.Init.RepetitionCounter=0;
12
HAL_TIM_Base_Init(&htim1);
13
14
HAL_TIM_Base_Start_IT(&htim1.Instance);
15
HAL_NVIC_SetPriority(TIM1_IRQn,0,0);
16
HAL_NVIC_EnableIRQ(TIM1_IRQn);
17
HAL_TIM_IRQHandler(&Thtim1.Instance);
18
}
Das habe ich dazu genutzt. Klappt das so? Oder ist das falsch? Wie
lautet die ISR Routine, in die er springen muss? Soll einfach ein Timer
im Interrupt sein, welcher jede ms einen Interrupt erzeugt (compare),
also wenn er die periode erreicht hat. Getaktet vom Systemclock mit
ensprechendem Prescaler.
Marius D. schrieb:> Ich verstehe nicht, was ich da falsch mache, oder ob mir da (und wenn ja> welche) eine Library fehlt.
Nein. Eine Library (*.a oder *.lib) fehlt da nicht; da fehlt eine
Include-Datei (*.h), oder es sind bestimmte Symbole nicht definiert, die
vor dem Einbinden der Include-Datei definiert sein müssen.
Es gibt Systeme, bei denen der verwendete Prozessortyp per #define oder
Compilerargument festgelegt werden muss, damit aus einer generischen
Include-Datei die für diesen Prozessortyp nötigen Definitionen verwendet
werden.
Du kannst selbst herausfinden, welche Include-Datei fehlt - mit einer
Volltextsuche über alle Include-Dateien nach dem angekreideten Namen,
also z.B. USART_IT_RXNE.
Rufus Τ. F. schrieb:> Marius D. schrieb:>> Ich verstehe nicht, was ich da falsch mache, oder ob mir da (und wenn ja>> welche) eine Library fehlt.>> Nein. Eine Library (*.a oder *.lib) fehlt da nicht; da fehlt eine> Include-Datei (*.h), oder es sind bestimmte Symbole nicht definiert, die> vor dem Einbinden der Include-Datei definiert sein müssen.>> Es gibt Systeme, bei denen der verwendete Prozessortyp per #define oder> Compilerargument festgelegt werden muss, damit aus einer generischen> Include-Datei die für diesen Prozessortyp nötigen Definitionen verwendet> werden.>> Du kannst selbst herausfinden, welche Include-Datei fehlt - mit einer> Volltextsuche über alle Include-Dateien nach dem angekreideten Namen,> also z.B. USART_IT_RXNE.
Es war schon klar, dass eine .h oder .c fehlt.
Wie soll ich das denn herausfinden, ich habe ALLE Dateien, welche die
.ioc erzeugt hat, dort ins Projekt implementiert. Die .ioc hänge ich
gleich an.
Wenn ich es in den Dateien finden sollte, dann wäre ja das Problem nicht
da.
Hat jmd. vll diese Dateien?
Ist der Code für die Uart den an sich so richtig?
Wie ist es mit dem Code des Timers für den Interrupt?
hp-freund schrieb:> Ich habe die ioc mit SW4STM32 importiert, alles ok.>> In der main.c erfolgt die Auswertung mit:>> void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
Hallo,
ich verstehe das jetzt nicht so ganz. Wenn ich sie so wie sie ist
importiere, dann klappt das auch. ABER: ich brauche doch noch den
RX-Interrupt bei der Uart. Der muss doch erst mit dem HAL_NVIC
initialisiert werden (was in der Main überhaupt nicht gemacht wurde).
Wenn ich das in der entsprechenden sub mache, dann habe ich die o.g.
Probleme.
Vll. bin ich aber auch völlig auf dem falschen Dampfer. Wie muss ich den
mit HAL den RX Interrupt initialisieren? Wieso nutzt du die Callback
fkt., geht nicht auch diese?
Hallo,
ich hatte nach der ioc gefragt um zu sehen ob alle Häkchen richtig für
den Int gesetzt sind. Das sind sie. Deshalb ist alles erledigt und es
braucht nur noch die genannte HAL Funktion.
Marius D. schrieb:> Es war schon klar, dass eine .h oder .c fehlt.> Wie soll ich das denn herausfinden, ich habe ALLE Dateien, welche die> .ioc erzeugt hat, dort ins Projekt implementiert.
Du sollst natürlich nicht in den Dateien Deines Projekts suchen, sondern
in den vom Compiler verwendeten Dateien.
Notfalls durchsuchst Du halt deine gesamte Festplatte nach dem
entsprechenden Symbol. Mag 'ne Weile dauern, aber ...
1
findstr /s /c:"USART_IT_RXNE" c:\*.h
Dein Gebrauch des Worts "implementieren" ist irreführend.
Marius D. schrieb:> Ich nutze EMBitz mit CubeMX und CMSIS....> Ich habe das Problem bei der Uart.
Ja dem sehe ich.
Es wird mir jedesmal traurig zumute, wenn ich sehe, wie Leute sich mit
eben diesem Zeugs herumquälen und entweder irgendwelche obskuren
Headerdateien nicht finden oder noch obskurere Kringel in einer ihnen
unbekannten Steuerdatei nicht passend gesetzt sind und deshalb die
Hälfte aller #define's in diversen Headern falsch laufen - und zum
Schluß kommt entweder garnichts oder Murks bei heraus.
Ich häng dir mal ein funktionables Beispiel hier dran.
ABER:
Je nach dem konkret verwendeten Chip mußt du die Interrupt-Nummern
anpassen und je nach verwendetem Startupcode wohl auch die Namen der
Interrupt-Handler. Ein Blick ins Refmanual hilft da gar sehr.
Vermutlich hast du auch keinen funktionablen SystemTick und keine
Systemuhr, aber darum solltest du dich selber kümmern. Man sollte einen
Controller der ARM-Klasse nicht ohne eine Systemuhr betreiben, allein
schon, um zeitliche Rahmen für auszuführende Aktionen setzen zu können,
denn ein Watchdog ist regelmäßig ein zu primitiver Knüppel für sowas.
So. Stell dich nicht so an.
W.S.
hp-freund schrieb:> Ich habe die ioc mit SW4STM32 importiert, alles ok.>> In der main.c erfolgt die Auswertung mit:>> void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
Kannst du mir etwas genauer erläutern, wie das hiermit geht?
Ich erstelle die fkt. und frage ab ob die instancen gleich sind und dann
mache ich was.
Wo wird diese fkt. dann aufgerufen? In der _it.c nämlich nicht. Und dort
sind alle Interrupts.
Ich bin nach wie vor der Meinung es wäre generell sinnvoll zuerst den
Umgang mit der Sprache C zu lernen, die Organisation von Code in
mehreren .c und .h Dateien zu verstehen, was Präprozessieren,
Kompilieren und Linken bewirkt (welchem Zweck diese
Verarbeitungsschritte haben, wann und mit welchen Dateien und mit
welchen Tools das geschieht und welche Konsequenzen das hat in Bezug auf
das was man in seinen Code an welchen Stellen hinschreiben kann, soll,
muss oder nicht kann oder nicht soll), etc. bevor man anfängt blind in
einem zigtausend-zeiligen und zweidutzend-dateiigen Projekt
herumzustochern ohne zu wissen woraus es besteht, wie die Teile
zusammenhängen, wie die Programmiersprache überhaupt funktioniert, noch
nicht mal in groben Zügen, und wonach man überhaupt sucht. Ich bin der
Meinung daß das sinnvoll wäre.
Ok.
Ich habe dein Projekt naggisch gemacht.
Lasse nur deinen Takt, JTAG und UART2.
Im Anhang schon Mal die ioc Datei.
Die Importiere ich jetzt und erweitere die main.c - und nur diese - um
einige Programmstücke.
Am Ende kannst Du deinem µC seriell eine Zeichenkette senden die in
Kleinbuchstaben zurückgegeben wird.
Ich habe deinen µC nicht, also wollen wir mal testen wie gut HAL
wirklich ist ;-)
In der Datei finden sich die jeweiligen "USER CODE" Bereiche.
Übernimm diese und es sollte funktionieren.
Die magische HAL_UART_RxCpltCallback Funktion befindet sich als __weak
in der stm32f7xx_hal_uart.c .
Da wird sie auch aufgerufen.
Habe noch was gefunden.
Da bei mir USART3 aktiv ist, ist leider einer durch gerutscht.
if (huart->Instance==USART3){
muss natürlich
if (huart->Instance==USART2){
werden.
hp-freund schrieb:> Habe noch was gefunden.> Da bei mir USART3 aktiv ist, ist leider einer durch gerutscht.>> if (huart->Instance==USART3){>> muss natürlich>> if (huart->Instance==USART2){>> werden.
OKay danke dir erstmal. Ab dem 28.09 kann ich wieder daran arbeiten.
Dann gucke ich mir das genauer an. Vielen Dank aber schonmal.