Forum: Mikrocontroller und Digitale Elektronik TDA1543 tut nichts


von Sam .. (sam1994)


Lesenswert?

Hi

Ich versuche gerade aus dem TDA1543 einen Ton heraus zubekommen - leider 
mit wenig Erfolg. Da ich erstmal nur einen Kanal nutzen möchte, habe ich 
WS per PWM so getoggelt, dass immer der Linke Kanal beim schreiben aktiv 
ist. Ich sende derzeit 8bit per SPI, danach wird WS 2xgetogglt und im 
nächsten Interrupt werden die nächsten Daten gesendet. Das einzige, was 
man hört, ist ein Knacken im rechten Kanal nach einen Reset des Avrs.
Der IC wird geschätzt 50-60°C heiß. Einen passenden Kühlkörper für DIP8 
besitze ich leider nicht.

Der PWM (WS) Takt beträgt 33,5KHz (nachgemessen, µC läuft intern mit 
8Mhz). Für die restlichen Leitungen wäre ein Logikanlyser sinnvoll (habe 
ich natürlich auch nicht).

Die Schaltung habe ich nach 
http://www-user.tu-chemnitz.de/~heha/Mikrocontroller/TDA1543.htm 
aufgebaut (für Audio), die Verbindungen auch schon mehrmals überprüft. 
Der TDA wird übrigens mit 8V betrieben, der µC mit 5V. Trotzdem sollte 
der TDA die 5V als High erkennen. Laut Simulator sollte auch alles 
funktionieren, was es aber in der Praxis nicht tut.

http://www.docethifi.com/TDA1543_.PDF
1
.include "m8515def.inc"  
2
3
.def low_bufend          = r8
4
.def temp                = r16
5
.def temp2               = r17
6
.def next_data           = r21
7
8
9
.equ BUFLEN  = 256
10
11
.equ SPI_DDR = DDRB
12
.equ MOSI    = PB5
13
.equ SCK     = PB7
14
.equ SS      = PB4
15
16
.org 0x000
17
    rjmp INIT
18
.org OVF0addr   ;Die folgenden Interrupts sind unwichtig, daher werden sie überschrieben
19
    out SPDR, next_data
20
    Ld next_data, X+
21
    cpse XL, low_bufend
22
    reti
23
    ldi XH, HIGH(BUF)
24
    ldi XL, LOW(BUF)
25
    reti
26
27
INIT:
28
    ldi temp, HIGH(RAMEND)     ;Stackpointer initialisieren
29
    out SPH, temp
30
    ldi temp, LOW(RAMEND)
31
    out SPL, temp
32
33
    ;SPI Init für DAC
34
    ldi temp, (1<<SCK) | (1<<MOSI) | (1<<0) | (1<<SS)
35
    out SPI_DDR, temp   
36
37
    ldi   temp, (1<<SPE) | (1<<MSTR)  | (1<<CPHA)
38
    out   SPCR, temp            ;keine Interrupts, MSB first, Master
39
                                ;CPOL = 0, CPHA = 1
40
                                ;SCK Takt = 1/2 XTAL
41
    ldi   temp, (1<<SPI2X)
42
    out   SPSR, temp            ;double speed aktivieren
43
    out   SPDR, temp            ;Dummy Daten, um SPIF zu setzen
44
45
    ;Timer initialisieren
46
    ldi temp, (1<<WGM00) | (1<<WGM01) | (1<<COM01) | (1<<CS00) ;non-Inverting PWM
47
    out TCCR0, temp
48
    ldi temp, (1<<TOIE0)
49
    out TIMSK, temp          ;OVF-Interrupt aktivieren
50
    ldi temp, 128
51
    out OCR0, temp
52
53
54
    ldi temp, LOW(BUFEND)
55
    mov low_bufend, temp    ;Wichtig für Abfrage in ISR, ob Buffer am Ende
56
57
    ;Pointer für Buffer setzen
58
    ldi XH, HIGH(BUF)      ;X-Pointer mit Startadresse
