Hallo, Ich bin STudent und will beweißen dass der NVIC wirktlich nestable ist. Mein Plan ist 2 irqs mithilfe von TIM6 and 7 zu generieren, dann Portpins setzten und das ganze mit dem Oszi nachprüfen... soweit bin ich: #include <include.h> void main(void) { RCC_APB2ENR = (1<<5); //enable Clock GPIOD RCC_APB1ENR = (U16)((1<<4) | (1<<5)); //enable Clock TIM6, TIM7 SETENA1 = (U32)((1<<22) | (1<<23)); TIM6_DIER = (1<<0); //enable TIM6 Interrupt TIM6_PSC=0x07D0; //prescaler 2000 => 36kHz TIM6_CR1 = (1<<7) | (1<<2) | (1<<0); TIM7_DIER = (1<<0); //enable TIM7 Interrupt TIM7_PSC=0x01F4; //prescaler 500 => 144kHz TIM7_CR1 = (1<<7) | (1<<2) | (1<<0); GPIOD_CRH &= 0x333FFFFF; GPIOD_BSRR = 0x0000E000; while(1){ } return 0; } __irq void TIM6(void) { static int cnt=0; cnt++; } __irq void TIM7(void); Jetzt ist das Problem, dass die TIM6 Interrupts generieren (Ich sehs im Pending register) aber die TIM Handler werden nie gestartet. Stattdessen geht der Prozessor in den Fault Mode. Danke für eure Hilfe Simon
Interrupts müssen beim STM32 meist im Handler explizit zurückgesetzt werden. Anders als beispielsweise bei AVRs passiert das nicht automatisch mit Aufruf des Handlers. Es empfiehlt sich übrigens, statt RCC_APB1ENR = (U16)((1<<4) | (1<<5)); die im passenden Include-File der CMSIS definierten compilerübergreifend vereinheitlichten Registerzugriffstechniken und insbesondere die Bitnamen zu verwenden. Das sonst entstehende Zahlengeschwurbel ist ohne Handbuch unverifizierbar.
Ist klar, dass die Interrupts zurückgestetzt werden müssen. Der Interrupt wird kein einziges mal aufgerufen. Noch besser: Laut Linker map file wird die Funktion TIM6 nicht mal mitgelinkt!
Dann hat sie möglicherweise den falschen Namen? Ich bin mit den IAR Compiler nicht vertraut. Bei den Cortexen liegt es von der Arbeitsweise des NVIC her nahe, dass die Zuordnung der ISRs zu den einzelnen Interruptvektoren über den Namen der Funktion erfolgt. Wie das genau funktioniert, das verrät dir hoffentlich das Handbuch vom IAR. Oder, wenn du Pech hast, etwas Gebuddel in den Startup- und Hilfscodes, die dem Programm von der Programmierumgebnug automatisch hinzugegeben werden. Ausserdem sollte man bedenken, dass beim Cortex M3 eine ISR eine ganz normale C-Funktion ist, ohne spezielle Prolog/Epilog-Mechanismen wie sie bei anderen Prozessoren und älteren ARMs nötig sind. Daher stelle ich mal ganz blauäugig das Attribut __irq in Frage - vielleicht wird es beim CM3 eben grad nicht benötigt.
Also laut Verctor Table ist TIM6 Interrupt auf 0x118 und per define mit TIM6 verknüpft. Laut IAR Handbuch werden Interruptfunktionen mit __irq begonnen. Hab aber auch schon ohne Probiert... Kein Erfolg. Beim aufkommen des Interrupts wird das Bit IACCVIOL in CFSR-reg gesetzt.
Wenn die ISR vom Compiler komplett ignoriert wird, dann benötigst du jemanden, der mit dem IAR Compiler besser vertraut ist. IAR? IAR Support-Forum? Gibt es Beispielcode speziell für IAR?
Yep, das mit der IRQ Definition ist schonmal ein Punkt. Der IRQ Handler wird als ganz normale C Funktion gestaltet und muss einen vorgegebenen Namen haben, also: void TIM6_IRQHandler(void) { } Die Interrupttabelle findet sich in einem File Namens startup_stm32f10x_yy.s Dieses muss im Projekt mit eingebunden werden. Wobei "yy" je nach verwendeter Device z.B. "md" für Medium Density Devices ist. Ansonsten fehlt noch das aktivieren der betreffenden NVIC Interrupts. Ich erledige das immer mit den Funktionen der Lib, also NVIC_EnableIRQ(). Alles in allem würde ich Dir empfehlen, mal mit den Samples von ST anzufangen. Die sind auch für IAR verfügbar und zeigen schonmal die wichtigsten vorgehensweisen zur Benutzung der Peripherie.
Also ich finde in inc von IAR dieses File: iostm32f107xx.h Daraus hab ich entnommen:
1 | /***************************************************************************
|
2 | **
|
3 | ** STM32F107xx Interrupt Lines
|
4 | **
|
5 | ***************************************************************************/
|
6 | #define MAIN_STACK 0 /* Main Stack */ |
7 | #define RESETI 1 /* Reset */ |
8 | #define NMII 2 /* Non-maskable Interrupt */ |
9 | #define HFI 3 /* Hard Fault */ |
10 | #define MMI 4 /* Memory Management */ |
11 | #define BFI 5 /* Bus Fault */ |
12 | #define UFI 6 /* Usage Fault */ |
13 | #define SVCI 11 /* SVCall */ |
14 | #define DMI 12 /* Debug Monitor */ |
15 | #define PSI 14 /* PendSV */ |
16 | #define STI 15 /* SysTick */ |
17 | #define WWDG 16 /* Window Watchdog interrupt */ |
18 | #define NVIC_PVD 17 /* PVD through EXTI Line detection interrupt*/ |
19 | #define NVIC_TAMPER 18 /* Tamper interrupt */ |
20 | #define NVIC_RTC 19 /* RTC global interrupt */ |
21 | #define NVIC_FLASH 20 /* Flash global interrupt */ |
22 | #define NVIC_RCC 21 /* RCC global interrupt */ |
23 | #define NVIC_EXTI0 22 /* EXTI Line0 interrupt */ |
24 | #define NVIC_EXTI1 23 /* EXTI Line1 interrupt */ |
25 | #define NVIC_EXTI2 24 /* EXTI Line2 interrupt */ |
26 | #define NVIC_EXTI3 25 /* EXTI Line3 interrupt */ |
27 | #define NVIC_EXTI4 26 /* EXTI Line4 interrupt */ |
28 | #define NVIC_DMA_CH1 27 /* DMA Channel1 global interrupt*/ |
29 | #define NVIC_DMA_CH2 28 /* DMA Channel2 global interrupt*/ |
30 | #define NVIC_DMA_CH3 29 /* DMA Channel3 global interrupt*/ |
31 | #define NVIC_DMA_CH4 30 /* DMA Channel4 global interrupt*/ |
32 | #define NVIC_DMA_CH5 31 /* DMA Channel5 global interrupt*/ |
33 | #define NVIC_DMA_CH6 32 /* DMA Channel6 global interrupt*/ |
34 | #define NVIC_DMA_CH7 33 /* DMA Channel7 global interrupt*/ |
35 | #define NVIC_ADC1_2 34 /* ADC global interrupt */ |
36 | #define NVIC_CAN1_TX 35 /* CAN1 TX interrupt */ |
37 | #define NVIC_CAN1_RX0 36 /* CAN1 RX0 interrupt */ |
38 | #define NVIC_CAN1_RX1 37 /* CAN1 RX1 interrupt */ |
39 | #define NVIC_CAN1_SCE 38 /* CAN1 SCE interrupt */ |
40 | #define NVIC_EXTI9_5 39 /* EXTI Line[9:5] interrupts */ |
41 | #define NVIC_TIM1_BRK 40 /* TIM1 Break interrupt */ |
42 | #define NVIC_TIM1_UP 41 /* TIM1 Update interrupt */ |
43 | #define NVIC_TIM1_TRG_COM 42 /* TIM1 Trigger and Commutation interrupts */ |
44 | #define NVIC_TIM1_CC 43 /* TIM1 Capture Compare interrupt */ |
45 | #define NVIC_TIM2 44 /* TIM2 global interrupt */ |
46 | #define NVIC_TIM3 45 /* TIM3 global interrupt */ |
47 | #define NVIC_TIM4 46 /* TIM4 global interrupt */ |
48 | #define NVIC_I2C1_EV 47 /* I2C1 event interrupt */ |
49 | #define NVIC_I2C1_ER 48 /* I2C1 error interrupt */ |
50 | #define NVIC_I2C2_EV 49 /* I2C2 event interrupt */ |
51 | #define NVIC_I2C2_ER 50 /* I2C2 error interrupt */ |
52 | #define NVIC_SPI1 51 /* SPI1 global interrupt */ |
53 | #define NVIC_SPI2 52 /* SPI2 global interrupt */ |
54 | #define NVIC_USART1 53 /* USART1 global interrupt */ |
55 | #define NVIC_USART2 54 /* USART2 global interrupt */ |
56 | #define NVIC_USART3 55 /* USART3 global interrupt */ |
57 | #define NVIC_EXTI15_10 56 /* EXTI Line[15:10] interrupts */ |
58 | #define NVIC_RTC_ALARM 57 /* RTC alarm through EXTI line interrupt */ |
59 | #define NVIC_OTG_FS_WKUP 58 /* USB On-The-Go FS Wakeup through EXTI line interrupt */ |
60 | #define NVIC_TIM5 66 /* TIM5 global interrupt */ |
61 | #define NVIC_SPI3 67 /* SPI3 global interrupt */ |
62 | #define NVIC_UART4 68 /* UART4 global interrupt */ |
63 | #define NVIC_UART5 69 /* UART5 global interrupt */ |
64 | #define NVIC_TIM6 70 /* TIM6 global interrupt */ |
65 | #define NVIC_TIM7 71 /* TIM7 global interrupt */ |
66 | #define NVIC_DMA2_CH1 72 /* DMA2 Channel1 global interrupt*/ |
67 | #define NVIC_DMA2_CH2 73 /* DMA2 Channel2 global interrupt*/ |
68 | #define NVIC_DMA2_CH3 74 /* DMA2 Channel3 global interrupt*/ |
69 | #define NVIC_DMA2_CH4 75 /* DMA2 Channel4 global interrupt*/ |
70 | #define NVIC_DMA2_CH5 76 /* DMA2 Channel5 global interrupt*/ |
71 | #define NVIC_ETH 77 /* Ethernet global interrupt */ |
72 | #define NVIC_ETH_WKUP 78 /* Ethernet Wakeup through EXTI line interrupt*/ |
73 | #define NVIC_CAN2_TX 79 /* CAN2 TX interrupt */ |
74 | #define NVIC_CAN2_RX0 80 /* CAN2 RX0 interrupt */ |
75 | #define NVIC_CAN2_RX1 81 /* CAN2 RX1 interrupt */ |
76 | #define NVIC_CAN2_SCE 82 /* CAN2 SCE interrupt */ |
77 | #define NVIC_OTG_FS 83 /* USB On The Go FS global interrupt */ |
78 | |
79 | #endif /* __IOSTM32F107xx_H */ |
80 | |
81 | /*###DDF-INTERRUPT-BEGIN###
|
82 | Interrupt0 = NMI 0x08
|
83 | Interrupt1 = HardFault 0x0C
|
84 | Interrupt2 = MemManage 0x10
|
85 | Interrupt3 = BusFault 0x14
|
86 | Interrupt4 = UsageFault 0x18
|
87 | Interrupt5 = SVC 0x2C
|
88 | Interrupt6 = DebugMon 0x30
|
89 | Interrupt7 = PendSV 0x38
|
90 | Interrupt8 = SysTick 0x3C
|
91 | Interrupt9 = WWDG 0x40
|
92 | Interrupt10 = PVD 0x44
|
93 | Interrupt11 = TAMPER 0x48
|
94 | Interrupt12 = RTC 0x4C
|
95 | Interrupt13 = FLASH 0x50
|
96 | Interrupt14 = RCC 0x54
|
97 | Interrupt15 = EXTI0 0x58
|
98 | Interrupt16 = EXTI1 0x5C
|
99 | Interrupt17 = EXTI2 0x60
|
100 | Interrupt18 = EXTI3 0x64
|
101 | Interrupt19 = EXTI4 0x68
|
102 | Interrupt20 = DMA1Ch1 0x6C
|
103 | Interrupt21 = DMA1Ch2 0x70
|
104 | Interrupt22 = DMA1Ch3 0x74
|
105 | Interrupt23 = DMA1Ch4 0x78
|
106 | Interrupt24 = DMA1Ch5 0x7C
|
107 | Interrupt25 = DMA1Ch6 0x80
|
108 | Interrupt26 = DMA1Ch7 0x84
|
109 | Interrupt27 = ADC1_2 0x88
|
110 | Interrupt28 = CAN1_TX 0x8C
|
111 | Interrupt29 = CAN1_RX0 0x90
|
112 | Interrupt30 = CAN1_RX1 0x94
|
113 | Interrupt31 = CAN1_SCE 0x98
|
114 | Interrupt32 = EXTI9_5 0x9C
|
115 | Interrupt33 = TIM1_BRK 0xA0
|
116 | Interrupt34 = TIM1_UP 0xA4
|
117 | Interrupt35 = TIM1_TRG_COM 0xA8
|
118 | Interrupt36 = TIM1_CC 0xAC
|
119 | Interrupt37 = TIM2 0xB0
|
120 | Interrupt38 = TIM3 0xB4
|
121 | Interrupt39 = TIM4 0xB8
|
122 | Interrupt40 = I2C1_EV 0xBC
|
123 | Interrupt41 = I2C1_ER 0xC0
|
124 | Interrupt42 = I2C2_EV 0xC4
|
125 | Interrupt43 = I2C2_ER 0xC8
|
126 | Interrupt44 = SPI1 0xCC
|
127 | Interrupt45 = SPI2 0xD0
|
128 | Interrupt46 = USART1 0xD4
|
129 | Interrupt47 = USART2 0xD8
|
130 | Interrupt48 = USART3 0xDC
|
131 | Interrupt49 = EXTI15_10 0xE0
|
132 | Interrupt50 = RTCAlarm 0xE4
|
133 | Interrupt51 = OTG_FSWakeup 0xE8
|
134 | Interrupt52 = TIM5 0x108
|
135 | Interrupt53 = SPI3 0x10C
|
136 | Interrupt54 = UART4 0x110
|
137 | Interrupt55 = UART5 0x114
|
138 | Interrupt56 = TIM6 0x118
|
139 | Interrupt57 = TIM7 0x11C
|
140 | Interrupt58 = DMA2Ch1 0x120
|
141 | Interrupt59 = DMA2Ch2 0x124
|
142 | Interrupt60 = DMA2Ch3 0x128
|
143 | Interrupt61 = DMA2Ch4 0x12C
|
144 | Interrupt62 = DMA2Ch5 0x130
|
145 | Interrupt63 = ETH 0x134
|
146 | Interrupt64 = ETHWakeup 0x138
|
147 | Interrupt65 = CAN2_TX 0x13C
|
148 | Interrupt66 = CAN2_RX0 0x140
|
149 | Interrupt67 = CAN2_RX1 0x144
|
150 | Interrupt68 = CAN2_SCE 0x148
|
151 | Interrupt69 = OTG_FS 0x14C
|
152 |
|
153 | ###DDF-INTERRUPT-END###*/
|
Aber so gehts ja nicht! Hab mir die entsprechenden s files geholt, und mal ausprobiert. War klar geht nichts. Nur ein haufen errors. Ich such mal weiter. Danke für den Tipp, habs Gefühl dass is der Richtige weg :) ach ja: http://code.google.com/p/stm32f107/source/browse/trunk/STM32F10x_Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/?r=4 Link zu den *.s files...
Simon schrieb: > Link zu den *.s files... Und ebendort finde ich in der Vektorleiste beispielsweise Namen wie "TIM2_IRQHandler". Und drunter die Defaults mit Hardfault für nicht definierte Handler, in denen du offenkundig landest. Also das was ich sagte: falscher Funktionsname.
Und das was ich gepostet hab, ist das keine korrekte Vektortabelle?
Ich sehe darin oben nur einen Haufen #defines der Vektorindizes und darunter einen länglichen Kommentar für rechenschwache Zeitgenossen. Eine Tabelle sehe ich dort nicht. Die Tabelle sehe ich hingegen in http://code.google.com/p/stm32f107/source/browse/trunk/STM32F10x_Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/iar/startup_stm32f10x_md_vl.s?r=4
Gut das erklärt dann meinen nichterfolg! Dann werd ich jetzt nachsuchen wie ich eine Vektortabelle bauen kann...
Du solltest erst einmal rauskriegen, wie sich IAR die Entwicklung von Programmen für STM32 vorgestellt hat, bevor du nacheinander sämtliche 4 Räder deines Autos einzeln neu erfindest. Ist ja nicht so, dass IAR ein völliger Neuling in der Branche wäre.
Ich kann mich da A.K. nur anschließen. Geh einfach mal zu ST und lad Dir die STM32F10x_StdPeriph_Lib runter. Dort drinnen gibt es neben den Samples auch ein IAR Template Project welches als Ausgangspunkt für eigene Entwicklungen dienen sollte. Und selbst wenn Du die Lib dann nicht nutzen magst erklärt sich doch vieles, indem man den Code einfach durchliest. Aber auch IAR bringt im Ordner Examples->ST->STM32F103x einige Beispiele mit, unter anderem auch für den F107. Der Nachteil ist hier lediglich, dass die von IAR mitgelieferte ST-Library meist einige Versionsnummern hinterherhinkt (und alte Versionen hatten durchaus den ein oder anderen Bug...)
Jut. Es Funktioniert. Es reicht die Verktortabelle ins Projektverzeichniss zu legen und irgendwo die Funktion sysinit zu deklarieren, meinetwegen um z.b. möglichst früh irgendwelche Portpins richtig einzustellen... Danach kann jeder Interrupt korrekt ausgeführt werden! Vielen dank für eure Hilfe
Ach ja und die Interrupts werden automatisch zurückgesetzt! Zumindest auf NVIC Seite. Beim Timer muss im Statusregister der Interruptrequest per Software zurückgesetzt werden. Genau wie bei AVR...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.