MSP430F16xx-- CAP-Modus im Timer B einstellen

OP #4613483
Lesenswert?

Leider komme ich mit meinem Problem, welches schon im 
Beitrag "MSP430F1610 und TIMER-B" beschrieben wurde, 
nicht weiter. Ich will die Impulslänge, welche ein 
Ultraschallabstandsmesser als Echo sendet, messen.
Mit dem Eingang TB0 (1.Gerät) funktioniert die Messung einwandfrei, 
während die Messung mit z.B. TB3 (2.Gerät) nicht läuft.
Offensichtlich reicht es nicht, nur die Register von TBCCTL0 auf z.B. 
TBCCTL3 umzustellen und  TBCCR3 auszulesen.
In dem Datenblatt zum MSP430F16xx  steht unter
„interrupt vector addresses“
Timer_B7 (see Note 5) TBCCR0 CCIFG (see Note 2) Maskable 0FFFAh 13
Timer_B7 (see Note 5) TBCCR1 to TBCCR6 CCIFGs, TBIFG (see Notes 1 & 2)
Maskable 0FFF8h 12

was ich leider nicht deuten kann. Ich entnehme nur, dass es einen 
Unterschied zwischen TBCCR0 und TBCCR1 bis TBCCR6 gibt.
Kennt sich jemand genauer damit aus und könnte mir helfen?
Angehängte Dateien:
#4613916
Lesenswert?

Das User's Guide sagt in Abschnitt 12.2.6:
> Two interrupt vectors are associated with the 16-bit Timer_B module:
> ☐ TBCCR0 interrupt vector for TBCCR0 CCIFG
> ☐ TBIV interrupt vector for all other CCIFG flags and TBIFG

oder <msp430f1610.h>:
> #define TIMERB1_VECTOR  (13)    /* 0xFFF8 Timer B CC1-6, TB */
> #define TIMERB0_VECTOR  (14)    /* 0xFFFA Timer B CC0 */

Für CCR3 darfst du also nicht TIMERB0_VECTOR nehmen.

Und außer für CCR0 werden die CCIFG-Bits nicht automatisch gelöscht. Das 
muss dein Code tun; siehe das User's Guide.
OP #4614361
Lesenswert?

Clemens L. schrieb:
> Für CCR3 darfst du also nicht TIMERB0_VECTOR nehmen.
>
> Und außer für CCR0 werden die CCIFG-Bits nicht automatisch gelöscht. Das
> muss dein Code tun; siehe das User's Guide.

Danke für die Hinweise.
Die Umstellung auf TIMERB1 sollte ja nicht das Problem sein.
Aber wie die CCIFG-Bits zu löschen sind, da hab ich wieder so meine 
Probleme.

Im Anhang mein "überarbeiteter" Programmschipsel mit der Fehlermeldung 
für die letzte Zeile:
>Error[Pe137]: expression must be a modifiable lvalue

Wie wäre es richtig?
Angehängte Dateien:
#4614524
Lesenswert?

Rufus Τ. F. schrieb:
> Das ist ein Bitwert

Nein, das ist die Nummer des Interrupts (mal zwei, damit man das direkt 
als Offset verwenden kann).

Das IFG-Bit kann man auf die übliche Art löschen:
1
TBCCTL3 &= ~CCIFG;

Aber wenn man mehrere Interrupts behandeln muss, nimmt man lieber das 
IV-Register:
1
switch (TBIV) {
2
case TBIV_TBCCR1:
3
    ...
4
    break;
5
case TBIV_TBCCR2:
6
    ...
7
    break;
8
case TBIV_TBCCR3:
9
    ...
10
    break;
11
...
12
}
Beim Lesen des TBIV-Registers wird das entsprechende IFG-Bit autmatisch 
gelöscht.
OP #4614551
Lesenswert?

Rufus Τ. F. schrieb:
> Wie ist das Register mit der Adresse 0x11E in Deiner Headerdatei
> definiert?

meinst Du damit diese Definitionen?
>* Timer B7
>************************************************************/
>#define _MSP430_HAS_TB7_ /* Definition to show that Module is available */

>#define TBIV_               (0x011E)  /* Timer B Interrupt Vector Word */
>READ_ONLY DEFW( TBIV           , TBIV_)
>#define TBCTL_              (0x0180)  /* Timer B Control */
>DEFW(   TBCTL             , TBCTL_)
>#define TBCCTL0_            (0x0182)  /* Timer B Capture/Compare Control 0 */
>DEFW(   TBCCTL0           , TBCCTL0_)

Ich habe es zusätzlich mal mit mspgcc probiert. Hier kommt zwar keine 
Fehlermeldung, aber das Programm hängt sich auf.

Da war ich zu langsam. Die weiteren Tips werde ich mal testen.
OP #4614825
Lesenswert?

So richtig verstanden habe ich zwar noch nicht alles, aber mein Programm 
läuft jetzt erst einmal wunschgemäß.
Verwendet habe ich:
>Das IFG-Bit kann man auf die übliche Art löschen:
>TBCCTL3 &= ~CCIFG;
Der 2. Teil wurde für einen evtl. späteren Gebrauch abgespeichert.
Für die Hilfe recht vielen Dank.
OP #4620542
Lesenswert?

wolle g. schrieb:
> aber mein Programm läuft jetzt erst einmal wunschgemäß.
Mit dieser Einschätzung war ich wohl etwas zu voreilig.

