Forum: Mikrocontroller und Digitale Elektronik MSP430 Experimentirboard Buzzer


von Jochen (Gast)


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)
1
#include "msp430xG46x.h"
2
3
4
void main (void)
5
{
6
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
7
8
  P2DIR = 0xFF;  //P2 als Ausgang setzen
9
  P3DIR = 0xFF; //P3 als Ausgang setzen
10
  P3OUT = 0x00;
11
12
  P2OUT = 0x00; //LEDs 1&2 aus
13
  P2OUT = 0x02; // LED2 an
14
  P2OUT = 0x04; //LED2 aus und LED1 an
15
  P2OUT = 0x06; //beide LEDs an
16
  
17
  P3OUT = 0x20; //Das ist der Buzzer, er geht nur einmal kurz 
18
                      //und sehr leise an
19
}

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Jochen (Gast)


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...

von Jochen (Gast)


Lesenswert?

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

Jumper JP1 bleibt natürlich gesteckt...

von Stefan (Gast)


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.

von Jochen (Gast)


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...

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Jochen (Gast)


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...

von Andreas B. (buyman)


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)

von Jochen (Gast)


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?

von reflection (Gast)


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

von Stefan (Gast)


Lesenswert?

Für "Anfänger" durchaus empfehlenswert ist es mal die Codebeispiele von 
TI durch zu schauen:
http://focus.ti.com/mcu/docs/mcuprodcodeexamples.tsp?sectionId=96&tabId=1468

von Jochen (Gast)


Lesenswert?

Supi... :-)

Das funktioniert ja bestens....

Bleibt bei mir nur die Frage übrig,

Mit der lösung einer for-Schleife:
1
...
2
do
3
  {
4
  for (int i=0;i<50000;i++)
5
  P3OUT = 0x20;
6
  for (int k=0;k<50000;k++)
7
  P3OUT = 0x00;
8
  }
9
while (c == 0);
10
...

hat es nicht funktioniert.

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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Andreas B. (buyman)


Lesenswert?

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


1
do
2
  {
3
  for (unsigned int i=0;i<50000;i++);
4
  P3OUT = 0x20;
5
  for (unsigned int k=0;k<50000;k++);
6
  P3OUT = 0x00;
7
  }
8
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:
1
while (1)  //Endlosschleife
2
  {
3
  for (unsigned int i=0;i<50000;i++);
4
  P3OUT ^= 0x20;
5
  }

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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:
1
:
2
volatile unsigned int i;
3
:
4
do
5
  {
6
  for (i=0;i<50000;i++);
7
  P3OUT ^= 0x20;
8
  }
9
:

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
Noch kein Account? Hier anmelden.