Hallo,
ich habe eine Sleep-Funktion mit Timer im Up-Mode erstellt. Zur Zeit
arbeite ich noch mit 1 MHz, Source SMCLK. Ohne Teiler komme ich so auf
max. 65,535 ms. Deshalb arbeite ich mit Overflow um den Sleep erweitern
zu können. Die Dauer wird in Millisekunden eingegeben und dann mit 1024
multipliziert um auf Takte zu kommen. Die Ungenauigkeit von 2,4% ist
unerheblich, zudem auch Laufzeiten eine Rolle spielen.
Im Sekunden-Takt funktioniert die Funktion relativ genau. Probleme gibt
es wenn TA0CCR0 = 1 gesetzt wird. Dann bleibt das Programm beim Return
der Sleep-Funktion stehen.
Aber es gibt schon zuvor eine Unstimmigkeit, aus meiner Sicht. In der
Interrupt-Funktion habe ich Breakpoints gesetzt um den Ablauf zu prüfen.
TA0CCR0 = 2 ist jetzt auf gesetzt. Es wird zunächst erwartungsgemäss
0x0A, der Overflow, ausgeführt. overflow_loops und overflow_rest stehen
auf 0. Der low power mode wird beendet.
Aber, Interrupt-Funktion wird nochmals aufgerufen, TA0IV ist 0 (No
interrupt pending). Wie kann dies sein????
Bei TA0CCR0 = 2 geht es dann munter weiter, overflow .... No interrupt
pending .... overflow ....
Bei TA0CCR0 = 1 sieht es so aus, overflow .... No interrupt pending ....
overflow .... hängen beim Return der Sleep-Funktion
Fragen: muss das Clear - Flag gesetzt werden? Fehlt irgendwo noch eine
Pause wie __no_operation()???
mfg klaus
TA0IV gilt nur für Interrupts, die am TIMER0_A1_VECTOR ankommen.
Du solltest dich entscheiden, ob du TA0CTL.TAIE oder TA0CCTL0.CCIE haben
willst.
Und ID/IDEX wäre einfacher, als Überläufe manuell zu behandeln.
Vielen Dank für Deine Antwort.
Clemens L. schrieb:> TA0IV gilt nur für Interrupts, die am TIMER0_A1_VECTOR ankommen.>
Ist doch in Ordnung, oder?
> Du solltest dich entscheiden, ob du TA0CTL.TAIE oder TA0CCTL0.CCIE haben> willst.>
Wie mache ich das?
> Und ID/IDEX wäre einfacher, als Überläufe manuell zu behandeln.
Kannst Du das mal ausführlicher erläutern? ID/IDEX sagt mir im Moment
nichts.
mfg klaus
Klaus R. schrieb:> Clemens L. schrieb:>> TA0IV gilt nur für Interrupts, die am TIMER0_A1_VECTOR ankommen.>> Ist doch in Ordnung, oder?
Nein, weil du nicht TIMER0_A1_VECTOR sondern TIMER0_A0_VECTOR benutzt.
Siehe Abschnitt 12.2.6 des User's Guide.
>> Du solltest dich entscheiden, ob du TA0CTL.TAIE oder TA0CCTL0.CCIE haben>> willst.>>> Wie mache ich das?
Indem du eines dieser Bits setzt, und das andere nicht. Und dann den
richtigen Interrupt behandelst.
> ID/IDEX sagt mir im Moment nichts.
Siehe Abschnitt 12.2.1.1 des User's Guide. Allerdings hat dein
unbekannter Chip wahrscheinlich kein IDEX.
Hallo Clemens,
ich habe den MSP430G2553 und das User-Guide SLAU144J. Im CCS habe ich
über den Resource Explorer gesehen, dass ich damit aktuell bin.
Clemens L. schrieb:> Klaus R. schrieb:>> Clemens L. schrieb:>>> TA0IV gilt nur für Interrupts, die am TIMER0_A1_VECTOR ankommen.>>>> Ist doch in Ordnung, oder?>> Nein, weil du nicht TIMER0_A1_VECTOR sondern TIMER0_A0_VECTOR benutzt.> Siehe Abschnitt 12.2.6 des User's Guide.>
Mit TIMER0_A1_VECTOR lande ich in ISR_TRAP.ASM. Das Sample
msp430g2xx3_ta_02.c den TIMER0_A0_VECTOR.
Im Abschnitt 12.2.6 des User's Guide finde ich leider Angabe über die
Zuordnung von Variablen und Vektoren. Es ist ziemlich frustrierend sich
die Infos aus den Samples herauszuholen. Die geben ja auch nicht alles
wieder.
>>> Du solltest dich entscheiden, ob du TA0CTL.TAIE oder TA0CCTL0.CCIE haben>>> willst.>>>>> Wie mache ich das?>> Indem du eines dieser Bits setzt, und das andere nicht. Und dann den> richtigen Interrupt behandelst.>
Ich möchte eigentlich den TA0CTL.TAIE nehmen und dann über TA0IV den
overflow behandeln. Wenn ich den TA0CCTL0.CCIE nicht setze komme ich in
TIMER0_A0_VECTOR aber nicht hinein.
>> ID/IDEX sagt mir im Moment nichts.>> Siehe Abschnitt 12.2.1.1 des User's Guide. Allerdings hat dein> unbekannter Chip wahrscheinlich kein IDEX.
Da steht bei mir nur:
1
12.2.1.1 Clock Source Select and Divider
2
The timer clock can be sourced from ACLK, SMCLK, or externally via TACLK or INCLK. The clock source
3
is selected with the TASSELx bits. The selected clock source may be passed directly to the timer or
4
divided by 2, 4, or 8, using the IDx bits. The timer clock divider is reset when TACLR is set.
Klaus R. schrieb:> Im Abschnitt 12.2.6 des User's Guide finde ich leider Angabe über die> Zuordnung von Variablen und Vektoren.
Siehe auch den Abschnitt "Interrupt Vector Addresses" des Datenblatts
und die xxx_VECTOR-Definitionen am Ende von msp430g2553.h.
> Ich möchte eigentlich den TA0CTL.TAIE nehmen und dann über TA0IV den> overflow behandeln.
Dann brauchst du TIMER0_A1_VECTOR.
> Mit TIMER0_A1_VECTOR lande ich in ISR_TRAP.ASM.
Weil du TA0CCTL0.CCIE auch gesetzt hast; dann springt die CPU beim
Erreichn des CCR0-Wertes auch zu TIMER0_A0_VECTOR.
> Das Sample msp430g2xx3_ta_02.c den TIMER0_A0_VECTOR.
Weil es (nur) TA0CCTL0.CCIE benutzt.
__interruptvoidTIMERA0_ISR(void)// Flag cleared automatically
15
{
16
__low_power_mode_off_on_exit();
17
}
Es wurde bei der Messung der Sleep-Dauer klar, mit 1 MHz SMCLK-Takt wird
es erst ab 1 ms (TA0CCR0 = 1000) genauer. Darunter spielt die Laufzeit
eine zunehmende Rolle. Ich werde vermutlich auf 8 MHz oder vielleicht 16
MHz gehen. Aber das wird sich noch zeigen.
Nochmals vielen Dank für Deine Geduld.
mfg klaus
Klaus R. schrieb:> Im Abschnitt 12.2.6 des User's Guide finde ich leider Angabe über die> Zuordnung von Variablen und Vektoren.
???
Dort steht:
12.2.6 Timer_A Interrupts
Two interrupt vectors are associated with the 16-bit Timer_A module:
• TACCR0 interrupt vector for TACCR0 CCIFG
• TAIV interrupt vector for all other CCIFG flags and TAIFG
...
12.2.6.3 TAIV Software Example
...
Was braucht man noch?
Klaus R. schrieb:> brauchte ich noch die Hilfe eines MSP430 - Buches
Natürlich muss man sich mit dem Thema beschäftigen. Das fliegt dir nicht
nachts zu. :-<
Klaus R. schrieb:> switch(TA0IV)
probier mal
switch (__even_in_range(TAIV, 0x0A))
und damit für Dritte das Ganze besser zu lesen ist, nutze die defines
aus dem header file anstatt der Werte
/* T0_A3IV Definitions */
#define TA0IV_NONE (0x0000) /* No Interrupt pending */
#define TA0IV_TACCR1 (0x0002) /* TA0CCR1_CCIFG */
#define TA0IV_TACCR2 (0x0004) /* TA0CCR2_CCIFG */
#define TA0IV_6 (0x0006) /* Reserved */
#define TA0IV_8 (0x0008) /* Reserved */
#define TA0IV_TAIFG (0x000A) /* TA0IFG */
jöjöjö schrieb:> Klaus R. schrieb:>> Im Abschnitt 12.2.6 des User's Guide finde ich leider Angabe über die>> Zuordnung von Variablen und Vektoren.>> ???>> Dort steht:> 12.2.6 Timer_A Interrupts> Two interrupt vectors are associated with the 16-bit Timer_A module:> • TACCR0 interrupt vector for TACCR0 CCIFG> • TAIV interrupt vector for all other CCIFG flags and TAIFG> ...> 12.2.6.3 TAIV Software Example> ...>> Was braucht man noch?>
Ja das ist ja genau das Dilemma. Im Headerfile msp430g2553.h finde ich
zwar die Namen der Vektoren, aber welchen Interrups sind die zugeordnet?
Jetzt mit meinen neuen Informationen könnte ich ja raten.
TIMER0_A0_VECTOR ..... /* 0xFFF2 Timer0_A CC0 */
TIMER0_A1_VECTOR ..... /* 0xFFF0 Timer0)A CC1, TA0 */
TIMER1_A0_VECTOR ..... /* 0xFFFA Timer1_A CC0 */
TIMER1_A1_VECTOR ..... /* 0xFFF8 Timer1_A CC1-4, TA1 */
Auch die Namen der dazugehörigen ISR-Funktionen werden wohl mal mit und
ohne dem Zusatz _ISR geschrieben.
> probier mal> switch (__even_in_range(TAIV, 0x0A))>
Diesen Ausdruck verwendet John Davies im besagten Buch auch stetig.
Spart man sich wirklich so viel Laufzeit?
> und damit für Dritte das Ganze besser zu lesen ist, nutze die defines> aus dem header file anstatt der Werte
Ich hatte es quasi aus den Samples von TI übernommen, finde die Defines
aber auch lesbarer.
Besten Dank.
Klaus
Klaus R. schrieb:>> • TACCR0 interrupt vector for TACCR0 CCIFG>> • TAIV interrupt vector for all other CCIFG flags and TAIFG>> Im Headerfile msp430g2553.h finde ich zwar die Namen der Vektoren,> aber welchen Interrups sind die zugeordnet?
Einer für CCR0, der andere für alle anderen CCRs und TA.
Mit zwei TimerA-Modulen sind das dann vier Interrupt-Vektoren:
> TIMER0_A0_VECTOR ..... /* 0xFFF2 Timer0_A CC0 */> TIMER0_A1_VECTOR ..... /* 0xFFF0 Timer0)A CC1, TA0 */> TIMER1_A0_VECTOR ..... /* 0xFFFA Timer1_A CC0 */> TIMER1_A1_VECTOR ..... /* 0xFFF8 Timer1_A CC1-4, TA1 */
Und die Vektor-Adressen kannst du auch im Datenblatt nachschlagen.
(Die Namen der Timer-Symbole sind historisch gewachsen und deshalb sehr
inkonsistent.)
> Auch die Namen der dazugehörigen ISR-Funktionen werden wohl mal mit und> ohne dem Zusatz _ISR geschrieben.
Der Name der ISR-Funktion ist egal.
>> switch (__even_in_range(TAIV, 0x0A))>> Spart man sich wirklich so viel Laufzeit?
Das kommt auf den Compiler an.