59
    ldi XL, LOW(BUF)       ;des Buffers laden
60
61
    ldi temp, 128
62
    ldi temp2, 0
63
    ldi YH, HIGH(BUF)
64
    ldi YL, LOW(BUF)
65
    rjmp L
66
    ;Ram mit Rechteck füllen
67
L0:
68
    ldi temp, 127
69
L:
70
    st Y+, temp
71
    inc temp2
72
    breq L3
73
    cpi temp2, 128
74
    breq L0
75
    rjmp L
76
L3:
77
    sei
78
L2:
79
    rjmp L2
80
81
.dseg              ;Ram
82
;Sample Buffer mit Audio-Daten
83
BUF:  .BYTE  BUFLEN
84
BUFEND:

von MaWin (Gast)


Lesenswert?

Mit einem out SPDR, next_data wirst du keine Daten an einen TDA1543 
übertragen können, und da du vor dem letzten Bit immer WS ändern musst, 
kannst du nicht nur einen Kanal beschicken, sondern musst zumindest 1 
bit an den anderen Kanal senden.

von Sam .. (sam1994)


Lesenswert?

Danke für deine schnelle Antwort.

Das heißt, wenn ich mit SPI arbeiten möchte muss ich den Zeitpunkt des 
PWM-Signals so berechnen, dass es genau beim 7bit umschaltet und dann 
noch irgendetwas in den 2. Kanal schreibt. Dafür müsste man den OCR0 
Vergleichswert in der ISR neusetzen.

Gibts da etwa keinen eleganteren Weg?

Könnte man auch den Toogle-PWM modus nutzen? Man beschreibt nach jedem 
Überlauf ein Kanal, beim nächsten den anderen. Timerfreq wäre x2. Die 
beiden Kanäle wären in diesem Falle um ca. 10us verschoben. Kann man das 
hören?
Ich hätte gerne 50% Duty beim PWM, da damit zusätzlich eine negative 
Spannung erzeugt wird.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Samuel K. schrieb:
> Der IC wird geschätzt 50-60°C heiß.

Samuel K. schrieb:
> Der TDA wird übrigens mit 8V betrieben

Warum zum Geier? Der läuft mit 5V hervorragend, 8V ist die absolut 
maximale Obergrenze. Der Chip sollte, wenn überhaupt, dann nur handwarm 
sein.

Samuel K. schrieb:
> Ich sende derzeit 8bit per SPI, danach wird WS 2xgetogglt und im
> nächsten Interrupt werden die nächsten Daten gesendet.

Kannst Du vergessen. Mit SPI bekommst Du kein jitterfreies Signal hin da 
Du immer nachladen mußt und somit Pausen erzeugst. So gerät der Wandler 
aus dem Takt. Such Dir einen AVR, der sein UART auch als Master-SPI 
nutzen kann. Nur damit kannst Du endlose Streams generieren. Einen 
direkt gekoppelten Timer, der die Wordclock generiert dazu und dann wird 
alles gut. Allerdings wird der Controller mit dem Nachladen der Daten 
auch zu 80% ausgelastet sein. Es sei denn, Du hast eine miese Bit- und 
Samplerate, wofür Du dann aber den DAC auch nicht brauchst...

von Sam .. (sam1994)


Lesenswert?

Knut Ballhause schrieb:
> Warum zum Geier? Der läuft mit 5V hervorragend, 8V ist die absolut
> maximale Obergrenze. Der Chip sollte, wenn überhaupt, dann nur handwarm
> sein.

Ich habe mich an 
http://www-user.tu-chemnitz.de/~heha/Mikrocontroller/TDA1543.htm 
gehalten. Unter dem ersten Schaltbild steht er sollte dafür mit 8V 
betrieben werden, schließlich beträgt die Ampitude dann auch 2.5V statt 
1V.
60°C sollte er aushalten - ich weiß das es besser kälter ist. Ich werde 
mich mal nach einem Kühlkörper umschauen. Derzeit habe ich nur einen 
Dip16-Kühlkörper, dieser passt aber nicht, da die Koppelkondensatoren 
und die ISP-Buchse nah am IC liegen.

Knut Ballhause schrieb:
> Kannst Du vergessen. Mit SPI bekommst Du kein jitterfreies Signal hin da
> Du immer nachladen mußt und somit Pausen erzeugst. So gerät der Wandler
> aus dem Takt. Such Dir einen AVR, der sein UART auch als Master-SPI
> nutzen kann. Nur damit kannst Du endlose Streams generieren.

Sollte das wirklich so sein, habe ich ein kleines Problem, da die 
Platine schon geätzt ist. Ich habe auf das Datenblatt vertraut:
1
The data in the input registers is simultaneously latched in the output
2
registers which control the bit switches.
Demnach hat der TDA1543 ein 2x16bit Latch und braucht keine Regelmäßiges 
Signal. Ich hoffe nur ein kommt auch mit 11Mbit zurecht und nicht nur 
mit 9.2Mbit, da ich einen 22Mhz Quarz auf der Platine habe. Bisher läuft 
er deswegen mit interem RC-Osc.

Wenn ich mich richtig erinnere, kann der Atmega8515 Uart im SPI-Mode 
laufen lassen, allerdings stimmt dafür die Platine nicht.

von Sam .. (sam1994)


Angehängte Dateien:

Lesenswert?

Laut Beitrag "TDA1543 DAC mit SPI ansteuern" muss nur das WS Signal 
regelmäßig sein. Das heißt, es wäre am einfachsten wenn man die alle 
Audiodaten logisch um eins nach rechts schiebt.

Um dem Problem näher zu kommen, hab ich mir jetzt doch einen kleinen 
Logikanalyser gebaut. Die Abtastfrequenz beträgt 5.3Mhz, was für 4Mhz 
SPI Takt reichen sollte (mehr als 5.3Mhz ist mit einem Atmega bei 16Mhz 
auch nicht zu erreichen). Das Diagramm ist leider falsch dargestellt. Es 
ist mir aber erst jetzt aufgefallen. Oben bedeutet low. Wenn das 
Diagramm richtig deute funktioniert das SPI nicht. Es werden viel zu 
wenig Clocks gesendet. Außerdem stimmen die Daten nicht.

Im Code habe ich nur die ISR und die Timer initialisierung geändert:
1
.NOLIST
2
.include "m8515def.inc"  
3
.LIST
4
5
.def low_bufend          = r8
6
.def sregtmp             = r9
7
.def rorsreg             = r10
8
.def temp                = r16
9
.def temp2               = r17
10
.def next_data           = r21
11
12
.org 0x000
13
  rjmp INIT
14
15
.equ BUFLEN = 256
16
17
.equ SPI_DDR= DDRB
18
.equ MOSI   = PB5
19
.equ SCK    = PB7
20
.equ SS     = PB4
21
22
.org OC0addr   ;Die folgenden Interrupts sind unwichtig, daher werden sie überschrieben
23
    out SPDR, next_data
24
    Ld next_data, X+        ;nächste Audiodaten laden, diese müssen nun nach rechts geschoben werden
25
    in sregtmp, SREG        
26
    out SREG, rorsreg       ;voriges LSB laden (darf erst nach dem WS-Flankenwechsel gesendet werden)
27
    ror next_data           ;nach rechts schieben, dabei wird das LSB an die MSB geschoben
28
    in rorsreg, SREG        ;neues LSB speichern (Carry)
29
    out SREG, sregtmp
30
    cpse XL, low_bufend
31
    reti
32
    ldi XH, HIGH(BUF)
33
    ldi XL, LOW(BUF)
34
    reti
35
36
INIT:
37
  ldi temp, HIGH(RAMEND)     ;Stackpointer initialisieren
38
  out SPH, temp
39
  ldi temp, LOW(RAMEND)
40
  out SPL, temp
41
42
  ;SPI Init für DAC
