www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 Experimentirboard Buzzer


Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte den Buzzer (SP1) vom TI ExperimantoerBoard ansteuern.

Jetzt habe ich P§ als Ausgang gesetzt und bekomme aber nur ein ganz 
leises "klick" vom Buzzer zu hören.
Das "klick" ist auch nur ganz kurz und dann verstummt der Buzzer wieder.
Mit dem Buzzer soll später ein Schalter auf sienen Zustand überwacht 
werden und der Buzzer dann als Alarmsignal so lange laut piepsen, bis 
der Schalter wieder zurückgesetzt wurde.

Hab euch hier mal mein "Spiel-Programm" (is mit blödsinnigem Zeugs 
versehen zum Testen)


#include "msp430xG46x.h"


void main (void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P2DIR = 0xFF;  //P2 als Ausgang setzen
  P3DIR = 0xFF; //P3 als Ausgang setzen
  P3OUT = 0x00;

  P2OUT = 0x00; //LEDs 1&2 aus
  P2OUT = 0x02; // LED2 an
  P2OUT = 0x04; //LED2 aus und LED1 an
  P2OUT = 0x06; //beide LEDs an
  
  P3OUT = 0x20; //Das ist der Buzzer, er geht nur einmal kurz 
                      //und sehr leise an
}



Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der "Buzzer" ist ein Lautsprecher. Damit da ein Ton rauskommt, muss 
schon eine Wechselspannung angelegt werden.
Du musst also entweder im Timerinterrupt den Pin P3.5 zwischen 0 und 1 
hin- und herschalten, dann bestimmt die Frequenz des Timerinterrupts die 
des Tones (genauer: Der Ton hat die halbe Frequenz des Timerinterrupts) 
oder aber sehen, daß Du auf P3.5 den Ausgang einer der 
Capture-Compare-Units eines der Timer geschaltet bekommst, dann kann der 
Timer den Lautsprecher ansteuern.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha...da ich (noch) absoluter Neuling bin, versteh ich aktuell nur so n 
bisschen wie ich das umsetzen kann...

Hab mal ne Schleife eingebaut und nun macht der Buzzer auch was:

...
int c = 0;  //definieren von "c" für die Schleife
...
do  //Beginn der Endlosschleife
  {
  P3OUT = 0x20;  //Buzzer ein
  P3OUT = 0x00;  //Buzzer aus
  }
while (c == 0);  //Ende der Endlosschleife
...

Jetzt hab ich damit aber noch Probleme...

Zum Einen wie bekomm ich ne andere Frequenz hin, damit der Buzzer einen 
lauten Alarmton von sich gibt?

Und warum brummt der Buzzer nur dan, wenn ich dem MSP430FG4618 den Saft 
vom Board nehme...also Jumper1 abziehe? Der Buttarie-Jumper bleibt 
nactürlich gesetzt...

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm...kleiner Fehler...der Buzzer summt nur dann wenn der Jumper PWR1 
abgezogen ist ;-)

Jumper JP1 bleibt natürlich gesteckt...

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würd mal sagen, Dein Hörbereich erstreckt sich bis max. 20kHz.
Deine Schleife wird aber sicherlich mit einigen 100kHz ausgeführt!
Beim Abziehen der Vcc passiert nur noch undefinierter Murcks.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich kann suchen wo und wie ich will...aber zum Einstellen der 
Frequenz für den Buzzer(-klang) find ich echt nix...

Kann mir da bitte geholfen werden?

Bisher habe ich nur LEDs usw. ein, bzw. wieder ausgeschaltet...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also ich kann suchen wo und wie ich will...aber zum Einstellen der
> Frequenz für den Buzzer(-klang) find ich echt nix...

Nicht? Das ist die Frequenz, mit der Du P3.5 ein- und ausschaltest. Also 
die Frequenz, in der Dein Controller durch die Endlosschleife rauscht.

Mach, wie ich es Dir gesagt habe: Nimm einen Timer und pack das 
Umschalten von P3.5 in den Timerinterrupt.

Und zwar Umschalten, nicht sofort nacheinander ein- und wieder 
ausschalten.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich weiß auch nicht...aber mit dem Thema Timer hatte ich gestern 
schon so meine Mühen...

Hast du mir ein Beispiel wie ich den Timer hier einsetze?

Wälz mich hier von Buch zu Buch und Internetseite zu Internetseite...
Bin einfach urlaubsrief...(naja noch 3 Tage dan gehts ja los :-) )

Also...wäre klasse wenn du mir da helfen kannst ;-)

Danke schon mal im Vorraus...

Autor: Andreas B. (buyman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly wrote:
> Nicht? Das ist die Frequenz, mit der Du P3.5 ein- und ausschaltest. Also
> die Frequenz, in der Dein Controller durch die Endlosschleife rauscht.
>
> Mach, wie ich es Dir gesagt habe: Nimm einen Timer und pack das
> Umschalten von P3.5 in den Timerinterrupt.
>
> Und zwar Umschalten, nicht sofort nacheinander ein- und wieder
> ausschalten.

So wäre es natürlich schön und sehr genau (von der Frequenz her) gelöst 
- allerdings nicht unbedingt Anfänger geeignet.

Ich würde zuerst eine kleine Delay-Schleife in die Endlosschleife 
einfügen und nach Try & Error prinzip eine passende Frequenz finden. 
Danach kann er es ja Interruptgesteuert versuchen :)
(Vorausgesetzt er ist des Lesen eines Datenblattes bzw. des User's Guide 
fähig)

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also...hab jetzt versucht mich durch den User-Guide zu lesen.

Ist TimerA der richtige?

Vom Prinzip setze ich den Timer mit meiner gewünschten Frequenz, starte 
ihn anschließend und lasse dann durch den Timer meinen gewünschten 
Ausgang toggeln?
Ist das soweit richtig?

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum testen kannst Du ja einfach ein Delay programmieren und das zwischen 
dem Ein-, resp. Ausschalten des Buzzers ablaufen lassen

void warte(unsigned int zeit)
{
  for (; zeit> 0;zeit--)
  {
    int i;
    i = 130;
    do (i--);
    while (i != 0);
  }
}


do  //Beginn der Endlosschleife
  {
  P3OUT = 0x20;  //Buzzer ein
  warte(1000);
  P3OUT = 0x00;  //Buzzer aus
  warte(1000);
  }
while (c == 0);  //Ende der Endlosschleife

Ich habe zwei Schleifen ineinander programmiert da ich so mit dem mir 
zur Verfügung stehenden Quarz eine nachvollziehbare Zeitbasis habe 
(natürlich nur so lange keine Interrupts auftreten).

Gruss reflection

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für "Anfänger" durchaus empfehlenswert ist es mal die Codebeispiele von 
TI durch zu schauen:
http://focus.ti.com/mcu/docs/mcuprodcodeexamples.t...

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Supi... :-)

Das funktioniert ja bestens....

Bleibt bei mir nur die Frage übrig,

Mit der lösung einer for-Schleife:
...
do
  {
  for (int i=0;i<50000;i++)
  P3OUT = 0x20;
  for (int k=0;k<50000;k++)
  P3OUT = 0x00;
  }
while (c == 0);
...

hat es nicht funktioniert.

Die for-Schleife macht doch aber eigentlich nichts anderes...also auch 
eine Zeitverzögerung...oder bin ich da aufm Holzweg?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist TimerA der richtige?

Ja, den kannst Du nehmen. Ebenso geht aber auch Timer_B, wenn denn Dein 
MSP430-Derivat einen hat.

> Vom Prinzip setze ich den Timer mit meiner gewünschten Frequenz,
> starte ihn anschließend und lasse dann durch den Timer meinen
> gewünschten Ausgang toggeln?
> Ist das soweit richtig?

