kramann.info
© Guido Kramann

Login: Passwort:










Mikrocontroller
1 Einfuehrung
..1.1 Entwicklungsgeschichtliches
..1.2 Maschinensprache
..1.3 Assemblerbeispiel
..1.4 Sprachwahl
..1.5 Praxis
....1.5.1 Digital_IO
....1.5.2 Byteoperationen
....1.5.3 AVR_Studio
....1.5.4 Testboard
....1.5.5 Aufgaben
....1.5.6 Do_it_yourself
......1.5.6.1 Ampel
......1.5.6.2 Programmierer
..1.6 Literatur
..1.7 Programmierer
....1.7.1 Bauverlauf
....1.7.2 KurzreferenzLow
....1.7.2 Kurzreferenz_16PU
..1.8 Uebung1
..1.9 BoardAtHome
....1.9.1 Software
....1.9.2 Hardware
....1.9.3 Knoppix
....1.9.4 Aufbau
....1.9.5 LED
2 Oszillator
..2.1 Assembler
..2.2 Interner_RC
..2.3 Quarz
..2.4 Taktgenerator
3 DigitalIO
..3.1 Elektrische_Eigenschaften
..3.2 Pullup_Widerstaende
..3.3 Bitmasken_Eingang
..3.4 Bitmasken_Ausgang
..3.5 Tic_Tac_Toe
....3.5.1 DuoLEDs
....3.5.2 Schaltplan
....3.5.3 Spielfeld
....3.5.4 Anwahl
....3.5.5 Kontrolle
..3.6 Laboruebung2
..3.7 Zaehler
4 PWM
..4.1 Prinzip
..4.2 Nutzen
..4.3 Generierung
..4.4 Programmierung
..4.5 Servos
..4.7 Laboruebung3
..4.8 LoesungUE3
..4.9 Uebung6
5 LichtKlangKugeln
..5.1 LED
..5.2 RGB
..5.3 Sensoren
..5.4 lautsprecher
..5.5 tonerzeugung
6 UART
..6.1 Bussysteme
..6.2 UART
..6.3 RS232
..6.4 Hardware
..6.5 Senden
..6.6 Hyperterminal
..6.7 Empfangen
..6.8 Broadcast
..6.9 Uebung4
7 Infrarot
..7.1 schalten
..7.2 seriell
..7.3 Uebung
..7.4 Cloud
8 OOP
..8.1 Ansatz
..8.2 Uebung
..8.3 Statisch
..8.4 Datentypen
..8.5 RS232
....8.5.1 Prozedural
....8.5.2 Analyse
....8.5.3 Umsetzung
....8.5.4 Vererbung
....8.5.5 Statisch
....8.5.6 Performance
..8.6 Fahrzeug
9 ADW
..9.1 ADW
..9.2 Zufallsgenerator
..9.3 Sensoren
..9.4 Musterloesung
10 Cloud
11 SPI
..11.1 Testanordnung
..11.2 Register
..11.3 Test1
..11.4 Test2_Interrupt
..11.5 Test3_2Slaves
..11.6 Laboruebung
12 EEPROM
13 I2C
..13.1 MasterSendByte
..13.2 MasterSend2Bytes
..13.3 MasterReceiveByte
..13.4 MasterReceive2Bytes
14 Anwendungen
..14.1 Mechatroniklabor
....14.1.1 Biegelinie
....14.1.2 Ausbruchsicherung
....14.1.3 Einachser
....14.1.4 AV
....14.1.5 Vierradlenkung
....14.1.6 Kommunikation
..14.2 Sinuserzeugung
....14.2.1 Variante1
....14.2.2 Variante2
....14.2.3 Variante3
....14.2.4 Variante4
..14.3 Laboruebung8
..14.4 Loesung_Ue8
..14.5 SPI_Nachtrag
20 Xubuntu

5.5 Tonerzeugung mit der Licht-Klangkugel

Zum besseren Verständnis der Tonerzeugung werden nun ausgehend von einem sehr einfachen Programm immer aufwändigere Programme zur Toerzeugung entwickelt.

Die Quelltexte der folgenden Programm sind nicht bei SNIPPETS_KLANGKUGEL mit dabei, sondern können hier nachfalgend heruntergeladen werden:

tonerzeugung.zip -nachfolgende Beispielprogramme.

ton001 - Ansteuerung über den digitalen Ausgang PD6

#include<avr/io.h>
#include<avr/interrupt.h>


void init()
{     
   DDRA = 0;
   DDRB = 0;
   DDRC = 0;
   DDRD = 0;

   PORTA = 0;
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;   

   //Für Ton PD6 als digitalen Ausgang setzen, PD7 als digitalen Eingang:
   DDRD |= 0b01000000;
}

int main(void)                    
{   
    unsigned char ton_ein = 0; 
    unsigned long pause=0;
    init();

    while(1)
    {
        for(pause=0;pause<400;pause++)
            DDRC=0;
        PORTD|=0b01000000;
        for(pause=0;pause<400;pause++)
            DDRC=0;
        PORTD&=0b10111111;
    }//Ende while(1)
}

