mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP 430: Timer verwenden um Lautsprecher zu steuern?


Autor: Daniel Simic (daniel72)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

Ich habe hier bereits einmal gefragt, wie man Lautsprecher steuern kann. 
Dank diesem Forum konnte ich dann mein Programm entsprechend beenden.

Nun zur Generierung  von Tons verwende ich einfach ein Register in dem 
ich einen Startwert reinschiebe und dann dekrementiere bis auf Null. Das 
ist gleich auch meine Schleife in der ich dann Lautsprecher (ist auf Pin 
4 vom Port 2 angeschlossen) ein- bzw. ausschalte.
Das alles funktioniert gut.

Nun bin ich mir bewusst, dass es keine ideale Lösung ist, weil das 
Programm nur gerade mit dieser Prozessorgeschwindigkeit funktionieren 
würde. Wenn die Geschwindigkeit etwas schneller wäre, dann würde ich den 
Ton wahrscheinlich auch nicht mehr hören.

Daher denke ich, dass es gut wäre, wenn ich den Timer verwenden würde. 
Ich kann dann für jeden Ton genau ausrechnen, wie viele [ms] lang meine 
Schleife dauer soll damit ich entsprechenden Ton am Lautsprecher höre.

Diese Lösung würde dann unabhängig von Prozessorgeschwindigkeit 
funktionieren.

Nun wie hole ich mir die Timerwerte? In anderen Programmiersprachen 
(C/C++, NET, Java) hole ich mir die aktuelle Zeit und in jedem 
Schleifendurchgang berechne ich eine Differenz. So weiss ich wie lange 
die Schleife dauern soll (Wenn Differenz erreicht ist, dann wird 
Schleife beendet). Wie ist das aber mit Assembler bzw. MSP430?

Für einen Tipp bedanke ich mich bereits im Voraus.

Grüsse
DAniel

Autor: Ekschperde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die MSP430 sind eigentlich ein Multifunktionstimer mit einer
drangehängten 16-bit-CPU :-)

Da hilft nur ausgiebiges Studium des entsprechenden Family Users 
Manual
in Verbindung mit dem typspezifischen Datenblatt, ob die verwendete CPU
auch dieses oder jenes Feature unterstützt.
Was zugegenermassen gerade am Anfang ein wenig verwirrend ist.

Für die MSP430x2xxx-Serie z.B. also bei TI nach SLAU144 nach suchen.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Diese Lösung würde dann unabhängig von Prozessorgeschwindigkeit
>funktionieren.
Das würde ich so jetzt nicht generell sagen!
Wenn Du für MCLK (CPU) und für den Timer dieselbe Clock-Source 
ausgewählt hast und deren Frequenz änderst, läuft dein Timer nicht 
unabhängig von der CPU! Allerdings bietet das flexible Clock-Management 
des MSP430 genug Möglichkeiten, diese Unabhängigkeit zu realisieren 
(falls das überhaupt notwendig ist).

Der User-Guide ist in jedem Fall die erste Anlaufstelle als Lektüre.
Ich würde an Deiner Stelle mal über die Möglichkeit nachdenken, eine PWM 
als "Tonerzeugung" zu verwenden. Dazu gibt es auch genügend 
Codebeispiele von TI.

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

dafür verwendet man normal einen Timer im PWM oder Frequenzmodus 
(Up-Mode). Den muss man nur einmal konfigurieren und der Rest der 
Tonerzeugung passiert im Hintergrund, ohne dass die CPU benötigt wird. 
Wenn man den Ton wieder stoppen möchte, hält man entweder den Timer an 
oder man setzt die Portfunktion (PSELx) wieder von CCR auf Port um. Im 
Family Guide ist die Verwendung von Timern mit 
Capture-Compare-Rergistern zur Ausgabe von PWM und Frequenzen genau 
beschrieben, sogar mit Codebeispielen und Grafiken, wie die Waveform 
dann aussieht.

Du brauchst dafür Einstellungen in den Registern PSELx, TxCCRx, TARx, 
TxCTRL und noch ein paar anderen, aber die Benutzung ist nicht weiter 
kompliziert, wenn man das manual gelesen hat.

Grüße,

Peter

Autor: Daniel Simic (daniel72)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zuerst einmal vielen Dank an alle.

Ich habe nun ein kleines Beispiel gefunden:

mov.w     #TASSEL0+TACLR,&TACTL

mov.w     #OUTMOD_4,&CCTL0
mov.w     #30000,&CCR0

mov.w     #OUTMOD_7,&CCTL1
mov.w     #22500,&CCR1

mov.w     #OUTMOD_7,&CCTL2
mov.w     #7500,&CCR2

bis.b    #BIT1+BIT2+BIT3,&P1DIR
bis.b    #BIT1+BIT2+BIT3,&P1SEL
bis.w    #MC0,&TACTL

Problem dabei ist, dass mir P1IN (Pin 1,2 und 3) gesetzt werden. Auf 
meinem EDU Board ist aber Lautsprecher am Port 2 Pin 4 angeschlossen!

Ich suche jetzt seit einer Stunde, wie ich PWM auf Ausgangsport 2 Pin 4 
umleiten kann, aber habe leider nichts gefunden.

Auch wenn ich &P1DIR auf &P2DIR und &P1SEL auf &P2SEL ändere, geht's 
nicht, weil dann P2IN angesprochen wird (und ich brauche den als Ausgang 
und zwar Pin 4).

