hi, ich habe bereits viel mit 8-Bit AVRs gemacht,
und mache jetzt meine ersten Erfahrungen an einem STM32.
Habe hier ein "WaveShare Core 4171" mit einem STM32F407 auf einem
"WaveShare Open 4171" Breakout-Board.
Toolchain mit GCC, Eclipse und JTAG-Debugger läuft.
Mein erstes Programm wo ich die GPIOs ansteuere funktioniert.
Jetzt wollte ich einen Timer-Interrupt haben der alle 8ms aufgerufen
wird.
Aber die Interrupt-Callback-Funkltion wird nicht aufgerufen.
Hab ich irgendwas vergessen?
Timer mit Clock-Quelle verbinden.
Interrupts global erlauben?
Die Dokumentation der STM32CubeF4-HAL ist leider nicht so toll.
Der Aufruf von HAL_TIM_Base_GetState() gibt 1 (Peripheral Initialized
and ready for use) zurück
Christian schrieb:> GPIO_InitStructure.Pin = 0b00001100;
So etwas kann beim STM32 funktionieren, muss aber nicht, denn sowohl
CMSIS als auch HAL/Cube erwarten hier ein 16-bit Argument. Nimm lieber
die 'GPIO_Pin_3' und 'GPIO_Pin_4' Definitionen, denn dafür sind sie da.
Das gleiche kommt in deinem Code noch woanders vor.
Also
1
GPIO_InitStructure.Pin=GPIO_Pin_3|GPIO_Pin_4;
Dann sehe ich in deinem Code keine Initialisierung des NVIC. Der wird
für Interrupts benötigt. In CMSIS Syntax sieht das ungefähr so aus:
Christian schrieb:> HAL_TIM_Base_Start_IT(&hT4);
Wenn ich HAL richtig kapiere, sollte das eigentlich die ISR
Initialisierung erledigen, so das das Problem evtl. wirklich nur die
GPIO Definition betrifft.
Bin aber wirklich mit HAL auf Kriegsfuss - schon CMSIS geht mir über die
Hutschnur.
Edit: Ahh, lese jetzt dein letztes Posting - fein, das es klappt.
Übrignes gibt es bei einigen STM32 ein Problem mit dem Rumfummeln an
GPIOs in ISR Routinen, wenn man nicht vorher schon das IT Bit löscht.
Das betrifft aber eher externe Interrupts - sollte man aber dran
denken,z.B. so:
Das nächste Problem,
meine ISR wird um den Faktor 2 zu häufig aufgerufen, sprich mit 250Hz
statt 125Hz.
Ist der Timer-Takt ein andere als der CPU-Takt?
Der CPU-Takt sollte vom Startup-Code auf 168Mhz eingestellt sein.
Christian schrieb:> Ist der Timer-Takt ein andere als der CPU-Takt?
Oh, ja. Schau dir mal den Clock Tree im Reference Manual an (RM0090) auf
Seite 212/1713, dort steht auch, das die Timer von APB1 oder APB2
angetrieben werden, typisch 1/2 oder 1/4 CPU Clock. Wie genau die
Vorteiler stehen, kannst du mittels der SystemClock_Config() einstellen,
aber voller CPU Takt geht nicht.
OK, also wenn die maximale Timer-Clock, 1/2 CPU-Clock ist, dann läuft
mein Timer sogar um den Faktor 4 zu schnell.
Also, so als ob diese Zeile kein Effet hat.
1
hT4.Init.ClockDivision=TIM_CLOCKDIVISION_DIV4;
Dann werde ich mir mal Reference Manual reinziehen.
Matthias S. schrieb:> Christian schrieb:>> GPIO_InitStructure.Pin = 0b00001100;>> So etwas kann beim STM32 funktionieren, muss aber nicht, denn sowohl> CMSIS als auch HAL/Cube erwarten hier ein 16-bit Argument. Nimm lieber> die 'GPIO_Pin_3' und 'GPIO_Pin_4' Definitionen
Tatsächlich ist Pin eine 32-bit Variable, was einem als C-Programmierer
aber auch egal sein kann, da sowieso automatisch konvertiert wird.
Interessanter ist eher die Frage ob das Bitmuster immer stimmt. Daher
würde ich auch eher zu den Defines raten, allerdings meintest du wohl
'GPIO_PIN_2' und 'GPIO_PIN_3', denn hier wird bei 0 angefangen zu
zählen!
Sebastian V. schrieb:> Tatsächlich ist Pin eine 32-bit Variable, was einem als C-Programmierer> aber auch egal sein kann, da sowieso automatisch konvertiert wird.
Darüber, dass die automatische Konvertierung manchmal nicht so
konvertiert, wie es der unerfahrene C-Programmierer erwartet, ist schon
so mancher gestolpert.
Steffen R. schrieb:> Darüber, dass die automatische Konvertierung manchmal nicht so> konvertiert, wie es der unerfahrene C-Programmierer erwartet, ist schon> so mancher gestolpert.
Wenn man nicht gerade signed und unsigned mischt kann bei der
Konvertierung zu größeren Datentypen eigentlich nichts schiefgehen. Bei
signed zu unsigned gleicher Größe ist auch alles gut wenn man keine
negativen Werte hat.
Sebastian V. schrieb:> Wenn man nicht gerade signed und unsigned mischt>> GPIO_InitStructure.Pin = 0b00001100;
Pin sollte unsigned sein.
0b00001100 naja, dürfte implementierungsspezifisch sein. GGf als int und
somit signed interpretiert werden.
Üblich angewendet werden hex und binär eher als unsigned.
Ich wäre mir hier zumindest unsicher. Aber das trägt nichts zum Thema
bei.
Steffen R. schrieb:> Üblich angewendet werden hex und binär eher als unsigned.
Richtig. Das hat man sich beim Standardkomitee auch wohl bedacht. Daher
hat 0x7FFFFFFF den Typ int (wenn int 32Bit groß ist) und 0x80000000 den
Typ unsigned int. In dem 0x7FFFFFFF Fall und alle kleineren Zahlen ist
es aber auch kein Problem wenn der Wert zu unsigned konvertiert wird, da
0x7FFFFFFF nicht negativ ist und daher garantiert in einen unsigned int
passt. Für binary wird es ähnlich sein, auch wenn es nicht
standardisiert ist. Wenn man sich unsicher ist kann man ja immer noch
ein 'u' anhängen.
Ich versuche derzeit auch den Timer mit Interrupt zum laufen zu
bekommen. Doch bei mir springt er dauernd in den Default Handler. Warum
wird mein TIM2_IRQHandler nicht erkannt? Ist die
"HAL_TIM_PeriodElapsedCallback"-Funktion die in den Beispielen von ST
verwendet wird, für alle Timer gleichzeitig? In den Beispielen
funktioniert der Timer auch ohne HAL_NVIC_EnableIRQ(TIM2_IRQn);
Warum sollte er? Hierzu machst Du keine Angaben, die man überprüfen
könnte.
Der Interrupt selbst ist aktiv. Du bestätigst ja selbst, dass "ein"
Interrupthandler aufgerufen wird.
Dein Problem ist eher, dass bei Dir noch der Defaulthandler statt des
TIM2_IRQHandler als Interrupthandler für den Timer hinterlegt ist.
Du musst in dem Interrupt Handler ein Flag zurück setzen, weiß jetzt
nicht welches.
Das macht die HAL-Funktion die du aus dem Handler aufrufen musst, wenn
du es nicht selbst machst.
mach initTimBase global
dann
Sehr komisch,
HAL_NVIC_* eventuell erst nach Start_IT machen.
Übrigens HAL_TIM_PeriodElapsedCallback() wird aus der
HAL_TIM_IRQHandler() aufgerufen, und die wiederum muss aus
TIM2_IRQHandler() mit dem richtigen Handler aufgerufen werden.
Hab mich in den letzten Wochen intensiv damit beschäftigt.
Aber dann muss ich TIM_HANDLE_Typedef global definieren. Geht das auch
so, dass ich diese irgendwie lokal erstelle? Im Beispiel von ST wird
aber HAL_TIM_PeriodElapsedCallback() als Interruptroutine verwendet.
Nein es ändert sich nichts, wenn ich die Zeilen vertausche.
Dann schau dir mal die stm32f4xx_it.c in den Beispiel Projekten an, da
sind die xxx_IRQHandler() definiert, die alle die HAL_xxx_IRQHandler()
aufrufen.
Die HandleType variablen müssen leider global definiert sein.
Was hast du denn als Entwicklungsumgebung?
µVision Keil mit dem MDK-ARM Compiler, oder was auf GCC Basis.
Bei meinem Eclipse wird bei der Projekterstellung bereits CMSIS und die
HAl eingebunden, und auch durch den Startup Code initialisiert.
Ich verwende Eclipse unter Linux
Christian K. schrieb:> Dann schau dir mal die stm32f4xx_it.c in den Beispiel Projekten an, da> sind die xxx_IRQHandler() definiert, die alle die HAL_xxx_IRQHandler()> aufrufen.
Stimmt sorry habe ich übersehen. Muss ich meinen Handler auch in einer
Datei mit diesem Namen machen oder ist das egal wo ich meinen Interrupt
Handler erstelle/ die Standardroutine überschreibe?
Kommentier mal den Default Handler für Timer2 aus, bei mir steht er in
der startupxxx.S
// .weak TIM2_IRQHandler
// .thumb_set TIM2_IRQHandler,Default_Handler
dann wird der Linker schon moppern.
Ich hatte den Fehler auch, meinen Handler hatte ich einer .cpp Datei und
da wurde er nicht gefunden.
Er muss in C++ als
extern "C" void void TIM2_IRQHandler(void){
...
deklariert werden.
Wenn ich das auskommentiere, dann kommt ein Fehler, dass
TIM2_IRQHandler undeclariert ist. Wie kann ich meine Handler funktion
dazu linken, dass ich Sie verwenden kann?
Die Weak-Funktionen brauchen nicht auskommentiert werden.
Weak bedeutet, dass die Funktion nur benutzt wird, wenn keine andere
gleichnamige vorhanden ist.
Martin M. schrieb:> Muss ich meinen Handler auch in einer> Datei mit diesem Namen machen oder ist das egal wo ich meinen Interrupt> Handler erstelle
ist egal wo sie stehen.
Da du einen anderen Statupcode hast als ich, fehlt bei dir eventuell der
HAL_init() Aufruf, denn musst am Anfang der Main machen.
Jetzt habe ich die HAL_Init eingebaut. Leider keine Veränderung.
Habe jetzt mal im Datasheet gelesen. Hier steht, dass dies die minimalen
Dateien sind, die man braucht. Dabei ist auch die stm32f4xx_it.c wo die
interrupt handler sein sollen. Kann ich die Datei einfach erstellen oder
wie kann ich das verstehen?
Da der Default Interrupt Handler aufgerufen wird, brauchst Du nicht an
der Interrupterzeugung herumzudocktern!
Armin schrieb:> Kommentier mal den Default Handler für Timer2 aus, bei mir steht er in> der startupxxx.S> // .weak TIM2_IRQHandler> // .thumb_set TIM2_IRQHandler,Default_Handler> dann wird der Linker schon moppern.
Dem stimme ich für die Fehlersuche zu. Das weak führt dazu, dass das
fehlen des Symbols TIM2_IRQHandler überdeckt wird. Solange du versuchst
dein Symbol sichtbar zu machen hilft der Linkerfehler weiter.
Da zu wenig Angaben gemacht wurden, hat Armin auch ein Beispiel
geliefert, warum TIM2_IRQHandler nicht gefunden wird.
Martin M. schrieb:> void _attribute_ ((weak, alias ("Default_Handler")))> TIM2_IRQHandler(void); Wenn ich das auskommentiere, dann kommt ein> Fehler, dass> TIM2_IRQHandler undeclariert ist. Wie kann ich meine Handler funktion> dazu linken, dass ich Sie verwenden kann?
Genau das ist dein Problem, was du lösen mußt. Nicht die Erzeugung des
Interrupts.
Das Problem liegt in der Datei, aus dem dein Eingangs geposteter Code
stammt. Entweder ist die Funktion nicht global sichtbar oder der
Compiler nennt diese um. Die Idee von Armin war, dass diese mit (C++)
gpp übersetzt wird. Und C++ hat ein anderes NamensSchema wie C. Der Code
ist für eine Übersetzung mit einem C Compiler (gcc).
Vielleicht hast Du die Datei mit *.cpp enden lassen statt mit *.c?
Vielelicht einfach mal die Originaldatei anhängen, welche den
TIM2_IRQHandler() enthält.
Zeig doch mal deinen gesamten Code.
Mit Main und allen Handlern die du definiert hast. Am besten alles in
eine Datei reinkopieren, soviel hast du ja noch nicht.
Du verwendest als Startup Code die Assembler-Datei aus dem
CMSIS-Package.
Die ruft einige Funktionen auf (noch bevor Main losgeht) auf die du
selbst implementieren musst.
In den Beispielprojekten sind diese in der system_stm32f4xx.c drin.
> Kommentier mal den Default Handler für Timer2 aus, bei mir steht er in> der startupxxx.S> // .weak TIM2_IRQHandler> // .thumb_set TIM2_IRQHandler,Default_Handler> dann wird der Linker schon moppern.
Ich finde aber keine startupxxx.S Datei
Nach dem generierten Main-Code sieht es so aus als ob du Eclipse
verwendest.
Dann gibt es keine startupxxx.S Datei.
Eclipse verwendet stattdessen µOS++III als Startupcode, welcher komplett
in C geschrieben ist (statt Assembler)
Im Startupcode wird bereits die Hal und der Systemtakt initialisiert.
Der Aufruf von HAL_Init(); in der Main ist unnötig.
Die If Abfragen in deiner Timer Callback solltest du tauschen, oder es
direkt in den TIM2_IRQHandler schreiben.
Hab grad einen ähnlichen Fall.Bei mir hat der Linker die schwachen
Symbole aus dem Assemblerfile nicht durch die starken aus dem C -Code
ersetzt. Linken mit der Option Wl,--whole-archive brachte die
Fehlermeldung das der Assemblercode kein Objekt ist. Im C Code klappte
das Ersetzen. Meine Theorie ist das gcc die Dinge auseinanderhalten will
weil irgendwelche Assemblerdirektiven nicht stimmen, Meine Lösung war
das Auskommentieren der weak Stellen im Assemblercode.
Martin M. schrieb:> #pragma GCC diagnostic ignored "-Wunused-parameter"> #pragma GCC diagnostic ignored "-Wmissing-declarations"> #pragma GCC diagnostic ignored "-Wreturn-type"
Wozu die ganzen pragmas?
Martin M. schrieb:>> Kommentier mal den Default Handler für Timer2 aus, bei mir steht er in>> der startupxxx.S>> // .weak TIM2_IRQHandler>> // .thumb_set TIM2_IRQHandler,Default_Handler>> dann wird der Linker schon moppern.> Ich finde aber keine startupxxx.S Datei
Naja, irgendwo mußt du die Interruptvektoren schon eingebunden haben.
Da findest Du dann auch den Code, der TIM2_IRQHandler auf
Default_Handler umbiegt. Ich hoffe mal, dass du die Vektoren drin hast
und der Default_Handler nicht durch einen Trap ausgelöst wird.
Dieter Graef schrieb:> Hab grad einen ähnlichen Fall.Bei mir hat der Linker die schwachen> Symbole aus dem Assemblerfile nicht durch die starken aus dem C -Code> ersetzt.Martin M. schrieb:> Aber ich habe ja kein Assembler Initfile in Eclipse
Bei Dieter G. wird der relevante Code im Linkerfile sein.
Anm:
Da dein Projekt scheinbar anders ist, als die meisten es von uns gewöhnt
sind, müßtest Du wohl etwas mehr beschreiben. Es geht um alles, das
TIM2_IRQHandler und Default_Handler enthält.
Martin M. schrieb:> vectors_stm32f4.c
OK. Genau richtig.
Kommentiere nur die 'weak' Funktionalität aus:
1
void/* __attribute__ ((weak, alias ("Default_Handler"))) */
2
TIM2_IRQHandler(void);
Die eigentliche Deklaration brauchst Du für die Vectortabelle.
Er wird vermutlich melden, dass er TIM2_IRQHandler nicht findet. Das
wäre dann der Beweis, dass es an der Nicht-Sichtbarkeit deines
Interrupthandlers liegt. Nun ist es an Dir den Linkerfehler zu
beseitigen.
Wenn diese Linkerwarnung nicht kommt, sondern weiterhin der
Default-Handler aufgerufen wird, wird ein anderer Interrupt/Trap
aufgerufen.
Danach kannst Du den Originalzustand in vectors_stm32f4.c wieder
herstellen.
Martin M. schrieb
>Springt immer noch in den Default Handler. Hab aber in der gleichen >.c>Datei noch das gefunden. kann damit aber leider nichts anfangen.
Dem Linker muß mitgeteilt werden wo sich was im Mikrokontroller befindet
(RAM ROM)
Dazu wird dem Linker per Option ein Linkerscript meist mit der
Dateiendung ld mitgegeben in dem dann unter anderem steht:
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
Einfach die komplette Datei anhängen. Ist einfacher und enthält auch
Infos, an die du nicht denkst.
Was sagt das Mapping File?
Hast Du das richtige Derivate ausgewählt oder nur ein ähnliches?
HAL_InitTick() nutzt den Systick interrupt. Aber der sollte bei dir auch
schon eingerichtet sein, oder? Den genauen Namen hast du mit deinen ...
verschluckt. Ich glaube Systick_Handler().
Du kannst echt nicht debuggen?
Dieter Graef schrieb:> Dem Linker muß mitgeteilt werden wo sich was im Mikrokontroller befindet
Ohne diese Angabe wäre er gnadenlos abgestürzt.
Aber richtig:
@Martin: Woher weißt du, dass du im Default_Handler() landest?
Steffen R. schrieb:> Woher weißt du, dass du im Default_Handler() landest?
Er springt immer in diese Routine:
1
void__attribute__((section(".after_vectors")))
2
Default_Handler(void)
3
{
4
#if defined(DEBUG)
5
__DEBUG_BKPT();
6
#endif
7
while(1)
8
{
9
}
10
}
Ich habe dort zwar kein Brakepoint gesetzt, aber der Debugger hält hier
immer.
Im Anhang habe ich jetzt mal das komplette Projekt hochgeladen.
"Placeholder to list other libraries required by the application." Das
steht in der libs.ld muss ich da eventuell meine C Dateien angeben?
Dieter Graef schrieb:> Dazu wird dem Linker per Option ein Linkerscript meist mit der> Dateiendung ld mitgegeben in dem dann unter anderem steht:
Ja habe ich gefunden.
Steffen R. schrieb:> Was sagt das Mapping File?> Hast Du das richtige Derivate ausgewählt oder nur ein ähnliches?
???
Steffen R. schrieb:> Du kannst echt nicht debuggen?
Doch ich kann Debuggen, habe nie gesagt, dass ich das nicht kann.
Martin M. schrieb:> Ich habe dort zwar kein Brakepoint gesetzt, aber der Debugger hält hier> immer.
Na toll.... ;-)
Schau doch gleich in das PSR Register (genauer IPSR, weiß nicht, was bei
den Core registern angezeigt wird). Dort findest Du den Auslöser des
Interrupts (Interruptnummer). In deinem Datasheet zu deinem Prozessor
solltest du die Nummer auflösen können.
(mehr Details im Dokument DM00046982)
Lt. deinem Mappingfile sollte es wohl eines von den Handlern sein, die
du dort aufgelistet findest:
Christian schrieb:> Habe hier ein "WaveShare Core 4171" mit einem STM32F407 auf einem> "WaveShare Open 4171" Breakout-Board.Martin M. schrieb:> Steffen R. schrieb:>> Was sagt das Mapping File?>> Hast Du das richtige Derivate ausgewählt oder nur ein ähnliches?>> ???
Wenn Du einen STM32F407 hast, wäre das Define STM32F411xE offensichtlich
falsch. Ich vermute STM32F407xx wäre richtig. Das würde dann auch
erklären, dass der Timer2 Interrupt nicht an der richtigen Stelle wäre.
@Martin M.
Erstell nochmal das Projekt neu, und achte das du wirklich den richtigen
Controller angibst.
Und ändere nichts an den Quellcodedateien im Systemordner.
Eventuell hast du durch dein editieren die Vektortabelle kaputt gemacht.
Alle relevanten Funktionen sind als WEAK Definiert, das heißt du kannst
sie in deinem Code einfach neu definieren.
@Steffen Rose
Ich bin TO, aber mein Problem ist schon seit längerem gelöst.
Steffen R. schrieb:> Wenn Du einen STM32F407 hast
Nein ich habe einen stm32f411re. Hat am Anfang das Problem dass der
externe Clock nicht stimmte der Standardmäßig eingestellt wurde, weshalb
es auch lange nicht ging.
Christian K. schrieb:> @Martin M.> Erstell nochmal das Projekt neu, und achte das du wirklich den richtigen> Controller angibst.>> Und ändere nichts an den Quellcodedateien im Systemordner.> Eventuell hast du durch dein editieren die Vektortabelle kaputt gemacht.
Zugegeben. Korrekterweise gehören Dateien, die man ändert, immer ins
Projekt.
Uns man sollte immer auch die Originaldateien behalten, um Fehler wieder
rückgängig zu machen.
> Alle relevanten Funktionen sind als WEAK Definiert, das heißt du kannst> sie in deinem Code einfach neu definieren.
Meine Vermutung war, dass das Überdefinieren nicht geklappt hat. Durch
das weak bekommt man aber keinen Fehler. Welche Alternative hätte man?
> @Steffen Rose> Ich bin TO, aber mein Problem ist schon seit längerem gelöst.
Mist. Ist mir nicht aufgefallen, dass dein Thread nachgenutzt wurde.
Martin M. schrieb:> Steffen R. schrieb:>> Wenn Du einen STM32F407 hast>> Nein ich habe einen stm32f411re. Hat am Anfang das Problem dass der> externe Clock nicht stimmte der Standardmäßig eingestellt wurde, weshalb> es auch lange nicht ging.
Wie soll man hier noch durchblicken. Wäre hier nicht ein eigener Thread
besser gewesen?
Also weiter mit dem IPSR.
@Martin
Hab das Projekt auf einem stm32f407 mit einigen Änderungen zum laufen
bekommen.
Mein Linker kam mit der weak Zuweisungen nicht klar
die Methode aus vectors_stm32f4xx.c mit
void __attribute__((weak))
Default_Handler(void);
und dann
void /*__attribute__ ((weak, alias ("Default_Handler"))) */
TIM2_IRQHandler(void);
mit
void _attribute_ ((section(".after_vectors")))
Default_Handler(void)
{
#if defined(DEBUG)
__DEBUG_BKPT();
#endif
while (1)
{
}
}
sprang generell in die Default routine auch wenn woanders der
TIM2_IRQHandler definiert war. Mit
void /*__attribute__ ((weak)) */
TIM2_IRQHandler(void)
{
}
gings aber. Wenn das oben genannte funktioniert spart es Speicherplatz.
Zusätzlich hab ich noch den ganzen Startuprummel in c durch die von ST
vorgegebene Assemblermethode mit startup_stm32f407xx.s ersetzen müssen
da ansonsten gleich ein HardFault kam.
Martin M schrieb:
>Hast du einfach das attribute ((weak)) auskommentiert?
nee sorry ein copy und paste fehler
__attribute__((weak)) void TIM2_IRQHandler(void)
{
}
ich hab ne echte Funktion draus gemacht keinen alias
m.f.G.
Dieter
Wenn ich eine echte Funktion mache und das weak nicht auskommentiere,
wird immer noch der Default Handler ausgeführt, wenn ich das weak weg
lasse, dann kommt der Fehler, dass es hier das erste mal definiert
wurde.
Martin M. schrieb:
>dann kommt der Fehler, dass es hier das erste mal definiert>wurde
Das ist richtig da in deiner main.c Datei die Funktion ja schon steht.
Wie gesagt ich hab dann den c startup code aus deinem Projekt durch
Assembler von ST ersetzt und dann gings.Leider hab ich nur den 407 und
nicht den 411.Vermutlich ist deine Vorlage gar nicht für den gcc
Compiler sondern für einen anderen.
m.f.G.
Dieter
Auf meinem Laptop hat sich Eclipse geupdatet. Jetzt konnte ich auswählen
ob ich ein C oder ein C++ Programm schreiben wollte ( vorher stand immer
C/C++ Programm jetzt stehen Sie getrennt)
Habe am Code nur das extern "C" eingefügt, was vorher keine Wirkung
hatte, und siehe da er springt in die Routine rein :)
Ein großes Danke an alle die mir hier geholfen haben!!!
Christian schrieb:> OK, also wenn die maximale Timer-Clock, 1/2 CPU-Clock ist, dann> läuft> mein Timer sogar um den Faktor 4 zu schnell.>> Also, so als ob diese Zeile kein Effet hat.hT4.Init.ClockDivision => TIM_CLOCKDIVISION_DIV4;> Dann werde ich mir mal Reference Manual reinziehen.
Ich habe das selbe Problem mit einem STM32F746IGK, dass
TIM_CLOCKDIVISION_ kein Effekt hat. Konntet ihr das lösen? Mein
Prescaler ist bereits am Limit, weshalb ich auf die Taktteilung
angewiesen bin.
Danke
Ich hab mich mittlerweile komplett von der Cube-HAL gelöst.
Und greife jetzt ausschließlich über CMSIS (die Hardware-Register
direkt) zu.
Registerdefinitionen einfach im Datenblatt nachschlagen.
Hier aus meinem letzten Projekt:
timer4.h
1
#ifndef STM32F4_TIMER4_H
2
#define STM32F4_TIMER4_H
3
4
voidtimer4_init(void);
5
voidtimer4_enableInt(void);
6
7
//WEAK
8
voidtimer4_1sec_event1(void);
9
10
#endif /* STM32F4_TIMER4_H */
timer4.c
1
#include<CMSIS_Device/stm32f4xx.h>
2
3
#include"timer4.h"
4
5
voidTIM4_IRQHandler(void);
6
7
voidTIM4_IRQHandler(void){
8
staticinti=0;
9
if(TIM4->SR&TIM_SR_UIF){
10
i++;
11
if(i==125){
12
timer4_1sec_event1();
13
i=0;
14
}
15
TIM4->SR=~TIM_SR_UIF;
16
}
17
}
18
19
voidtimer4_init(void){
20
/*
21
* GP 16-Bit Timer
22
*/
23
24
RCC->APB1ENR|=RCC_APB1ENR_TIM4EN;
25
26
TIM4->PSC=840-1;// 84 MHz / (840) = 100 KHz
27
TIM4->ARR=800-1;// 100 KHz / (800) = 125 Hz
28
TIM4->EGR=TIM_EGR_UG;// Generate an update event to reload the Prescaler
29
30
TIM4->CR1=TIM_CR1_CEN;// Edge-aligned mode; upcounter; TIM enable
31
//TIM4->CR2;
32
//TIM4->SMCR;
33
//TIM4->DIER = TIM_DIER_UIE; // Enable the TIM Update interrupt
Hallo,
ich bin so frech und knüpfe hier einfach mal an. Ich habe das Problem
mit dem Timer6, dass wenn ich den Timer mit
1
HAL_TIM_Base_Start_IT(&htim6);
starte und im Anschluss mit
1
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
den Interrupt aktiviere, er direkt in die IRQ springt, was ich aber
nicht möchte und auch absolut keinen Sinn macht.
Muss ich vorher irgendein Bit löschen?
Kennt jemand dieses Problem?
Vielen Dank!
Koni schrieb:> Muss ich vorher irgendein Bit löschen?
Ja bitte. Und zwar vermutlich das TIM_IT_Update Bit (oder bei dir das
DAC Bit, das ich nicht nachschlagen werde). Dann die ISR freigeben. Nu
frag aber nicht, wie man das mit HAL macht - davon bin ich aus
medizinischen Gründen befreit worden :-)