Forum: Mikrocontroller und Digitale Elektronik STM8S - Timer4 Overflow Interrupt führt zu unhandled exception


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Max M. (maxmicr)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich versuche gerade, den Overflow Interrupt des Timer4 vom STM8S zum 
laufen zu kriegen. Nach dem der Timer voll ist, läuft das Programm in 
eine "_iar_unhandled_exception" (siehe Anhang). Meine Timer 
Initialisierung:
1
void initTimer(){
2
  CLK_PCKENR1 |= (1<<4); //Enable Clock for Timer 4
3
  TIM4_PSCR = (0x07);    //Prescaler, Divide Clock by 7
4
  TIM4_IER = 1;          //Enable Update Interrupt
5
  TIM4_CR1 |= 1;         //Enable Timer
6
  asm("rim");           //Enable Interrupts        
7
}

Meine Interrupt Funktion:
1
#pragma vector = 23
2
__interrupt void TIM4_UPD_OVF_IRQHandler(void){
3
  displayInit();
4
  show();
5
  TIM4_SR &=~(1<<0);    //Clear Update interrupt
6
}

Woran liegt das?

von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Max M. schrieb:
> #pragma vector = 23

Meine Meinung: Das ist falsch, der Interrupt hat die Nummer 11.

von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Oh sorry, Timer4 hab ich übersehen.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Die Initialisierung des Displays in der Interrupt Routine lässt mich 
ahnen, dass das Programm strukturelle Mängel hat. Falls du keinen 
wirklich wichtigen Grund dafür hast, schlage ich Dir vor, den gesamten 
Quelltext zu zeigen, dann können wir Dir helfen, ihn zu verbessern.

von Max M. (maxmicr)


Bewertung
0 lesenswert
nicht lesenswert
Wenn ich die Zeile:
1
asm("rim");

auskommentiere lande ich nach dem Overflow nicht in der Exception, 
allerdings auch nicht in der Interrupt Funktion. Der Timerwert erhöht 
sich nun nur nach jedem 21. Step im Debug-Modus (aber auch erst, nach 
dem er einmal mit +6 / Step durchgelaufen ist). Das UIF-Bit wird nach 
dem Overflow gesetzt.

: Bearbeitet durch User
von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Max M. schrieb:
> Wenn ich die Zeile:asm("rim");
>
> auskommentiere

Dann gibt es auch keine Interrupts ...

von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> schlage ich Dir vor, den gesamten
> Quelltext zu zeigen, dann können wir Dir helfen, ihn zu verbessern

von Max M. (maxmicr)


Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Falls du keinen
> wirklich wichtigen Grund dafür hast, schlage ich Dir vor, den gesamten
> Quelltext zu zeigen, dann können wir Dir helfen, ihn zu verbessern.