Im Prinzip ja. Du musst eine Timerinterruptroutine schreiben, das ist 
eine Funktion, die beim Ablauf des Timers aufgerufen wird. In dieser 
schaltest Du dann P3.5 um.

Den Timer programmierst Du so, daß Du zunächst die Taktquelle festlegst, 
also ACLK, SMCLK oder MCLK. Dann kannst Du einen Eingangsteiler 
festlegen (/1 bis /8). Mit der so erzeugten Frequenz zählt der Timer. Du 
kannst nun einen (16-Bit-)Wert vorgeben, bis zu dem der Zähler zählt, 
bevor er überläuft und sich auf 0 setzt, um wieder von vorne anzufangen.

Angenommen, Du versorgst den Timer mit MCLK (das ist der Takt, mit dem 
der CPU-Teil des Controllers läuft), der bei 8 MHz liegt und verwendest 
einen Vorteiler /8. Dann zählt Dein Timer mit 1 MHz Taktrate; jeder 
Zählvorgang dauert also 1 µs. Wenn Du als Ablaufwert 199 einträgst, dann 
zählt der Zähler 200 µs lang, bevor er umspringt. Damit erzeugst Du ein 
5 kHz-Signal.
Löst Du damit einen Interrupt aus und toggelst im Interrupt Deinen 
Lautsprecherausgang, so erzeugst Du damit effektiv ein Rechtecksignal 
mit 2.5 kHz, was ein recht hochfrequentes Quietschen sein dürfte.

Übliche Quarzwecker arbeiten mit 1 kHz; Du musst also den Timer auf 2 
kHz Interruptrate anpassen. Also: Ablaufwert 499 verwenden.


Wenn P3.5 aber auch der Ausgang einer der Capture/Compare-Einheiten von 
Timer_A/Timer_B ist (-> steht im Datenblatt), dann kannst Du auch die 
Capture/Compare-Einheit so programmieren, daß die das Umschalten selbst 
übernimmt, dann musst Du keine Interruptroutine schreiben.

Derzeit ist der TI-Server irgendwie gestört, daher kann ich mir das 
Datenblatt nicht ansehen.

Autor: Andreas B. (buyman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jochen wrote:
> Supi... :-)
>
> Das funktioniert ja bestens....
>
> Bleibt bei mir nur die Frage übrig,
>
> Mit der lösung einer for-Schleife:
>
>
> ...
> do
>   {
>   for (int i=0;i<50000;i++)
>   P3OUT = 0x20;
>   for (int k=0;k<50000;k++)
>   P3OUT = 0x00;
>   }
> while (c == 0);
> ...
> 
>
> hat es nicht funktioniert.
>
> Die for-Schleife macht doch aber eigentlich nichts anderes...also auch
> eine Zeitverzögerung...oder bin ich da aufm Holzweg?


do
  {
  for (unsigned int i=0;i<50000;i++);
  P3OUT = 0x20;
  for (unsigned int k=0;k<50000;k++);
  P3OUT = 0x00;
  }
while (c == 0);

Du hast den ; nach den For-Schleifen vergessen. So hast du P3OUT zuerst 
50000 Mal 0x20 zugewiesen - anschließend 50000 Mal 0x00 (die Sache mit 
signed und unsigned int habe ich bei der Betrachtung zur Vereinfachung 
außer Acht gelassen)

Oder etwas eleganter:
while (1)  //Endlosschleife
  {
  for (unsigned int i=0;i<50000;i++);
  P3OUT ^= 0x20;
  }

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Andreas K.
>Du hast den ; nach den For-Schleifen vergessen.
Macht eigentlich nichts, ausser die for-Schleife noch langsamer, weil 
50000mal der Port gesetzt und danach 50000mal wieder zurückgesetzt wird.
War aber sicher so nicht beabsichtigt...

Jetzt ist nur noch die Frage, ob der Compiler optimiert...
Dann wäre besser so zu schreiben:
:
volatile unsigned int i;
:
do
  {
  for (i=0;i<50000;i++);
  P3OUT ^= 0x20;
  }
:

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.