Forum: Mikrocontroller und Digitale Elektronik IAR und TIM6,7 Interruptprobleme beim STM32F107


von Simon (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Simon (Gast)


Lesenswert?

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!

von (prx) A. K. (prx)


Lesenswert?

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.

von Simon (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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?

von Hannes S. (Gast)


Lesenswert?

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.

von Simon (Gast)


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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.

von Simon (Gast)


Lesenswert?

Und das was ich gepostet hab, ist das keine korrekte Vektortabelle?

von (prx) A. K. (prx)


Lesenswert?

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

von Simon (Gast)


Lesenswert?

Gut das erklärt dann meinen nichterfolg!
Dann werd ich jetzt nachsuchen wie ich eine Vektortabelle bauen kann...

von (prx) A. K. (prx)


Lesenswert?

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.

von Hannes S. (Gast)


Lesenswert?

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

von Simon (Gast)


Lesenswert?

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

von Simon (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.