Forum: Mikrocontroller und Digitale Elektronik Interrupt wird nicht ausgelöst ( C167 )?


von Roman N. (namenloser)


Lesenswert?

Hi, ich bin neu hier und auch auf dem Gebiet der Microcontroller 
Programmierung.
Ich arbeite mit dem Evaluierungsboard Easy Kit XE167F von infineon.

Bin gerade bei der Interruptprogrammierung an einem einfach beispiel bei 
dem einfach ein led anwechselnd durch alle 100 Interruptaufrufe blinken 
soll.
Der Interrupt sollte ja automatisch bei einem Timer Under-oder Overflow 
ausgeläst werden soweit ich das verstanden habe.
PSW_IEN und IE,GLVL,LVL im Interrupt Controlregister werden auch gesetzt 
aber bei mir tut sich da irgendwie garnix.
Hab schon diverse verschiedene Werte für die timerinitialisierung 
versucht und auch alle möglichen Bits im IC und CON gesetzt aber 
nichts...
1
#include <XE167F.h>
2
3
#define RELOAD 20000
4
#define LEDON  0
5
#define LEDOFF  1
6
7
void timer6_init(unsigned int);
8
void unlockProtectedRegister(void);
9
10
volatile unsigned int i_cnt = 0;
11
12
void timer_tic() interrupt 0x24    //Interruptroutine für Timer6
13
{
14
  GPT12E_T6 = RELOAD;
15
16
  i_cnt++;
17
  switch(i_cnt)
18
  {
19
  case 200: i_cnt = 0;
20
      P10_OUT_P0 = LEDOFF;
21
    break;
22
  case 100: 
23
    P10_OUT_P0 = LEDON;
24
    break;
25
    default : break;
26
  }
27
  
28
}
29
30
main()
31
{
32
  P10_IOCR00 = 0x80;       // P10.0 auf Ausgaberegister
33
  P10_OUT_P0 = LEDOFF;
34
      
35
  timer6_init(RELOAD);
36
37
  unlockProtectedRegister();
38
  GPT12E_KSCCFG = 0x0003;
39
  PSW_IEN = 1;   
40
41
  while(1);
42
}
43
44
void timer6_init(unsigned int reload)
45
{
46
  GPT12E_T6 = reload;
47
  GPT12E_T6CON = 0x04C3;    //timermode, prescaler, cnt.down
48
  GPT12E_T6IC |= 0x5F;    //Interrupt enable, int.priority    
49
50
}
51
52
void unlockProtectedRegister(void)  //XE167F Spezifisch um auf bestimmte Register zugreifen zu dürfen oder so...^^
53
{       
54
  unsigned int pass;
55
56
  SCU_SLC = 0xAAAA;
57
  SCU_SLC = 0x5554;
58
59
  pass = SCU_SLS & 0x00FF;
60
  pass = (~pass) & 0x00FF;
61
62
  SCU_SLC = 0x9600 | pass;
63
  SCU_SLC = 0x0000;    
64
}

Weiß da jemand was ich falsch mache oder vergesssen habe oder kann 
jemand nen nachvolziehbaren Code für das Board Posten ?

Danke

von Tim K. (timmey)


Lesenswert?

Hallo
kurze frage wiso hast du GPT12E_T6IC |= 0x5F; mit dem | gesetzt? hast 
dich da vllt vertippt oder kenne ich bloß die bedeutung nicht? 
Ansonnsten hab ich nichts gesehen was ich nicht kenne oder nicht passen 
würde...

gruß

timmey

edit:
deklarier mal den P10_OUT_P0 mit sbit LED_OUT=P10_OUT_P0; und pass das 
in deinem programm dementsprechend an.

von Roman N. (namenloser)


Lesenswert?

Hallo,
GPT12E_T6IC |= 0x5F; ist ja nur ne andere Schreibweise für GPT12E_T6IC = 
GPT12E_T6IC | 0x5F; also ne ODER-Verknüpfung da ich net weiß ob 
Standartmäßig in dem Register bits gesetzt werden und ich somit sicher 
gehn kann keine automatisch gesetzten bits zu überschreiben.

wenn ich
1
 sbit LED_OUT = P10_OUT_P0;
 declarieren will bringt mir der Compiler nen fehler "E7.C(32): error 
C156: 'LED_OUT': invalid 'sbit' declaration", aber daran sollte es denk 
ich mal nicht liegen da ich ja das LED ja manuell mit P10_OUT_P0 = 0; 
blinken lassen kann bzw mit P10_OUT_P0 =1; abschalten kann, nur wird 
eben anscheinened die Interrupt funktion überhauptnicht aufgerufen.
Ist da evtl. noch irgendwo ein bit zu setzen damit der Interrupt bei dem 
Under-oder Overvlow ausgelöst wird ?
Oder hab ich die falsche Traap Nr. angegenen ?

Also in meinen Interrupt Nodes steht bei "Source of Interrupt or 
PEC/Service Request":GPT2 Timer6 und in der spalten "Trap Number":24h 
und der Spalte "Control Register":GPT12E_T6IC.

Oder muss ich die Priorität anderes setzen ? Aber das sollte ja 
eignetlich keine Rolle spielen bei nur einem Interrupt ?

von TManiac (Gast)


Lesenswert?

Hallo Roman,

Woher weißt du das der Interrupt nicht auslöst?
Dein Timer läuft für eine LED recht schnell (Prscaler von 4 = 10MHz bei 
40 MHz CPU). Mit deiner 200er Zählschleife würde deine LED also 10*10E6 
/ 200 = 50000 mal pro Sekunde blinken (wenn ich mich nicht verschaut und 
verrechnet habe)

Warum nutzt du zum Nachladen nicht das CAPREL Register?

Läuft der Timer?

Du hast doch sicherlich JTAG um in den läufenden Controller rein 
zuschauen.

Ist das Codeschnipsel mit DAvE erstellt?

Gruß,
TManiac

von Julian (Gast)


Lesenswert?

TManiac schrieb:
> Prscaler von 4 = 10MHz bei
> 40 MHz CPU

soweit ich informiert bin läuft der Timer bei den c176ern immer mit nem 
Prescaler von mindestens 8. d.h. 40MHz / 64
Ist aber natürlich immernoch zu schnell um es wahrnehmen zu können

von TManiac (Gast)


Lesenswert?

Auch wenn im Titel C167 steht, wurde im Eröffnungsbeitrag geschrieben, 
dass es sich um ein XE167F handelt. Der is e Weng schneller ;-)

von Julian (Gast)


Lesenswert?

sorry, hab noch was vergessen:
lass deine LED doch im Interrupt einfach mal nur anschalten (nicht mehr 
aus). Wenn die LED angeht springt er in die ISR rein, wenn sie aus 
bleibt nicht

von Roman N. (namenloser)


Lesenswert?

Ja, hab ich auch schon versucht die LED im Interrupt einfach nur 
Anzuschalten, von daher sollte er ja also erst garnich reinspringen.

Mit derm CAPREL Register habe ich noch nicht gearbeitet, weiß also net 
wie man den Timer damit nachläd.

Ebenso wenig erfahrung habe ich mit JTAG und DAvE.

Ich hab den Timer auch schon mal mit 65000 vorgeladen, dann wäre ja 
immer nur ein LED änderung nach 65000*100 Takten wenn ich das richtig 
verstanden habe und das sollte ja doch wahrnehmbar sein ?^^

von TManiac (Gast)


Lesenswert?

Hm, kein JTAG wie bekommst du deine Programme dann in den Controller und 
wie sieht die Hardware allgemein aus? Die Eva-Kits von Infineon/Hitex 
haben alle JTAG per USB. Damit kann man dann im Tasking (müsste auch 
beim Keil gehen) direkt im Controller debuggen.
(Da du die Leds am Port 10 hast sieht es tark nach Eva-Kit aus)

Ok wenn die LED nicht angeht (bai auskommentierten ausschalten) dann ist 
das gut belegt.

Weißt du ob der Timer läuft?

Grundsätzlich würde ich zu Testzwecken immer eine niedrigeren Interrupt 
Level und Gruppen Level nehmen. Spielt aber hier keine Rolle, da du ja 
keine weiteren Interrupts hast.

[Muss ich wohl auch mal Eva Kit anstöpseln]

von Roman N. (namenloser)


Lesenswert?

Hmm vlt benutz ich JTAG ja und weiß es nur nicht^^
Also meine Programme lade ich über den DAS Client und XE16X-96F On Chip 
Flash Algorithmus auf mein Board.

Also der Timer sollte eigentlich laufen, hab damit in einem anderen 
Programm auch schon eine wait() Funktion zum Blinken der LED´s 
geschrieben und hat funktioniert, konnte den Wert des Timers abfragen 
und alles, hatt aber auch dort keinen Interrupt ausgelöst das ich dort 
die selbe Interrupt Funktion Implementiert habe nur mit anderem Inhalt.

Hier ist der Funktionierende Codeausschnitt der Timerfunktion
1
void wait()
2
{
3
  GPT12E_T6CON_T6UD = 1;
4
  GPT12E_T6CON |= 0x1007;
5
6
   counter2++;
7
       GPT12E_T6 = 65000;
8
       GPT12E_T6CON_T6R = 1;
9
10
     while(GPT12E_T6)
11
       {
12
                  
13
       }         
14
}

von Roman N. (namenloser)


Lesenswert?

Also ich hab das Programm jetzt nocheinmal neu geschrieben, wobei ich es 
so einfach wie möglich gehalten habe und dabei nur den Timer von 65000 
runterzahälen lasse und durch die interrupt Funktion dann die LED´s 
einschalten lasse.

Auf jeden Fall funktioniert das nun, ich weiß zwar nicht an was es 
gelgen hat und wo der Fehler in dem anderen Programm liegt aber is ja 
schon mal was^^

Hier das neue Prog
1
#include <XE167F.h>
2
3
void initLED();
4
void timer6_init();
5
void unlockProtectedRegister(void);
6
7
8
9
void timer_tic() interrupt 0x24    //Interruptroutine für Timer6
10
{
11
  P10_OUT = 0x00;    //LED einschalten
12
}
13
14
int main(void)
15
{
16
  initLED();        // P10 auf Ausgaberegister
17
  timer6_init();
18
19
  P10_OUT = 0xff;           //LED´s auschalten
20
21
  while(1);
22
23
  return 0;
24
}
25
26
void timer6_init()
27
{
28
  GPT12E_T6 = 65000;
29
  GPT12E_T6CON_T6UDE = 1;    //External Up/Down Enable
30
  GPT12E_T6CON_T6UD = 1;     //Timer T6 Counts Down
31
  GPT12E_T6CON |= 0x0106;   //Prescaler gpt/2,Timer Mode,Prescale Factor 128
32
  
33
  GPT12E_T6CON_T6R = 1;     //Timer T6 runs
34
  GPT12E_T6IC = 0x04E;    //Interrupt enable, int.priority
35
  
36
  PSW_IEN = 1;
37
}
38
39
void initLED()
40
{
41
  //Einstellen der Port Input/Output Control Register: Pn_IOCRx
42
  // -> User's Manual 7.2.5 - Seite 471
43
  P10_IOCR00 = 0x0080; // P10.0 auf Ausgaberegister
44
  P10_IOCR01 = 0x0080; // P10.1 auf Ausgaberegister
45
  P10_IOCR02 = 0x0080; // P10.2 -"-
46
  P10_IOCR03 = 0x0080; // P10.3 -"-
47
  P10_IOCR04 = 0x0080; // P10.4 -"-
48
  P10_IOCR05 = 0x0080; // P10.5 -"-
49
  P10_IOCR06 = 0x0080; // P10.6 -"-
50
  P10_IOCR07 = 0x0080; // P10.7 -"-
51
52
  unlockProtectedRegister();
53
  GPT12E_KSCCFG = 0x0003;
54
}
55
56
void unlockProtectedRegister(void)  //XE167F Spezifisch um auf bestimmte Register zugreifen zu dürfen oder so...^^
57
{       
58
  unsigned int pass;
59
60
  SCU_SLC = 0xAAAA;
61
  SCU_SLC = 0x5554;
62
63
  pass = SCU_SLS & 0x00FF;
64
  pass = (~pass) & 0x00FF;
65
66
  SCU_SLC = 0x9600 | pass;
67
  SCU_SLC = 0x0000;    
68
}

Werd nun nach und nach einmal das was ich gegenüber dem alten Programm 
geändert habe wieder zurück ändern um daraus vlt zu sehen wo es gahakt 
hat.

Danke trozdem für eure schnellen antworten.

Wobei hätte an der Stelle gleich noch ne Frage zu den DIP-Schaltern auf 
meinem Board.
Weil ich die ein oder andere Aufgabe zu Programmieren habe anhand der 
man in abhängigkeit der Schalter verschiedene Betriebsarten auswählen 
können soll oder einen Interrupt über die Schalter auslösen lassen soll.
In der Beschreibung steht das die Schlater mit den IO-Ports 4.0-4.3 als 
"pullup-devices" verbunden sind.

Ich hab die Ports dann einmal so declariert
1
P4_IOCR00 = 0x0020; //P4.0 1. Schalter
2
  P4_IOCR01 = 0x0020;
3
  P4_IOCR02 = 0x0020;
4
  P4_IOCR03 = 0x0020;
Entspricht: Pull-up device connected, Input value = 1; pull-up

Ich hab dann schon öfters versucht in abhängikeit der 
Schalterstellungen, sprich
1
 if(P4_IN_P3 == 1)
 oder ähnliches in verschieden Programmstücke zu verzweigen usw.
Aber egal was ich mit den schaltern mache, habe ich bis jetzt noch nie 
eine andere Reaktion erlebt als die der Standarteinstellung.

Weiß da jemand genaueres wie man die Schalterstellung abfragen und 
danach verzweigen kann bzw. einen interrupt durch einen schalter 
auslösen kann ?

von Tim K. (timmey)


Lesenswert?

void timer_tic() interrupt 0x24

ich kenn die interrupt funktion nur mit gefüllter (void) k.a ob das was 
ausmacht - habs chon weilchen nix mehr gemacht und war auch nich 
sonderlich vertieft.. hab auch ma en altes prog rausgekramt vllt hilft 
dir das ein wenig...

http://pastebin.com/B3Bd5Yh9

von TManiac (Gast)


Lesenswert?

Hm, auch gut dass du mit suchst.

Was ich gefunden habe ist dass, du im ersten Anlauf das OTL nicht aktiv 
hattest und im zweiten schon:
1
F E D C B A 9 8 7 6 5 4 3 2 1 0 
2
S C - BPS O O U U R  Mode Input
3
R L  | 2 |T E D D  |     |
4
 |R| | | |L| |E| | | | | | | | 
5
0 0 0 0.0 1 0 0.1 1 0 0.0 0 1 1  = 0x04C3
6
0 0 0 0.0 0 0 1.0 0 0 0.0 1 1 0  = 0x0106
7
              1 1 1              Bits seperat gesetzt
Dies sollte aber dem Interrupt egal sein (komischkomisch).

Was noch anders ist, ist die Reihenfolge. Ich weiß jetzt nicht aus dem 
Kopf welche GTP12E Register alle mit   unlockProtectedRegister(); 
entsperrt werden müssen.
Aber du konfigurierst im ersten Prog erst deine GPT und danach kommt:
1
  unlockProtectedRegister();
2
  GPT12E_KSCCFG = 0x0003;
und im zweiten Prog machst du es anders herum. Wäre ein Versuch wert ob 
es daran liegt.

Grundsätzlich ist es immer eine gute Idee das Run-Bit seperat zu setzen. 
Aber warum hast du das external Up/Down Bit gesetzt?

In deinem ersten Prog schreibst du außerdem:
1
 volatile unsigned int i_cnt = 0;
Darauf würde ich mich nicht verlassen, wenn ich die 
Initialisierungsroutine nicht selber geschrieben habe. Besser wäre es du 
inialiserst dein i_cnt am Anfang des Programmes.

Zu den DIPs kann ich im Moment keine Hilfestellung geben, die sind ja 
eigentlich für die Stardup Konfiguration da. Die hab ich noch nie 
angefasst.

von Roman N. (namenloser)


Lesenswert?

>Was noch anders ist, ist die Reihenfolge. Ich weiß jetzt nicht aus dem
>Kopf welche GTP12E Register alle mit   unlockProtectedRegister();
>entsperrt werden müssen.
>Aber du konfigurierst im ersten Prog erst deine GPT und danach kommt:
>
>  unlockProtectedRegister();
>  GPT12E_KSCCFG = 0x0003;

>und im zweiten Prog machst du es anders herum. Wäre ein Versuch wert ob
>es daran liegt.

Jo das wars, hab im ersten Programm nur die Reihenfolge geändert und is 
auf anhieb gelaufen...^^
Eigentlich ja auch logisch.

>Aber warum hast du das external Up/Down Bit gesetzt?
Hmm hab das in irgend nem Beispiel gesehen, weiß auch nicht für was das 
Bit genau steht, habs aber auch mal auf 0 gesetzt, machte keinen 
unterschied.

Nochmal danke für eure Hilfe.

Werd dann evtl nich nen extra Beitrag zu den DIP-Schaltern aufmachen.

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.