Gibt es also eine Möglichkeit den PWM Signal auf Ausgangsport 2 Pin 4 
umzuleiten? Wenn NEIN, wie kann ich dann vom Port P1IN auf P2OUT Pin 4 
umleiten?

Danke

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Gibt es also eine Möglichkeit den PWM Signal auf Ausgangsport 2 Pin 4
>umzuleiten? Wenn NEIN, wie kann ich dann vom Port P1IN auf P2OUT Pin 4
>umleiten?
Umleiten auf einen beliebigen Pin geht nicht!
Die Output-Einheit des Timers hat festgelegte Pins, die benutzt werden 
können. Dieses sind im Datenblatt aufgelistet (im Kapitel Timer).
Ohne Deinen genauen MSP430-Typ zu kennen, kann Dir da keiner weiter 
helfen.

Nur so als Bsp.:
Der MSP430F21x2 kann an P2.4 eine PWM ausgeben, wenn man Timer_0, 
CCR2-Compareregister benutzt und das TA2-Modul auf P2.4 ausgeben lässt.
Das Codebeispiel würde sich dann etwa so ändern:
mov.w     #TASSEL0+TACLR,&TACTL

mov.w     #OUTMOD_7,&CCTL2
mov.w     #7500,&CCR2          <- reset output
mov.w     #30000,&CCR0         <- set output


bis.b    #BIT4,&P2DIR
bis.b    #BIT4,&P2SEL
bis.w    #MC0,&TACTL

Es gibt aber auch andere MSP-Typen, die an P2.4 keinen Timer-Ausgang 
besitzen! Dann bliebe Dir weiterhin nur eine Software-PWM.

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

was Stefan sagt ist völlig korrekt, der MSP430 hat für jedes 
Capture-Compare-Register (CCR) nur bestimmte Pins die man in Verbindung 
mit diesem CCR als PWM-Ausgang verwenden kann. Das sind alle, die im 
Datenblatt mit TAx oder TBx gekennzeichnet sind, wobei x eine Ziffer 
ist. Es ist nicht optimal, den Lautsprecher an x=0 anzuschließen, das 
CCR0 hat eine Sonderstellung und wird meistens als Hilfsregister 
benutzt, z.B. als Umkehrwert für den Timer.

Damit wir dir helfen können, brauchen wir die genaue Bezeichnung des 
MSP430.

Grüße,

Peter

Autor: Daniel Simic (daniel72)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es handelt sich um MSP430F1232.

Laut ein paar Informationen aus dem Buch Mikrocontrollertechnik 
(Matthias Sturm), sollte er doch P2.4 ansprechen können.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Also es handelt sich um MSP430F1232.
Na dann haste aber Glück ;-)

Mein Bsp von oben sollte dann eigentlich funktionieren.

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

P2.4 ist TA2. D.h. du musst es so machen:

bis.b    #BIT4,&P2DIR
bis.b    #BIT4,&P2SEL

Das routet das CCRA2 auf P2.4.

Grüße,

Peter

Autor: Daniel Simic (daniel72)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, vielen Dank, das funktioniert jetzt auch. Ich höre schon etwas auf 
dem Lautsprecher :)

Nun musste ich ziemlich lange mit den Werten herumspielen, bis ich 
überhaupt einen Ton bekommen habe.

Noch eine letzte Frage hätte ich und zwar, was bedeuten die Werte von 
CCR0 bzw. CCR2. Momentan habe ich drin:

mov.w     #500,&CCR0
mov.w     #100,&CCR2

und man hört einen Ton. Wie soll ich die optimal setzen, dass auch ein 
normaler Ton generiert wird?

Ahh ja, und wie stoppe ich am einfachsten den Timer?

PS: Bei Werten #30000 und #7500,&CCR2 hört man dann nur das Knicken 
(wahrscheinlich weil die Frequenz sehr klein ist)!

Gruss

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Noch eine letzte Frage hätte ich und zwar, was bedeuten die Werte von
>CCR0 bzw. CCR2. Momentan habe ich drin:
CCR0 bestimmt die Frequenz Deines Tons.
Dein Timer läuft von 0 bis CCR0 und fängt dann wieder von 0 an...
Jedesmal, wenn er von CCR0 auf 0 überläuft, wird P2.4 gesetzt (high).
CCR2 bestimmt, wann P2.4 zurückgesetzt wird (low). Ich würde also in 
Deinem Fall CCR2 = CCR0/2 setzen, dann bekommst Du eine PWM mit 50% 
Duty-Cycle.

Jetzt hängt es nur noch von Deiner Clock-Source ab, welche Frequenz 
Deine PWM erzeugt. Timer_A Clock ist bei Dir ACLK (TASSEL0). Wenn nun an 
LFXT1 ein 32kHz-Uhrenquarz dranhängt, kommst Du auf ca. 65Hz.
Bei 1MHZ an LFXT1 wärens dann schon 2kHz PWM-Frequenz.

>Ahh ja, und wie stoppe ich am einfachsten den Timer?
z.B.
bic.w    #MC0+MC1,&TACTL

Autor: Daniel Simic (daniel72)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PERFEKT !!!

Vielen Dank es funktioniert nun alles wie gewünscht!!!

Schönen Abend noch!

Daniel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.