Forum: Mikrocontroller und Digitale Elektronik LPC1769 Kompass Sensor auslesen mit timer0 interrupt


von Stefan H. (stmuc)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe einen Kompass Sensor HMC6352 per I2C an meinem LPC1769 
angeschlossen, der mit 100 MHz läuft.
Als IDE verwende ich CooCox.

Die Datenübertragung funktioniert super und die gemessenen Daten sollen 
nach einem Tasterdruck über den CAN-Bus ausgegeben werden, was auch 
einwandfrei funktioniert.

Der Knopfdruck wird bisher über einen GPIO-Interrupt registriert.
Da der Taster aber mordsmäßig prellt, möchte ich sowohl Taster mit 
Timer0 periodisch abfragen (und somit entprellen), sowie auch das Timing 
der Kompassdatenabfrage regeln.

Mit Timer1 wird eine kleine Delay-Funktion realisiert, die einwandfrei 
funktioniert.

Problem: Der Timer0 Interrupt will einfach nichts machen!

Kann jemand das Problem erkennen, warum der nicht anspringt?
Ich tippe auf einen fiesen Anfängerfehler (der ich bezüglich 
ARM-Interrupts auch bin).

Ich Danke und viele Grüße
Stefan

von Jim M. (turboj)


Lesenswert?

Verwendest Du einen Debugger? Wenn nein besoge Dir einen:
1
  LPC_TIM0->MCR = (0x3 << 3);  /* Timer interrupt and reset */
2
  LPC_TIM0->TCR = 1; /* start timer */
3
  while (LPC_TIM0->TCR & (1 << 0));

Das Programm hängt in der while() Schleife beim Init des Timer0. Die hat 
da nix zu suchen, der Timer soll ja niemals anhalten sondern Interrupts 
auslösen.

von Stefan H. (stmuc)


Lesenswert?

Hallo Jim,

danke, das war dann wohl ein copy-paste-Fehler.
Funktioniert aber auch nicht nach Löschen der betreffenden Zeile.

Hab noch einen viel dooferen Fehler gefunden: Die timer0_init(void) 
steht jetzt auch in der main, geht aber trotzdem noch nicht.

Viele Grüße
Stefan

von Jim M. (turboj)


Lesenswert?

Ursache ist mal wieder zuviel magic Numbers:
1
LPC_TIM0->MCR = (0x3 << 3);  /* Timer interrupt and reset */

Obiger Code benutzt MR1, Du wolltest aber MR0 benutzen. Wenn man keine 
Konstanten (oder Makros) benutzt, findet man das praktisch nie.

Korrekt wäre also:
1
LPC_TIM0->MCR = 0x3;

Oder besser:
1
LPC_TIM0->MCR =  TIM_INT_ON_MATCH(0) | TIM_RESET_ON_MATCH(0);

: Bearbeitet durch User
von Stefan H. (stmuc)


Lesenswert?

Hallo Jim,

super! Danke dir für den Hinweis, werd ich heute Abend mal ausprobieren.
Sieht aber gefühlsmäßig so aus, als würde das funktionieren.
Fehler nachvollzogen und daraus gelernt (siehe user manual: Table 430).
Melde mich dann nach dem Test nochmal.
"zuviel magic numbers" :D werd ich mir auch mal merken.

Danke und Gruß
Stefan

von Stefan H. (stmuc)


Lesenswert?

So, noch kurze Rückmeldung:
1
LPC_TIM0->MCR =  TIM_INT_ON_MATCH(0) | TIM_RESET_ON_MATCH(0);
hat all meine groben Probleme gelöst.
Kleinere Fehler in der delayMs wurden noch behoben und die Funktion 
sieht jetzt so aus:
1
void delayMs(uint32_t delayInMs)
2
{
3
  LPC_TIM1->TCR = TIM_RESET;  /* reset timer */
4
  LPC_TIM1->PR  = 0x00;       /* set prescaler to zero */
5
  LPC_TIM1->MR1 = (SystemCoreClock / 4) / (1000 / delayInMs); //enter delay time
6
  LPC_TIM1->MCR = TIM_STOP_ON_MATCH(1);      /* stop timer on match */
7
  LPC_TIM1->TCR = TIM_ENABLE;        /* start timer */
8
  while (LPC_TIM1->TCR & (1 << 0));  /* wait until delay time has elapsed */
9
}

Danke Jim!

Viele Grüße
Stefan

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.