-         

Ergebnis 1 bis 8 von 8

Thema: Tonausgabe über µC

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    28.12.2011
    Alter
    23
    Beiträge
    11

    Tonausgabe über µC

    Anzeige

    Hi,
    Bräuchte mal eure Hilfe.
    Ich habe an meiner C-Control Mega 128 ein Lautsprecher angeschlossen. Er befindet sich an einem PWM Ausgang mit Tiefpass.
    In einem Array hab ich eine Sinustabelle angelegt, die den Sinusverlauf als PWM-Werte (0-255) wiedergibt.
    Eigentlich muss ich jetzt ja nur noch die Frequenz es Sinus für verschiedene Töne ändern... Aber genau hier liegt das
    Problem. Im Prinzip gibt es ja zwei möglichkeiten das zu tun entweder ein Sleep zwischen dem Abfragen der Sinus-werte oder mann überspringt einfach ab und zu
    ein paar Werte des Arrays.
    Aber irgendwie klappt das nicht so, ich meine ich kann keine verschiedenen Töne erzeugen.

    Code:
    int delval;                      // globale Variablendeklaration
    float i;
    int counter;
    float rate;
    
    int Sinustabele[256] = {
      127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,
      176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,
      217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,
      244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,
      254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,
      244,243,242,240,239,238,236,234,233,231,229,227,225,223,221,219,
      217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,
      176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,
      127,124,121,118,115,111,108,105,102, 99, 96, 93, 90, 87, 84, 81,
       78, 76, 73, 70, 67, 64, 62, 59, 56, 54, 51, 49, 46, 44, 42, 39,
       37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 16, 15, 14, 12, 11,
       10,  9,  7,  6,  5,  5,  4,  3,  2,  2,  1,  1,  1,  0,  0,  0,
        0,  0,  0,  0,  1,  1,  1,  2,  2,  3,  4,  5,  5,  6,  7,  9,
       10, 11, 12, 14, 15, 16, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
       37, 39, 42, 44, 46, 49, 51, 54, 56, 59, 62, 64, 67, 70, 73, 76,
       78, 81, 84, 87, 90, 93, 96, 99,102,105,108,111,115,118,121,124};
    
    #define Led1 5
    
    
    void main(void)
    {
    
        Port_DataDirBit(Led1,1);
        Port_WriteBit(Led1,1);
        
        counter = 0;
        rate = 2;   
    
        while(1)
        {
                Timer_T0PWM(Sinustabele[counter],PS0_256);
                counter = counter + rate;
    
                if(counter > 256)
                {
                       counter = 0;
                }
        }
    
        Port_WriteBit(Led1,0);
    }
    Eigentlich müsste sich doch jetzt über die variable "rate" die frequenz irgendwie verändern lassen, weil je nachdem gibt es ja verschieden viele Ticks.
    Aber es Funktioniert nicht , der Ton bleibt immer gleich.
    Achso , angeschlossen ist der Lautsprecher wie folgt : --> http://www.mikrocontroller.net/artic...lung_.28DAC.29

    Hoffe ihr habt eine Idee das ich verändern muss ^^

    Danke im vorraus
    Geändert von Animus94 (03.06.2012 um 21:03 Uhr)

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Gleich vorweg: Ich kenne weder das c-control noch dessen spezielle C-Variante. Deshalb kann ich mit der Funktion Timer_T0PWM() nichts anfangen. Aber das Thema reizt mich zu einer kleinen Überlegung:

    Wenn der Ton mit 1kHz klingen soll und deine Tabelle für eine Periode 256 Werte besitzt, dann mußt du alle 1/1000/256 Sekunde oder nach 0,00000390625 Sekunden einen neuen Wert aus der Tabelle ausgeben. Mal angenommen, du verwendest einen 16MHz-Takt, dann wären das 62,5 Takte pro Wert. Wie soll der Timer in 62 Takten auf 254 zählen? Wenn du nur jeden zweiten Wert verwendest kommst du auf 124 Takte und das gilt jetzt ja nur für 1kHz. (Was wird eigentlich bei Tabellenwert 0 ausgegeben?)

    Besser wäre wohl dieser Ansatz: http://www.google.de/search?q=R-2R-Widerstandsleiter
    Top: http://www.avr-asm-tutorial.net/avr_de/avr_dac.html

    Gruß

    mic
    Geändert von radbruch (03.06.2012 um 21:11 Uhr)

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    28.12.2011
    Alter
    23
    Beiträge
    11
    Hi,

    na es gibt ja noch mehr Vorteiler für die Pwm und einige sind in ihren Ticks viel schneller

    Vorteiler (prescaler) Zeitbasis (Dauer eines Ticks)
    ------------------------------------------------
    PS0_1 67,8 ns
    PS0_8 542,5 ns
    PS0_32 2,17 µs
    PS0_64 4,34 µs
    PS0_128 8,68 µs
    PS0_256 17,36 µs
    PS0_1024 69,44 µs
    -----------------------------------------------
    Bei PS0_128 dauert ein Tick 8,68 µs , also ein kompletter Sinus 2,222 µs das sind immerhin 450 Hz
    und das bei voller Auflösung. Damit sollte man doch eiglich schon einige Töne hinbekommen.
    Das mit dem Tabellenwert 0 hab ich mir noch garnicht überlegt ^^ PWM kann nicht auf null geregelt werden oder ?

    So ein Widerstandsnetzwerk ist doch eigl. auch nichts anderes als eine PWM mit Tiefpass oder ?
    Ein DA Wandler mit dem die Spannung am Verbraucher verändert wird

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Auch ohne Prescaler kann der Timer nicht schneller als der Kontroller zählen.

    Das Widerstandsnetzwerk ist ein variabler Spannungsteiler den man in 2er-Potenzen ansteuern kann.

    Letztlich ist das Sinussignal ja für einen Lautsprecher gedacht. Aber der verschleift das Signal wohl sowieso, deshalb kannst du dir die Mühe vermutlich sparen.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    Hallo!

    Ausserdem ist ein Unteschied zwischen Sinus und Dreieck aus Lautsprecher nur für Musiker deutlich erkennbar. Für Frequenzen über ca. 10 kHz lässt sich sogar kein Unterschied zwischen Sinus und Rechteck nur mit dem Ohr erkennen.
    MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    28.12.2011
    Alter
    23
    Beiträge
    11
    Hmm ok also ein Widerstandsnetzwerk ...
    trotzdem versteh ich nicht warum sich die töne überhaupt nicht ändern ...
    hier hat jemand das selbe versucht und auch hinbekommen
    --> http://www.mikrocontroller.net/topic/110106
    leider kenne ich mit der Programmiersprache von dem nicht genügen aus um das nachzuvollziehen

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Ich habe den gezeigten Thread durchgelesen, aber irgendwie scheint mir das nicht schlüssig. Der Timer läuft ohne Vorteiler im Mode 1 (WGM10 im TCCR1A ist gesetzt). Mode1 bedeutet: PWM, Phase Correct, 8-bit. Beim Match wird die ISR aufgerufen und OCR1A wird mit dem nächsten Wert aus der Tabelle geladen:

    ISR(TIMER1_COMPA_vect){
    OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);
    i += scale;
    }

    Es werden je nach Größe von scale einige Werte in der Tabelle übersprungen, so dass die Dauer einer Periode durch die Anzahl der Werte pro Periode beeinflusst werden kann. Soweit, so gut. Aber PhaseCorrekt bedeutet, dass der Counter von 0 nach 255 und wieder zurück zählt. Beim Aufwärtszählen wird beim Match der Ausgang zurückgesetzt, beim Abwärtszählen wird beim Match der Ausgang wieder gesetzt (COM1A1:0 in TCCR1A ist 10: Clear OC1A/OC1B on compare match when
    up-counting. Set OC1A/OC1B on compare match when downcounting.) Der neue OCR1A-Wert wird zwar in der Match-ISR geschrieben, aber erst bei TOP upgedatet (Mode1: Update of OCR1x). Dazu kommt noch, dass nur jeder zweite aus der Tabelle gelesene und ins OCR1A geschriebene Wert auch wirklich Wirkung zeigt.

    Es gibt noch viel zu erforschen.

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    28.12.2011
    Alter
    23
    Beiträge
    11
    Hi,
    hab heut morgen noch mal experimentiert und kann jetzt unterschiedliche Töne erzeugen.
    Gut tun sie sich aber noch nicht wirklich anhören, aber immer hin lässt sich der Ton überhaupt verändern ^^

    Ich hab die Liste runter gekürzt auf 128 Werte und den Vorteiler verändert.
    Code:
    int delval;                      // globale Variablendeklaration
    int i;
    int k;
    float rate;
    
    int Sinustabele[128] = {
    
    0 , 0 , 0 , 1 , 2 , 3 , 5 , 7 , 9 , 12 , 14 , 17 , 21 , 24 , 28 , 32,
    36 , 41 , 46 , 51 , 56 , 61 , 66 , 72 , 78 , 83 , 89 , 95 , 101 , 107 , 114 , 120,
    127 , 133 , 139 , 145 , 151 , 157 , 163 , 169 , 175 , 181 , 186 , 192 , 197 , 202 , 207 , 212,
    216 , 221 , 225 , 228 , 232 , 235 , 238 , 241 , 244 , 246 , 248 , 250 , 251 , 252 , 253 , 253,
    253 , 253 , 253 , 252 , 251 , 250 , 248 , 246 , 244 , 241 , 239 , 236 , 232 , 229 , 225 , 221,
    216 , 212 , 207 , 202 , 197 , 192 , 187 , 181 , 175 , 169 , 164 , 158 , 151 , 145 , 139 , 133,
    127 , 120 , 114 , 108 , 102 , 96 , 90 , 84 , 78 , 72 , 67 , 61 , 56 , 51 , 46 , 41,
    37 , 33 , 28 , 25 , 21 , 18 , 15 , 12 , 9 , 7 , 5 , 3 , 2 , 1 , 0 , 0};
    
    #define Led1 5
    
    
    void main(void)
    {
    
        Port_DataDirBit(Led1,1);
        Port_WriteBit(Led1,1);
    
        rate = 6;
    
        while(1)
        {
    
            Sound(35.3,1500);  //vermutlich 700 Hz
    
            Sound(6,1500);
        }
    
        Port_WriteBit(Led1,0);
    }
    
    
    void Sound(float Rate, int Time)
    {
        for(k=0; k<(1/(128/Rate))*Time; k++)     // Berechne zyklen
        {
            for(i=0; i<128; i=i+Rate)
            {
                Timer_T0PWM(Sinustabele[i],PS0_8);
            }
    
        }
    }
    Kann sich einer Vortstellen wie man die Frequenz berechnen kann?
    Ich hab sie heute jetzt mit Headset und Audacity gemessen und komme auf Frequenzen zwischen 570 und locker 900 Hz...
    Ich weiß nur nicht ob das stimmt ^^

Ähnliche Themen

  1. Asuro mit Tonausgabe ?
    Von IDG im Forum Asuro
    Antworten: 2
    Letzter Beitrag: 19.04.2011, 17:08
  2. Antworten: 1
    Letzter Beitrag: 19.04.2011, 13:36
  3. Antworten: 3
    Letzter Beitrag: 29.10.2008, 15:21
  4. Über C-Konsolenanwendung Daten über RS232 übertragen
    Von WDragon91 im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 03.07.2008, 20:23
  5. Chip für Tonausgabe???
    Von JayCool im Forum PIC Controller
    Antworten: 7
    Letzter Beitrag: 13.02.2006, 12:36

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •