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