Ich hab die Funktionen von oben nochmal umbenannt, nicht wundern:
1
/*
2
* main.c - Datei
3
*/
4
#include "MAX7219SPI.c"
5
#include "stdbool.h"
6
#define H 0x0C
7
#define E 0x0B
8
#define L 0x0D
9
#define S 0x0A
10
11
bool didInit = false;
12
13
uint8_t buffer[] = {
14
  H,E,L,L,0,S,S,S,S,1,3,3,7,S,S,S,S
15
};
16
17
void applyBuffer(){
18
  uint8_t counter;
19
  for(counter = 0; counter < 8; counter++){
20
    SPISendData(counter+1,buffer[8-counter]);
21
  }
22
}
23
24
void shuffleRight(){
25
  uint8_t counter, temp;
26
  for(counter = 0; counter < sizeof(buffer); counter++){
27
    if(counter != 0){
28
      uint8_t temp2 = buffer[counter];
29
      buffer[counter] = temp;
30
      temp = temp2;
31
    } else {
32
      temp = buffer[counter];
33
      buffer[counter] = buffer[sizeof(buffer)-1];
34
    }
35
  }
36
}
37
38
#pragma vector = 23
39
__interrupt void TIM4_UPD_OVF_IRQHandler(void){
40
  if(!didInit){
41
    initMAX7219();
42
    didInit = true;
43
  }
44
  applyBuffer();
45
  shuffleRight();
46
  TIM4_SR &=~(1<<0);    //Clear Interrupt
47
}
48
void initGPIOs(){
49
  PD_DDR = (1<<MOSI) | (1<<SCK) | (1<<CS);
50
  PD_CR1 = (1<<MOSI) | (1<<SCK) | (1<<CS);
51
  PD_ODR |= (1<<MOSI) | (1<<CS);
52
  PD_ODR &=~(1<<SCK);   //set SCK to low otherwise first clock isn't generated
53
}
54
55
void initTimer(){
56
  CLK_PCKENR1 |= (1<<4); //Enable Clock for Timer 4
57
  TIM4_PSCR = (0x07);    //Prescaler, Divide Clock by 7
58
  TIM4_IER = 1;          //Enable Update Interrupt
59
  TIM4_CR1 |= 1;         //Enable Timer
60
  asm("rim");           //Enable Interrupts        
61
}
62
63
int main(){
64
  initGPIOs();
65
  initTimer();
66
  while(1){
67
  }
68
}
69
/*
70
* MAX7219SPI.c Datei
71
*/
72
#include "iostm8s103f3.h"
73
#include "stdint.h"
74
75
#define MOSI    6
76
#define SCK     5
77
#define CS      4
78
79
void delay(uint16_t value){
80
  while(value != 0)
81
    value--;
82
}
83
84
void SPISendByte(uint8_t data){
85
  uint8_t mask;
86
  for(mask = 0x80; mask; mask >>=1){
87
    if(data & mask)
88
      PD_ODR |= (1<<MOSI);
89
    else
90
      PD_ODR &=~(1<<MOSI);
91
    delay(4);
92
    PD_ODR |= (1<<SCK);
93
    delay(12);
94
    PD_ODR &=~(1<<SCK);
95
    delay(2);
96
    PD_ODR &=~(1<<MOSI);
97
    delay(2);    
98
  }
99
}
100
101
void SPISendData(uint8_t regAddr, uint8_t data){
102
  delay(4);
103
  PD_ODR &=~(1<<CS);
104
  SPISendByte(regAddr);
105
  SPISendByte(data);
106
  PD_ODR |= (1<<CS);
107
  delay(4);
108
}
109
110
void initMAX7219(){
111
  SPISendData(0x0B,0x0F);               //Scan Limit
112
  delay(2);
113
  SPISendData(0x0A,0x0F);                //Max Intensity
114
  delay(2);
115
  SPISendData(0x0C,0x01);               //Normal Operation Mode
116
  delay(2);
117
  SPISendData(0x09,0xFF);               //Decode
118
  delay(2);
119
  SPISendData(0x0F,0x00);               //Normal Operation Mode
120
}

: Bearbeitet durch User
von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das fehlerträchtige Konstrukt würde ich nochmals überdenken:

#include "MAX7219SPI.c"

Ich habe mal Deine Version übernommen und im IAR kompiliert. Laut 
map-file landet die Interrupt-Routine an der richtigen Stelle. Im 
Simulator passiert nichts. Damit kenne ich mich allerdings auch nicht 
gut aus. Was macht Dein Programm auf der realen Hardware?

von Max M. (maxmicr)


Bewertung
0 lesenswert
nicht lesenswert
Okay, ich habs gelöst. Etwas seltsam...
Die Interrupt-Funktion wurde als solche erkannt allerdings hat der 
Vector nicht gestimmt 
(http://www.st.com/content/ccc/resource/technical/document/datasheet/ce/13/13/03/a9/a4/42/8f/CD00226640.pdf/files/CD00226640.pdf/jcr:content/translations/en.CD00226640.pdf 
[S.43]). Im Datenblatt steht als Nummer "23", in der Headerdatei hat der 
define "TIM4_OVR_UIF_vector" den Wert "25", wahrscheinlich, weil die 2 
obersten Interrupts "Reset" und "TRAP" nicht mitgezählt wurden. So 
funktioniert es nun:
1
#pragma vector = TIM4_OVR_UIF_vector
2
__interrupt void TIM4_UPD_OVF_IRQHandler(void){
3
  if(!didInit){
4
    initMAX7219();
5
    didInit = true;
6
  }
7
  applyBuffer();
8
  shuffleRight();
9
  TIM4_SR &=~(1<<0);    //Clear Update interrupt flag
10
}

Allerdings hätte ich dann erwartet, dass an der Adresse des 
Interrupt-Vektors mit der Nr. 23 die Sprungadresse meiner Funktion 
steht, aber die ganze Interrupt-Tabelle zeigte im Disassembly auf die 
unhandled-exception. Das
1
asm("rim");
 ist auch schwer bis unmöglich im Datenblatt zu finden. Naja, STM 
typisch.

: Bearbeitet durch User
von STM8 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Max M. schrieb:
> asm("rim"); ist auch schwer bis unmöglich im Datenblatt zu finden. Naja,
> STM

schau Dir mal intrinsics.h an ...

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
Falls du später mal die Variable didInit  außerhalb der ISR verwenden 
wirst, musst du sie als volatile deklarieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.