www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik WAV von 8bit auf 7bit


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an Alle!
Ich möchte eine WAV-Datei abspielen. Dazu benutze ich einen mega32 mit 
16MHz, CLK/8 PWM, und Mono 16KHz 8bit WAV-Daten. Um eben die 16KHz 
hinzubekommen (damit man am Ausgang den PWM nicht mehr hört) möchte ich 
den PWM auf 7bit einstellen. Das klappt soweit auch wunderbar. Die WAV 
wird in gewünschter Geschwindigkeit ausgegeben. Jedoch mit Rauschen. 
Nach einem Blick aufs Oszilloskop sehe ich, dass die obere hälfte meines 
signals abgeschnitten wird. Um von 8 auf 7 Bit zu kommen habe ich 
einfach durch 2 geteilt. Das scheint jedoch nicht des rätsels lösung zu 
sein. Weiss jemand hier was ich tun muss damit ich wieder beide 
Signalhälften am Ausgang vorfinde?

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

zeig' doch mal den betreffenden Code. Ich vermute, es gibt ein Problem 
mit dem Vorzeichen, da du einen signed Integer nicht direkt dem Timer 
zuweisen kannst.
Eher so:
OCR1 = (a / 2) + 64;

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ARGH!
Danke!
War ja eigentlich klar... Aber manchmal denkt man einfach nicht nach...
Aber, jetzt schneidet er mir beide seiten ab und das Signal erinnert 
mehr an ein Rechteck.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR(TIMER1_OVF_vect)
{
 if(read_position < track_infos[current_track].track_length)
  OCR1AL = (take_buffer_byte()/2)+64;
 else
  read_position = 0;
}

char take_buffer_byte()
{
 char ret = buffer_pointer[pwm_pointer];
 pwm_pointer++;
 if(pwm_pointer > (BUFFER_SIZE-1))
  swap_buffers();
 return ret;
}

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem gelöst. Danke für den Tipp mit signed char!
Ich habe das jetzt alles auf unsigned gestellt und schon arbeitet die 
Routine vernünftig. Hört sich toll an!

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> ISR(TIMER1_OVF_vect)
> {
>  if(read_position < track_infos[current_track].track_length)
>   OCR1AL = (take_buffer_byte()/2)+64;
>  else
>   read_position = 0;
> }
>
> char take_buffer_byte()
> {
>  char ret = buffer_pointer[pwm_pointer];
>  pwm_pointer++;
>  if(pwm_pointer > (BUFFER_SIZE-1))
>   swap_buffers();
>  return ret;
> }

Ist 'char' standardmässig signed? Ich denke nicht. Dann funktioniert es 
natürlich nicht, da der Klammerausdruck dann einen Wertebereich von 0 
bis 127 hat, was deine 7 Bit bei einer Addition von 64 überschreitet. Da 
kommt es nun drauf an, wie deine Daten im Puffer vorliegen. Sind es 
vorzeichenbehaftete Werte in Zweierkomplementdarstellen (Also einfach 
signed chars), dann solltest du sowohl Puffer wie auch Funktion damit 
deklarieren. Wenn es aber fortlaufende Werte von 0 bis 255 sind, dann 
reicht in der Tat eine einfache Division durch 2.

Ausserdem sind Funktionsaufrufe in ISRs nicht so geschickt, da dann 
jeweils alle Register auf dem Stack gesichert werden müssen.


EDIT: Zu spät ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:

> char take_buffer_byte()
> {
>  char ret = buffer_pointer[pwm_pointer];


Du solltest dir etwas zur Regel machen:

char benutzt du nur, wenn du es mit Texten zu tun hast.
Wenn deine Memory-Inhalte einfach nur Bytes sind, dann benutzt du 
unsigned char. Wenn in diesen Bytes zusätzlich noch ein Vorzeichenbit 
enthalten ist, dann benutzt du signed char

Aber grundsätzlich überlasst du es niemals dem Compiler, ausser bei 
Texten, ob er einen char als signed oder unsigned ansieht!

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.