Hallo, ich suche eine Möglichkeit ein I2S Signal mit einem AVR Mega88 einzulesen. Ich will nur den Signalpegel auswerten und über LEDs anzeigen. Gibt es eine Möglichkeit, ausser die Pin's abzupollen? Also sowas wie SPI, SIO in irgend einem Modus oder sonst eine Hardware unterstützung? Viele Grüsse, Peter
Glaube das wird nicht gehen. Der M88 kann doch nur mit 24MHz arbeiten und SPI braucht schon >4 Takte um was zu empfangen. Pollen wird auch nicht gehen. I2S ist recht flott, je nach Signal kommen da schon mal 26MHz zusammen. Ein externes Schieberegister könnte gehen oder ein Prozessor mit I2S Eingang.
Erst mal musst du was zur Signalgeschwindigkeit sagen, vorher ist alles Rätselraten. Woher kommt das Signal, wie schnell ist es, Auflösung?
Bis 96kHz/24Bit sollte SPI noch mitmachen. Allerdings kann es sein, daß Du Dir noch ein paar clock-Signale erzeugen musst ... Dies ist auch der Grenzfall und damit schon sehr Zeitkritisch. Bei CD (44.1/16) sollte es aber keine Probleme geben. Gruß Jobst
Jobst M. schrieb: > Bis 96kHz/24Bit sollte SPI noch mitmachen. sicher? I2S läuft mit 32bit, 2 kanäle => 6.144MHz hat dann die SCLK. gewagt, gewagt... ich würde auch ein externes Schieberegister nehmen, oder ein CPLD.
Moin! I2S läuft nicht immer mit 32Bit. Aber ich habe auch mit diesem Fall gerechnet. Dann läuft der uC mit 24.576MHz das ist leicht ausserhalb seiner Specs. Allerdings sollte der Takt aus dem Datensignal generiert werden. Das dies Grenzwertig ist, habe ich aber geschrieben. Abgesehen davon, würde ich das Ganze analog machen. Wenn es unbedingt digital sein muss, kann er ja einen SRC davor schalten. Gruß Jobst
Danke für die Infos. Ich habe zur Zeit 32Bit mit maximal 12,xxx MHz auf dem I2S Bus (192KHz 128FS). Das kann aber sein das ich noch schneller werden muss. Nun eine reine Software Lösung schließe ich jetzt auch aus. Der Einwand mit der SPI habe ich nachgelesen und wird wohl auch nicht gehen. Bleibt wohl nur ein Schieberegister oder ein kleiner ARM Prozessor. Dumm nur das ich mich mit den ARM Prozessoren nicht auskenne und auch keine Tools dafür habe. Was gibt es denn vernünftiges dafür? Eine AVR Lösung wird mit einem Schieberegister aber auch schwer. Ich muss den Inhalt ja abholen bevor das nächste Bit rein kommt. Oder gibt es da entsprechende Bausteine die das Ergebnis zwischen speichern? MfG Peter
@Peter Nimm nen ARM. Ein AT91SAM7S256 z.b. hat direkt eine I2S Schnittstelle inkl. DMA On-Board. Damit wird I2S zur Nebensache. Einem AVR würd ich ohnehin nicht zutrauen I2S Deserializing zu machen (es sei denn er macht NUR das), von der Verarbeitung mal ganz abgesehen. Jedenfalls nicht wenns CD Qualität aufwärts sein soll. 8kHz 16Bit mono bekommt man mit einem AVR sicherlich noch hin. Und da wäre auch wohl Verarbeitung noch evtl drin. Aber alles was darüber geht ... wenig Chancen.
Ich will die Daten nur einlesen und den Pegel anzeigen (LEDs). Wenn es geht, auch noch als 8Bit Wert über I²C bereitstellen. Das ein ARM7 das packt ist mir auch klar, aber den kenne ich nicht. MfG, Peter
Also wenn du dir den RMS Wert anzeigen lassen willst ist es noch etwas zu tun bis dahin ... Du mußt jedes Sample (also jedes empfangene Datenwort) quadrieren, aufsummieren, am Ende der Summation (alle x Werte, wobei x deine Fenstergröße vorgibt) dann durch x teilen, die Wurzel daraus ziehen und dann kannst du den Wert in dB umrechnen. Bei CD-Qualität ist der Aufwand (wenn man nicht gravierende Vereinfachungen macht) für einen AVR nicht zu schaffen. Lösung a) : - nur 8 von den 16 bzw 24 Bits verarbeiten. - Fenstergröße fest auf 2'er Potenz - Wurzelfkt. stark optimieren (Tabellen usw) Lösung b) : - I2S nach analog Wandeln, analog filtern und mit dem ADC des AVR's einlesen Wenn du es rein digital machen willst denke ich kannst du das vergessen. Quadrieren von 24 bzw 32 Bit. Teilen einer 32 bzw 64 Bit Zahl durch 16 bzw 32 Bit. Wurzelziehen aus einer 32 Bit Zahl. Und das alles in 10-20µs (200-400 Takte bei 20MHz pro Sample). Sehr sportlich.
Habe ich mal gemacht. Dabei taste ich nicht den kompletten Datenstrom ab, sondern immer nur Stichproben, damit noch Zeit zum Rechnen und für die Darstellung bleibt. Für eine LED-Anzeige gar kein Problem. Hier waren die 12.288Mhz MasterClock auch gleich die Taktfrequenz für den Controller, so daß man 4 Takte pro Samplebit zur Verfügung hat. Über LRCLK wurde der Frame synchronisiert, wenn ich mich recht erinnere, habe ich 16Bit/48kHz ausgewertet, logarithmiert und auf 2x10 LEDs angezeigt. Nettes Gimmick ist eine Peak-Hold-Funktion. Das Projekt läuft in einer digitalen DI-Box, Controller ist ein Mega16, der auch für die Akkuladung zuständig ist.
TheMason schrieb: > Wenn du es rein digital machen willst denke ich kannst du das vergessen. > Quadrieren von 24 bzw 32 Bit. Teilen einer 32 bzw 64 Bit Zahl durch 16 > bzw 32 Bit. Wurzelziehen aus einer 32 Bit Zahl. Und das alles in 10-20µs > (200-400 Takte bei 20MHz pro Sample). Sehr sportlich. Es gibt auch LookUp-Tables, die im oben beschriebenen Stichproben-Betrieb schnell genug sind. Es kommt hier nicht auf 100,000% Genauigkeit an. Es soll habwegs glaubhaft blinken und bei der Findung des optimalen Pegels helfen (nehme ich an).
@travelrec Einverstanden. Ich bin (leider) davon ausgegangen es so akkurat wie möglich zu machen, und hab natürlich die wichtigsten Optimierungsmöglichkeiten ausgelassen. Scheiß Perfektionismus :-) Aber so gesehen lässt sich da schon was machen.
@Travel Rec. Das ist genau das was ich machen will. Existiert das Projekt noch? Und ist der Code Öffentlich? MfG Peter
Ich bin auch zuversichtlich, daß der Mega88 das kann. Ich habe gerade das Umgekehrte gebaut, eine I²S Ausgabe, 48 kHz Stereo 16 Bit. Und die Samples muß der arme Controller auch noch errechenen (DDS mit nachgeschalteter linearer Interpolation zwischen den Tabellenwerten). Nimm nicht den SPI, sondern den USART im synchronen Modus. SPI hat beim Mega88 leider keine Doppelpufferung, USART schon. Ein weiterer "Trick" in meinem System war, nested Interrupts zuzulassen, um die Latenz klein zu kriegen. Und die Codierung der Haupt-ISR in Assembler... Jörg
Naja, leider kann man den synchronen UART nur als Master-SPI gebrauchen, was bei der vorliegenden Anwendung keine Vorteile bringt. Hier der betreffende Codeabschnitt, es werden keine Hardware-Interfaces benutzt. Engegen meiner Annahme werden nur je 8 obere Bits für den linken und rechnten Kanal benutzt, was für 10 LEDs aber ausreicht.
1 | ;reads I2S data, 8 MSB for each channel |
2 | GetSoundADC: |
3 | cli |
4 | |
5 | _GSA1: |
6 | sbic PinC, LRCK ;syncronize to LRCK |
7 | rjmp _GSA1 |
8 | |
9 | _GSA2: |
10 | sbis PinC, LRCK |
11 | rjmp _GSA2 |
12 | |
13 | nop |
14 | clr Temp |
15 | clc |
16 | sbic PinC, SDIN |
17 | sec |
18 | rol Temp |
19 | clc |
20 | sbic PinC, SDIN |
21 | sec |
22 | rol Temp |
23 | clc |
24 | sbic PinC, SDIN |
25 | sec |
26 | rol Temp |
27 | clc |
28 | sbic PinC, SDIN |
29 | sec |
30 | rol Temp |
31 | clc |
32 | sbic PinC, SDIN |
33 | sec |
34 | rol Temp |
35 | clc |
36 | sbic PinC, SDIN |
37 | sec |
38 | rol Temp |
39 | clc |
40 | sbic PinC, SDIN |
41 | sec |
42 | rol Temp |
43 | clc |
44 | sbic PinC, SDIN |
45 | sec |
46 | rol Temp |
47 | clc |
48 | sbic PinC, SDIN |
49 | sec |
50 | rol Temp |
51 | |
52 | brcc _TCLeft ;convert 2s complement to positive value |
53 | neg Temp |
54 | |
55 | _TCLeft: |
56 | sts LeftLow, Temp |
57 | |
58 | |
59 | _GSA4: |
60 | sbic PinC, LRCK |
61 | rjmp _GSA4 |
62 | |
63 | nop |
64 | clr Temp |
65 | clc |
66 | sbic PinC, SDIN |
67 | sec |
68 | rol Temp |
69 | clc |
70 | sbic PinC, SDIN |
71 | sec |
72 | rol Temp |
73 | clc |
74 | sbic PinC, SDIN |
75 | sec |
76 | rol Temp |
77 | clc |
78 | sbic PinC, SDIN |
79 | sec |
80 | rol Temp |
81 | clc |
82 | sbic PinC, SDIN |
83 | sec |
84 | rol Temp |
85 | clc |
86 | sbic PinC, SDIN |
87 | sec |
88 | rol Temp |
89 | clc |
90 | sbic PinC, SDIN |
91 | sec |
92 | rol Temp |
93 | clc |
94 | sbic PinC, SDIN |
95 | sec |
96 | rol Temp |
97 | clc |
98 | sbic PinC, SDIN |
99 | sec |
100 | rol Temp |
101 | |
102 | brcc _TCRight ;convert 2s complement to positive value |
103 | neg Temp |
104 | |
105 | _TCRight: |
106 | sts RightLow, Temp |
107 | |
108 | sei |
109 | ret |
Danke an alle. Nun versuche ich mal das alles umzusetzen. Melde mich wieder, wenn ich was neues berichten kann. Peter
Ja, mach mal. Die erhaltenen Daten mußt Du eigentlich nur maximieren (Peak detection) und diesen Maximalwert relativ langsam (10% Laufbandlänge /100ms) herunterzählen. Neue Peaks werden sofort übernommen. Das sieht dann optisch schon gut aus. Aufwerten läßt sich das durch ein Peak-Hold, bei dem die Spitzenpunkte 2s lang auf der Anzeige bleiben, bevor sie mit kleineren Werten geladen werden. Dabei kann dann die Release-Zeit des Gesamtbandes wieder etwas zügiger sein, so daß man schnellere Reaktionen sieht. Viel Spaß beim Proggen! Ich mach mal gelegentlich ein Filmchen von meinen Anzeigen ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.