Hallo zusammen,
ich versuche nun seit Stunden ein STM32F103 Board zum laufen zu
bekommen. Ich habe zuerst eine LED mit einem delay (for schleife)
blinken lassen und wollte nun einen Timer in Betrieb nehmen. Dazu habe
ich Code angepasst (Quelle:
http://visualgdb.com/tutorials/arm/stm32/timers/) und leider läuft es
einfach nicht.
Kommentiere ich die Interrupt Enable Funktion (EnableTimerInterrupt)
aus, blinkt die eine LED (mit Delays). Kommentiere ich die Funktion ein
leuchten beide LEDs (beide sollten blinken). Laut Debugger springt er
nicht in die Interruptfunktion. Er befindet sich immer in der
startup_32stm an folgender Stelle:
1
.section .text.Default_Handler,"ax",%progbits
2
Default_Handler:
3
Infinite_Loop:
4
b Infinite_Loop
5
.size Default_Handler, .-Default_Handler
Steppe ich mit dem Debugger durch kommt mir eine Stelle in der misc.c
komisch vor (siehe Bild im Anhang).
Der Code an der Stelle sieht folgendermaßen aus:
1
/* Compute the Corresponding IRQ Priority --------------------------------*/
Bin leider ziemlich ratlos.
Hier hatte anscheinend einer das gleiche Problem:
Beitrag "Timer Interrupt am STM32F103"
Leider keine Lösung in Sicht. Wer hat noch eine Idee?
Dank und Gruß
JD
Mein Code:
Hallo,
ich will am frühen Morgen nicht deinen Code einzeln durchwursteln, kann
Dir aber meinen gut dokumentierten Code für eine 103 Funk Anwendung
geben und da kannste schauen was da anders ist als bei Dir. Bei mir
laufen 3 Timer im Interrupt, einer arbeitet auch mit dem DMA des ADC
zusammen und füllt Daten in ein Arry ein, und es funzt prima.
Gib den Timer erst dann frei, wenn der NVIC konfiguriert ist.
Lösche das TIM_IT_Update Bit einmal in der Initialisierung des Timers,
um etwaige Pendings zu löschen.
Matthias S. schrieb:> Lösche das TIM_IT_Update Bit einmal in der Initialisierung des Timers,> um etwaige Pendings zu löschen.
Tut das wirklich Not? Sobald der NVIC den Int zulässt springt er dann
einmal rein und fertig. Ansonsten bleibt es eben ein Pending Bit was
keinen stört, solange der zugehörige Int Vektor nicht angesprungen wird.
Bin aber auch nach fast 3/4 Jahr Sommerpause das erste Mal wieder in dem
Thema, kann mich auch irren.
Christian J. schrieb:> Tut das wirklich Not?
Der TE initialisiert den Timer und lässt ihn losrennen und erst später
wird der NVIC programmiert.
Ich habe in meinem BLDC Projekt mit dem F100 gute Erfahrungen damit
gemacht, den Timer zwar zu initialisieren, aber erstmal den NVIC zu
setzen und erst dann den Timer zu starten - und es schadet sicher nicht,
auch etwaige Pendings zu löschen. Es haben schon einige Leute hier
'hängende' IRQs bemerkt, wenn man das nicht macht.
Hallo und guten Morgen,
ich habe meinen Code so weit abgeändert. Bringt keine Verbesserung. Ich
habe irgendwie das Gefühlt, dass es nicht am Code liegt sondern an
flascher Einsellung von irgendwas. Ändere ich den NVIC_IRQChannel z.b.
auf TIM3_IRQ blinkt eine LED (in den Interrupt läuft er
selbstverständlich nicht). Timer3 ist ja auch nicht aktiv. Aber sobald
er einen Interrupt auslöst (TIM2_IRQ) landet er an dieser stellte:
1
/**
2
* @brief This is the code that gets called when the processor receives an
3
* unexpected interrupt. This simply enters an infinite loop, preserving
4
* the system state for examination by a debugger.
5
*
6
* @param None
7
* @retval : None
8
*/
9
.section .text.Default_Handler,"ax",%progbits
10
Default_Handler:
11
Infinite_Loop:
12
b Infinite_Loop
13
.size Default_Handler, .-Default_Handler
D.h. er bekommt einen Interrupt, welchen er nicht kennt. Kann es sein,
dass er die Fkt. TIM2_IRQHandler() einfach nicht findet? Oder kann es
sein das die ebay STM32F103 boards nichts taugen? Ich meine der Code ist
relativ überschaubar, er generiert einen Interrupt aber den Falschen,
der Timer läuft.
@Christian: In deinen Code schaue ich nun als nächstes.
Mein geänderter Code
JD schrieb:> D.h. er bekommt einen Interrupt, welchen er nicht kennt. Kann es sein,> dass er die Fkt. TIM2_IRQHandler() einfach nicht findet?
Diesen Zirkus hatte ich auch mal. Es lag letztlich daran, dass ich mit
den Optimierungsstufen des GCC Murks gebaut hatte. Schaltete ich die
alle ab lief es wieder. Ich habe da Stunden um Stunden gesucht und
landete auch ewig in dem Exception Handler. Strip deinen Code erstmal
soweit runter, dass alles aus ist bis auf den Timer, also LEDS usw alles
raus. Du kannst das im Debugger gut sehen. Ich arbeite mit Embitz 1.0
und dem GCC.
Ich empfehle Dir den Code erstmal mit O0 zu kompilieren und dann
schrittweise zu optimieren. In meiner Firma sind Optimierungen per
Coding Richtlinien ganz verboten und das aus gutem Grund.
Ich habe diese kleinen DIP40 Boards von ebay für 6 Euro fuffzig wo der
F103 drauf ist, die spielen aber gut. Nur musst Du auch die JTAG
abschalten.
Guck Dir in meinem Code nur mal die Main.c an, was ich da alles
eingestellt habe vorher. Und die Inits der Timer im sysinit.c Das alles
läuft durch auf höchste Optimierungstufe inzwischen.
BITTE Code als File anhängen und nicht einfach in den Beitrag posten.
Dazu gibt es auch Tags, die benutzt werden können !
Hallo Christian,
Code optimierung war und ist aus. Oder gibt es noch andere Stellen?
Wie schalte ich den JTAG ab?
Ich habe deinen Code probiert -> gleiche Problem. Das komische ist:
Deklariere ich die TIM2_IRQHandler vor der main und beschreibe sie
hinter der main, kann ich nicht mal mehr einen Breakpoint setzten.
Läuft den der Code bei dir? Hast du noch was in den Einstellungen
geändert? Ich habe auch die mini boards für Euro aus Chinaebay.
Zum verrückt werden... Ich wollte eigentlich nur einen Code portieren,
da ich DMA brauche ... :-(
So habe das Program noch mal gestrippt und alles von dir reingemacht.
Problem bleibt bestehen. Kann man irgendwie auf den Interrupt trigger,
um zu sehen, welcher geschmissen wird?
Was ich immer noch komisch finde, er kann keinen Breakpoint im Handler
setzen, d.h. der ist weg.
Oder kann ich irgendwie nachschauen, ob im InterruptVectorTable die
richtige Adresse steht?
Hat jemand ein Programm für System Workbench und dem STM32F103C8T6 was
er mir mal zippen könnte und ich probiere es damit.
Ist echt zum verzweifeln....
Hallo,
das CubeMX zeug mag ich nicht wirklich. Da heißen wieder alle Funktionen
anders. Es muss doch auch wie oben beschrieben gehen. Irgendwas stimmt
mit den Einstellungen nicht, jedoch bin ich mittlerweile etwas ratlos.
Hat noch jemand einen Tip?
DAs mit dem CubeMX probiere ich morgen mal aus.
JD schrieb:> hinter der main, kann ich nicht mal mehr einen Breakpoint setzten.
Wenn Du keinen Break setzen kannst, dann wurde für den Source Code kein
Code erzeugt. Schon mal dran gedacht, dass die CPU einen weg hat? Ich
habe mir durhc Anfassen der Pins auch einige GPIOs zerschossen.....
Geht nicht, der Eimer muss spielen! Da ist nichts mehr falsch
dran, außer in deiner IDE, die ich nicht kenne.
Startup Code, Compiler Options, Linker Options? Vielleicht postet du den
Cracks hier mal den Parameter String des Compilers, den die IDE zusammen
gebastelt hat.
Am Einfachsten ist immer sich was Funktionierendes zu nehmen und das
dann schrittweise anzupassen.
Noch kurz:
/* JTAG Interface abschalten, SWD einschalten (PB3, PB4 freimachen) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,
ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
Das ermöglicht Dir das Debuggen mit einem ST-Link V2 und befreit 2
weitere Ports. Per Default ist Jtag aktiviert. Du benutzt doch swd
Interface? Vorsicht, Du kannst Dich aus dem Chip aussperren! Dafür sind
dann die Jumper da mit denen Du den Bootloader starten kannst, um wieder
rein zukommen. Wenn Du Dich aussperrst musst Du den Chip erasen indem Du
Reset drückst bei gesetztem Jumper, damit er nicht in dein Programm
springt sondern in den Boot Loader und dann ein Löschprogramm aufrufen
Code wo kein BP setzbar ist existiert nicht! Dann hat der Compiler den
weg optimiert, er nimmt nur das rein, was er erreichen kann und was
irgendwo deklariert ist. Prototypen stimmen hoffentlich.
Die DIP 40 Dinger sind echt genial, benutze ich mit einem LCD Grafik
Display aber ich habe auch schon CPUs geröstet und musste mir mehrfach
neue auflöten lassen.
So, bin mit meinem Latein auch am Ende.....
Christian J. schrieb:
[..]
>> Die DIP 40 Dinger sind echt genial, benutze ich mit einem LCD Grafik> Display aber ich habe auch schon CPUs geröstet und musste mir mehrfach> neue auflöten lassen.
[..]
Ich habe das wegen eines (immernoch) defekten Labornetzteils (Asche auf
mein Haupt) auch schon mal geschaft einen F103 und den ulkigen
Spannungsregler zu killen (die Netzteilspannung schnipst beim
Ausschalten hoch, ein Baugleiches tut das nicht, wird wohl ein Elko taub
sein).
Ich habe nach Ersatzteilen gegoogelt...der Regler ist mehr oder weniger
Unobtanium und eine F103 CPU einzeln ist schon teurer als die ganze
Platine ich China mit Porto hier her kostet...ich habe ein paar Teile
runter gelötet, die Platine Schulterzuckend wegggeschmissen und 5 neue
bestellt.
Wo zum Teufel nimmst Du BE her mit denen sich die Rep. lohnt? Aus Deiner
Firma weil die die gerade da haben?
Gruß,
Holm
Hallo Leute,
es geht jetzt (dank eines Hinweises aus einem anderen Forum).
Vielleicht könnt ihr mir sagen wie ihr das macht... und zwar folgendes
:...
Ich erzeuge in der (empfohlenen bzw. unterstützen) IDE von Ti (system
workbench) ein neues Projekt:
File -> New -> C Project
Executable -> Empty Project -> Ac6 STM32 MCU GCC
Debug and Release (bild configurations)
MCU Configuration
Standard Peripheral Library (StdPeriph V3.5.0)
Dann kommt heraus, was ich euch als zip angehängt habe.
Leider ist dort kein einziger Interruptvektor für irgendeinen Timer in
der startup eingetragen. Ich kenne das immer nur so, dass alle Vektoren
schon im Interrupttabel drinstehen und man nur den richtigen Namen
kennen muss.
1
g_pfnVectors:
2
3
.word _estack
4
.word Reset_Handler
5
.word NMI_Handler
6
.word HardFault_Handler
7
.word MemManage_Handler
8
.word BusFault_Handler
9
.word UsageFault_Handler
10
.word 0
11
.word 0
12
.word 0
13
.word 0
14
.word 0
15
.word 0
16
.word 0
17
.word 0
18
.word 0
19
.word 0
20
.word 0
21
.word 0
22
.word 0
23
.word 0
24
.word 0
25
.word 0
26
.word 0
27
.word 0
28
.word 0
29
.word 0
30
.word 0
31
.word 0
32
.word 0
33
.word 0
34
.word 0
35
.word 0
36
.word 0
37
.word 0
38
.word 0
39
.word 0
40
.word 0
41
.word 0
42
.word 0
43
.word 0
44
.word 0
45
.word 0
46
.word 0
47
.word 0 //TIM2_IRQHandler
48
.word 0
49
.word 0
50
.word 0
51
.word 0
52
.word 0
53
.word 0
54
.word 0
55
.word 0
56
.word 0
57
.word 0
58
.word 0
59
.word 0
60
.word 0
61
.word 0
62
.word 0
63
.word 0
64
.word 0
65
.word 0
66
.word 0
67
.word 0
68
.word 0
69
.word 0
Trägt man nun an der richtigen Stelle den Interruptvektor ein geht es.
Ich habe es oben im Code schon mal markiert. Herausgefunden habe ich es
durch einen vergleich mit einer startup Datei, welche ich mir über das
Cube Teil gebaut habe.
1
g_pfnVectors:
2
3
.word _estack
4
.word Reset_Handler
5
.word NMI_Handler
6
.word HardFault_Handler
7
.word MemManage_Handler
8
.word BusFault_Handler
9
.word UsageFault_Handler
10
.word 0
11
.word 0
12
.word 0
13
.word 0
14
.word SVC_Handler
15
.word DebugMon_Handler
16
.word 0
17
.word PendSV_Handler
18
.word SysTick_Handler
19
.word WWDG_IRQHandler
20
.word PVD_IRQHandler
21
.word TAMPER_IRQHandler
22
.word RTC_IRQHandler
23
.word FLASH_IRQHandler
24
.word RCC_IRQHandler
25
.word EXTI0_IRQHandler
26
.word EXTI1_IRQHandler
27
.word EXTI2_IRQHandler
28
.word EXTI3_IRQHandler
29
.word EXTI4_IRQHandler
30
.word DMA1_Channel1_IRQHandler
31
.word DMA1_Channel2_IRQHandler
32
.word DMA1_Channel3_IRQHandler
33
.word DMA1_Channel4_IRQHandler
34
.word DMA1_Channel5_IRQHandler
35
.word DMA1_Channel6_IRQHandler
36
.word DMA1_Channel7_IRQHandler
37
.word ADC1_2_IRQHandler
38
.word USB_HP_CAN1_TX_IRQHandler
39
.word USB_LP_CAN1_RX0_IRQHandler
40
.word CAN1_RX1_IRQHandler
41
.word CAN1_SCE_IRQHandler
42
.word EXTI9_5_IRQHandler
43
.word TIM1_BRK_IRQHandler
44
.word TIM1_UP_IRQHandler
45
.word TIM1_TRG_COM_IRQHandler
46
.word TIM1_CC_IRQHandler
47
.word TIM2_IRQHandler
48
.word TIM3_IRQHandler
49
.word TIM4_IRQHandler
50
.word I2C1_EV_IRQHandler
51
.word I2C1_ER_IRQHandler
52
.word I2C2_EV_IRQHandler
53
.word I2C2_ER_IRQHandler
54
.word SPI1_IRQHandler
55
.word SPI2_IRQHandler
56
.word USART1_IRQHandler
57
.word USART2_IRQHandler
58
.word USART3_IRQHandler
59
.word EXTI15_10_IRQHandler
60
.word RTC_Alarm_IRQHandler
61
.word USBWakeUp_IRQHandler
62
.word 0
63
.word 0
64
.word 0
65
.word 0
66
.word 0
67
.word 0
68
.word 0
69
.word BootRAM /* @0x108. This is for boot in RAM mode for
70
STM32F10x Medium Density devices. */
Woher kann man das wissen ??? Wie macht ihr das??? und vorallem wie
findet man die richtige Stelle? Mache ich generell was falsch?
Vielen Dank für eure Hilfe!
@Holm : Du vergisst dass ich in einem Elektronik Konzern arbeite wo
komplette Rework Arbeitsplätze existieren und ein F103 keine Seltenheit
ist :-) Das Löten übernimmt der Robby...
Christian J. schrieb:> @Holm : Du vergisst dass ich in einem Elektronik Konzern arbeite wo> komplette Rework Arbeitsplätze existieren und ein F103 keine Seltenheit> ist :-) Das Löten übernimmt der Robby...
Das hatte ich eher nicht vergessen, sondern ja auch angemerkt.
Das Löten ist nicht das Problem, das kriege ich selbst hin, ich bekomme
nur die Teile nicht preiswerter als die Boards.
Gruß,
Holm
Christian J. schrieb:> Diesen Zirkus hatte ich auch mal. Es lag letztlich daran, dass ich mit> den Optimierungsstufen des GCC Murks gebaut hatte. Schaltete ich die> alle ab lief es wieder.
Das liegt in 99% der Fälle nicht an den Optimierungsstufen, sondern an
Fehlern im Quelltext. Die Lösung ist dann nicht, die Optimierung
abzuschalten, sondern den Fehler im Quelltext zu finden. Auch dann, wenn
man später die Optimierung abschaltet.
Nop schrieb:> Das liegt in 99% der Fälle nicht an den Optimierungsstufen, sondern an> Fehlern im Quelltext.
Die Diskussion darüber ist müssig, "meistens" ist es so. Aber ein
Quältext kann nicht einmal richtig sein und einmal falsch. Daher sind
Optimierungsstufen in Bereichen der "sicheren Software" verboten, das
was im Quelltext steht muss Zeile für Zeile im Assembler abgebildet
werden.
Christian J. schrieb:> Aber ein> Quältext kann nicht einmal richtig sein und einmal falsch.
Genau, er ist auch vor der Optimierung nämlich schon falsch. Die
Optimierung abzuschalten ist dann Symptombekämpfung.
Darüber hinaus sagt der C-Standard klar aus, daß C-Quelltexte nicht 1:1
in Assembler umgesetzt werden müssen, sondern der Compiler darf die "as
if"-Regel verwenden. Er darf also funktional äquivalenten Code erzeugen.