Code 5.5-1: Quelltext von ton001.

Es entsteht ein tiefer Ton mit konstanter Lautstärke, da ein Rechtecksignal auf PD6 ausgegeben wird. Um eine definierte Tonhöhe festlegen zu können, wird nun der Timer 0 eingesetzt. Beim folgenden Programm ton002 wird ein Ton von exakt 1000Hz erzeugt.

#include<avr/io.h>
#include<avr/interrupt.h>


void init()
{     
   DDRA = 0;
   DDRB = 0;
   DDRC = 0;
   DDRD = 0;

   PORTA = 0;
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;   

   //Für Ton PD6 als digitalen Ausgang setzen, PD7 als digitalen Eingang:
   DDRD |= 0b01000000;

   //Zeitbasis mit Timer0:
   //Vorteilung 8, Obere Zählgrenze 125 => 1000000Hz/(8*125)= 1000Hz für einen Zählzyklus
   TCCR0 = (0<<FOC0) | (0<<WGM00) | (0<<COM01) | (0<<COM00) | (1<<WGM01) | (0<<CS02) | (1<<CS01) | (0<<CS00);
   OCR0=125;
}

int main(void)                    
{   
    init();

    while(1)
    {
        if(TCNT0<62) 
            PORTD|=0b01000000;
        else
            PORTD&=0b10111111;
    }//Ende while(1)
}

Code 5.5-2: Quelltext von ton002.

Über ein PWM-Signal auf PD7 / OC2 kann dem Ton eine Hüllkurve verliehen werden und so ein lebendigerer Klang erzeugt werden. Dies wird durch die besondere Verschaltung zwischen PD6, PD7 und dem Lautsprecher ermöglicht. In der nachfolgenden Schaltung ist der beteiligte Ausschnitt der Elektronik dargestellt.

Anschluß des Lautsprechers bei der Licht- Klangkugel.

Bild 5.5-1: Anschluß des Lautsprechers bei der Licht- Klangkugel.

In folgendem Programm wird für jeden Ton über den Wert von OCR2 eine Hüllkurve erzeugt. Der entsprechende Ton klingt so, als würde er angeschlagen und dann verklingen. Über die Variable obergrenze wird zudem die Tonhöhe nach jedem "Anschlagen" verändert.

#include<avr/io.h>
#include<avr/interrupt.h>


void init()
{     
   DDRA = 0;
   DDRB = 0;
   DDRC = 0;
   DDRD = 0;

   PORTA = 0;
   PORTB = 0;
   PORTC = 0;
   PORTD = 0;   

   //Für Ton PD6 und PD7 als digitalen Ausgang setzen:
   DDRD |= 0b11000000;

   //Zeitbasis mit Timer0:
   //Vorteilung 64, Obere Zählgrenze 125 => 1000000Hz/(64*125)= 125Hz für einen Zählzyklus
   TCCR0 = (0<<FOC0) | (0<<WGM00) | (0<<COM01) | (0<<COM00) | (1<<WGM01) | (0<<CS02) | (1<<CS01) | (1<<CS00);
   OCR0=125;

   //Das PWM-Signal von Timer2 geht über Pin 21 (PD7, OC2) auf blau2
   //und wird hier auch für das Dimmen konfiguriert:
   TCCR2 = (0<<FOC2) | (1<<WGM20) | (1<<COM21) | (0<<COM20) | (0<<WGM21) | (0<<CS22) | (0<<CS21) | (1<<CS20);
   OCR2 = 0; //Pulsbreite 0..255, 255==maximale Helligkeit, 0==dunkel.
   //hier ist es o.k., wenn PC1 auf 0 gesetzt ist.
}

int main(void)                    
{   
    unsigned int zaehler = 0;
    unsigned char obergrenze = 125;
    init();

    while(1)
    {
        if(TCNT0<(obergrenze>>1)) 
            PORTD|=0b01000000;
        else
            PORTD&=0b10111111;


        if(zaehler<100)
            OCR2=zaehler;
        else
            OCR2=100-zaehler/30;

        zaehler++;
        if(zaehler>3000)
        {
            zaehler = 0;
            obergrenze+=20;
            if(obergrenze>200)
                obergrenze=125;
            OCR0 = obergrenze;
        }
    }//Ende while(1)
}

Code 5.5-3: Quelltext von ton003.

Übung
  • Entwickeln Sie ein Konzept, um die Frequenz eines Tones auswählen zu können. Es reicht dabei, dass eine Reihe an Obertönen darstellbar sind, also z.B. 200Hz, 400Hz, 600Hz, 800Hz usw.
  • Lassen Sie dann eine Weiterentwicklung dieses Programms ein beliebige Abfolge dieser Töne mit Hüllkurve spielen.
  • Suchen Sie nun nach einem Konzept, mit dem sich auf möglichst einfache, Recourcen sparende Weise möglichst wohlklingende Töne realisieren lassen.