Hallo liebe Forums-Gemeinde! Ich nutze diese Forum schon länger als Nachschlagwerk, aber das ist jetzt mein erstes Post, also habt Rücksicht wenn nicht alles passt ;) Ich bin Einsteiger beim Programmieren von Mikrocontrollern und stecke seit längerem an einem Problem. Als myC verwende ich einen MSP430F5310 und programmiere mit dem CodeComposer. Ich muss für ein Projekt ein Display(DOGM162 mit ST7036-Controller) ansteuern. Ich habe schon sehr viele Code-Bsp im Internet gefunden und probiert zu verstehen und anzupassen aber leider blieb das LCD immer schwarz ;(. Nun zu meiner eigentlichen Frage: Für die Initialisierung des Displays brauche ich eine Zeitverzögerung. Da es ja beim MSP keine fertige Funktion gibt, möchte ich es über einen Timer mit Interrupt lösen. Anbei der Code (ich hoffe man kann ich öffnen). Ich habe probiert den Code Schritt für Schritt durchzugehen und im Register die Werte anzusehen. Soweit ich es erkennen konnte zählt er bis zum Grenzwert setzt auch das CCIF, geht aber dann nicht in die Routine und bleibt in der do-Schleife hängen. Könnt ihr mit ev. weiterhelfen? DANKE!
CCS versteht __delay_cycles, damit sollte es dir möglich sein Anhand der der Frequenz ein ein Delay zu erzeugen.
Danke, das mit dem delay_cycles habe ich auch schon mal versucht. Weiß jetzt aber gar nicht warum ich davon abgekommen bin. Wäre diese Lösung eine saubere Lösung? Und weißt du welche Clock dafür verwendet wird? LG
Du zeigst nur einen kleinen Ausschnitt, aus dem man nix erkennt. Brauchst den WDT? Wenn nicht ist das eine günstige Zeitreferenz. Wie es geht? Steht 1:1 im Family User Guide. Probiere es einfach aus. Wenn es nicht läuft, melde dich mit deinem Code wieder.
In der Initialisierung ist ein delay_cycles() in Ordnung. In der main loop dagegen wäre es unfein. Für die Interrupt-Lösung in deinem Code fehlt das globale Interrupt-Enable. _BIS_SR(LPM0_bits + GIE); sollte dir helfen. Max
:
Bearbeitet durch User
Ich wollte nicht den ganzen Code anhängen da ich mir dachte dass es zu unübersichtlich ist. Ich arbeite noch am delay, also kann es sein dass noch nicht alles korrekt ist.
Danke Max! Du hast mich in die richtige Richtung geführt. Mit dem LPM hat es nicht funktioniert aber auf den ersten Blick geht es mit __enable_interrupt(); Danke! Jetzt muss ich noch schauen ob ich das LCD zum laufen bring ;)
Zur Anregung hier ein Beispiel mit dem WDT
1 | #include "io430.h" |
2 | |
3 | typedef unsigned char uint8_t; |
4 | typedef unsigned int uint16_t; |
5 | |
6 | volatile uint16_t delaycount; |
7 | |
8 | |
9 | void delay (uint16_t time) |
10 | {
|
11 | delaycount = time / 8; |
12 | while (delaycount > 0) ; |
13 | }
|
14 | |
15 | void main( void ) |
16 | {
|
17 | // stop watchdog timer to prevent time out reset
|
18 | WDTCTL = WDTPW + WDTHOLD; |
19 | // clock source DCO, set to 1MHz
|
20 | BCSCTL1 = CALBC1_1MHZ; |
21 | DCOCTL = CALDCO_1MHZ; |
22 | // init port
|
23 | P1DIR |= BIT0; // Set P1.0 to output direction |
24 | // WDT Timer 8ms
|
25 | WDTCTL = WDT_MDLY_8; |
26 | // enable interrupts
|
27 | IE1 |= WDTIE; |
28 | __enable_interrupt(); |
29 | while(1) |
30 | {
|
31 | P1OUT |= BIT0; |
32 | delay (1000); |
33 | P1OUT &= ~BIT0; |
34 | delay (250); |
35 | }
|
36 | |
37 | }
|
38 | |
39 | //Watchdog Timer interrupt service routine
|
40 | #pragma vector=WDT_VECTOR
|
41 | __interrupt void WDT_ISR (void) |
42 | {
|
43 | if(delaycount > 0) |
44 | delaycount--; |
45 | }
|
Das geht natürlich besser. Solange das Delay läuft könnte man LPM aktivieren.
Danke für den Tip mit dem WDT, aber ich werde es jetzt mal mit dem Timer weiterverfolgen. Gibt es eine einfache Möglichkeit, die Zeit meines Delays zu überprüfen? Eine andere Frage habe ich auch noch zu meinem delay. Wenn ich das delay im main aufrufe scheint es zu funktionieren. Wenn ich es aber in einer ISR zum Entprellen eines Tasters verwenden möchte, gehts es nicht. Darf ich so überhaupt vorgehen?
Bernhard B. schrieb: > ich werde es jetzt mal mit dem Timer > weiterverfolgen Im Beispiel wird der WDT als Timer genutzt. Warum den kostbaren Timer A für so einfache Dinge verschwenden? Bernhard B. schrieb: > die Zeit meines Delays zu überprüfen Port Pin toggeln und messen. Bernhard B. schrieb: > Wenn ich es aber in einer > ISR zum Entprellen eines Tasters verwenden möchte, gehts es nicht. > Darf ich so überhaupt vorgehen? Du darfst auch durch Null teilen, aber du bekonmmst das nicht ans Laufen. ;-> Du erwartest in einer ISR einen anderen Interrupt. Geht das überhaupt? Wenn ja, wer darf wenn unterbrechen? Im Datenblatt gibt es eine Tabelle und im family user guide ein extra Kapitel. Eine ISR sollte nicht unnötig aufgebläht werden. Ein delay gehört da nicht rein.
Der Hintergrund für mein delay mittels Timer war ursprünglich folgendlich: Ich brauche eine Verzögerung für - das LCD - zum Tastenentprellen - ev. für noch andere Funktionen. Darum dachte ich mir dass es praktisch ist wenn ich mir eine "gescheite" delay-Funktion bastel die ich für alles verwenden kann.
Guter Gedanke. Leider läßt sich so nicht das Interruptverhalten des µC verändern. Aber ein delay in einer ISR ist nicht gut, nein, es ist sogar böse. :-D
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.