Das Programm läuft bei mir nur, wenn man jeweils nur einen HC SR04 
betreibe.
Ziel ist es aber, 2x HC SR04 an einem µC zu betreiben.
Wenn ich, wie im Anhang unter TimerA0, beide HC SR04 betreibe, dann ist 
das Messergenis des HC SR01-1 nur Müll.
HC SR04-2 behält aber seine brauchbaren Werte.
Wird nur HC SR01-1 getaktet, dann liefert auch dieser brauchbare Werte.
Kann mir noch einmal jemand helfen?
Angehängte Dateien:
OP #4621021
Lesenswert?

Clemens L. schrieb:
> Das kommt davon, wenn du TBCLR verwendest – das setzt den gesamten Timer
> auf Null, beeinflusst also auch alle CCRs.

Das war eigentlich auch so gedacht. Zuerst die Impulslänge von HC SR04-1 
erfassen (TB0) --> TBCCR0 lesen --> Timer auf Null setzen --> Pause und 
dann das Gleiche mit HC SR04-2 an TB3 wiederholen.
Da bin ich offensichtlich auf dem Holzweg.

>Um eine Zeitdauer zu messen, solltest du den Timer-Zähler vorher und
>nachher speichern (1. per Hand, 2. mit Capture-Event), und dann
>subtrahieren.
Das erscheint für mich zu hoch zu sein. z.B. Was soll per Hand gemacht 
werden?
Könntest Du vielleicht mein Programm versuchsweise  korrigieren?
#4621768
Lesenswert?

Innerhalb eines Interrupthandlers sind alle Interrupts erst einmal 
gesperrt. Der Code in Timer_A() sollte in die Hauptschleife verschoben 
werden.

Um die Schleife in regelmäßigen Abständen auszuführen, kann sich der 
Code dort schlafen legen und durch den TimerA-Interrupt-Handler 
aufwecken lassen.
OP #4649844
Lesenswert?

Nach einer „kleinen“ Pause melde ich jetzt wieder.
Clemens L. schrieb:
> Innerhalb eines Interrupthandlers sind alle Interrupts erst einmal
> gesperrt. Der Code in Timer_A() sollte in die Hauptschleife verschoben
> werden.
Ich habe mal mein Programm (leider immer noch erfolglos) umgebaut. Den 
Start und die Antwort habe ich in die while-Schleife  der Hauptschleife 
verlegt.
War es so gemeint?
Wird jeweils  nur 1 Ultraschallmesser gestartet, dann erscheint die 
Antwort plausibel. Sind beide, wie im umgebauten Programm, in Betrieb, 
dann gibt es unbrauchbare Messergebnisse.
MfG
Angehängte Dateien:
#4653501
Lesenswert?

Die beiden CCRs kommen sich immer noch in die Quere; TBCLR und das 
Start-Signal für den Sensor sind nicht synchonisiert.

Also konkret: beim Start und beim Ende wird der Zeitstempel gelesen:
1
  start1 = TBR;
2
  P4OUT &= ~BIT1;
3
  ...
Im Interrupt:
1
  ende1 = TBCCR0;
2
  ech1 = ende1 - start1;
Der Timer wird dabei nie auf 0 zurückgesetzt! (Und dann könnte man 
auch beide Messungen gleichzeitig machen.)

Und "volatile" fehlt bei den gemeinsam vom Hauptprogramm und 
Interrupt-Handlern benutzen Variablen.
Und Warteschleifen macht man besser mit __delay_cycles().
OP #4657343
Lesenswert?

Clemens L. schrieb:
> Der Timer wird dabei nie auf 0 zurückgesetzt! (Und dann könnte man
> auch beide Messungen gleichzeitig machen.)
>
> Und "volatile" fehlt bei den gemeinsam vom Hauptprogramm und
> Interrupt-Handlern benutzen Variablen.
> Und Warteschleifen macht man besser mit __delay_cycles().

Das sehe ich zum Teil etwas anders.

Im Prinzip habe ich nur meine Warteschleifen (pause) durch 
__delay_cycles() ersetzt und das überarbeitete Programm  funzt. Könnte 
man diesen Effekt erklären?
Noch zwei Fragen:
Warum sollte man "volatile" verwenden?
Wie hängen  __delay_cycles() und die Quarzfrequenz zusammen?

Im Anhang jetzt das in meinen Augen funktionstüchtige Programm. (Falls 
es jemanden interessiert)
Angehängte Dateien:
#4657403
Lesenswert?

wolle g. schrieb:
> Im Prinzip habe ich nur meine Warteschleifen (pause) durch
> __delay_cycles() ersetzt und das überarbeitete Programm funzt. Könnte
> man diesen Effekt erklären?

Offensichtlich waren die Warteschleifen zu kurz, oder wurden vom 
Compiler wegoptimiert.

> Warum sollte man "volatile" verwenden?

http://stackoverflow.com/q/246127/11654

> Wie hängen __delay_cycles() und die Quarzfrequenz zusammen?

Du hast MCLK auf 8 MHz konfiguriert, also 1 Takt = 125 ns.
OP #4657530
Lesenswert?

Clemens L. schrieb:
>> Warum sollte man "volatile" verwenden?
> http://stackoverflow.com/q/246127/11654
>> Wie hängen __delay_cycles() und die Quarzfrequenz zusammen?
> Du hast MCLK auf 8 MHz konfiguriert, also 1 Takt = 125 ns.

Danke.
Gibt es auch etwas ohne Frage- Antwortspiel und in deutsch?
und wann wird der Compiler ohne "volatile" etwas wegoptimieren?
Kann man das auch in wenigen Sätzen beschreiben?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren