Forum: Mikrocontroller und Digitale Elektronik STM32 Uart implementierung findet die defines nicht?!


von MOBA 2. (Gast)


Lesenswert?

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
void MX_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
void MX_TIM1_Init(void)
2
{
3
  TIM_SlaveConfigTypeDef sSlaveConfig;
4
  TIM_MasterConfigTypeDef sMasterConfig;
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.

von hp-freund (Gast)


Lesenswert?

Hänge mal deine .ioc Datei an.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von MOBA 2. (Gast)


Lesenswert?

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?

von MOBA 2. (Gast)


Angehängte Dateien:

Lesenswert?

Anbei mal meine .ioc!

von hp-freund (Gast)


Lesenswert?

Ich habe die ioc mit SW4STM32 importiert, alles ok.

In der main.c erfolgt die Auswertung mit:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

von MOBA 2. (Gast)


Lesenswert?

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?
1
//IRQ HANDLER FOR UART
2
void USART2_IRQHandler(void)
3
{
4
    if(wifi_uart.Instance->SR & USART_SR_RXNE)       radarV3.wlan = ESP_ParseUartData(get_weather);
5
6
    wifi_uart.Instance->SR &= ~USART_SR_RXNE ;    //clear interrupt flag
7
}

Hier ist bspw. das Flag was er nicht kennt: USART_SR_RXNE

von hp-freund (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von MOBA 2. (Gast)


Lesenswert?

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.

von Bernd K. (prof7bit)


Lesenswert?

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.

von hp-freund (Gast)


Angehängte Dateien:

Lesenswert?

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 ;-)

von hp-freund (Gast)


Angehängte Dateien:

Lesenswert?

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.

von hp-freund (Gast)


Lesenswert?

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.

von MOBA 2. (Gast)


Lesenswert?

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.

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.