43
    ldi temp, (1<<SCK) | (1<<MOSI) | (1<<0) | (1<<SS)
44
    out SPI_DDR, temp   
45
46
    ldi   temp, (1<<SPE) | (1<<MSTR)  | (1<<CPHA)
47
    out   SPCR, temp            ;keine Interrupts, MSB first, Master
48
                                ;CPOL = 0, CPHA = 1
49
                                ;SCK Takt = 1/2 XTAL
50
    ldi   temp, (1<<SPI2X)
51
    out   SPSR, temp            ;double speed aktivieren
52
    out   SPDR, temp            ;Dummy Daten, um SPIF zu setzen
53
54
  ;Timer initialisieren
55
    ldi temp, (1<<WGM01) | (1<<COM00) | (1<<CS00) ;toggle on compare match
56
    out TCCR0, temp
57
    ldi temp, (1<<OCIE0)
58
    out TIMSK, temp          ;Compare-Match-Interrupt aktivieren
59
    ldi temp, 127
60
    out OCR0, temp
61
62
63
    ldi temp, LOW(BUFEND)
64
    mov low_bufend, temp    ;Wichtig für Abfrage in ISR, ob Buffer am Ende
65
66
    ;Pointer für Buffer setzen
67
    ldi XH, HIGH(BUF)      ;X-Pointer mit Startadresse
68
    ldi XL, LOW(BUF)       ;des Buffers laden
69
    ldi temp, 128
70
    ldi temp2, 0
71
    ldi YH, HIGH(BUF)
72
    ldi YL, LOW(BUF)
73
    rjmp L
74
    ;Ram mit Rechteck füllen
75
L0:
76
    ldi temp, 127
77
L:
78
    st Y+, temp
79
    inc temp2
80
    breq L3
81
    cpi temp2, 128
82
    breq L0
83
    rjmp L
84
L3:
85
sei
86
L2:
87
    rjmp L2
88
89
.dseg              ;Ram
90
91
;Sample Buffer mit PWM-Daten
92
BUF:  .BYTE  BUFLEN
93
BUFEND:

von Sam .. (sam1994)


Angehängte Dateien:

Lesenswert?

Hier nochmal korrekt dargestellt.

von Sam .. (sam1994)


Angehängte Dateien:

Lesenswert?

Neuer Versuch: Ich habe den Code von 
Beitrag "Soundausgabe funktioniert nicht!!!" umgeändert und damit 
endlich mal ein paar Töne erzeugen können. Allerdings alles andere als 
der geplante Sinus.

Hat keiner eien Idee was noch falsch sein könnte?

von Sam .. (sam1994)


Angehängte Dateien:

Lesenswert?

Kleiner Fehler: Es darf natürlich nicht nur inc ZL heißen, sondern adiw 
Z, 1.

Jetzt kann ich ein Rechteckton ausgeben. Sinus will immer noch nicht. 
Dieser sieht genauso aus wie im vorigen Anhang.

Zudem sieht die Rechteckschwingung nicht sehr sauber aus.

von Sam .. (sam1994)


Lesenswert?

Sägezahnschwingung sieht noch schlimmer aus. Wie soll man mit dem IC zu 
brauchbaren Ergebnissen kommen? Oder könnte der auch einfach defekt 
sein?

von Sam .. (sam1994)


Angehängte Dateien:

Lesenswert?

Anhang

von Sam .. (sam1994)


Lesenswert?

Keiner eine Idee?

Ein paar Anhaltspunkte würden mir schon helfen. Ich weiß shcon gar nicht 
mehr was ich alles noch überprüfen könnte, um dem Problem näher zu 
kommen.

von Sam .. (sam1994)


Lesenswert?

Der Sinus wird doppelt so hoch abgespielt wie das Rechteck. Sägezahn 
wiederum doppelt so hoch wie der Sinus. Eigentlich dürfte das nicht so 
sein, da alle Samples 256 8bit Werte einer Schwingung enthalten.

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.