Forum: Projekte & Code Hook up a MEMS microphone to the I2S of a Cortex M4


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

Hi all,

I want to read out a MEMS microphone ( namely Knowles SPM1423HM4H-B ) to 
my Cortex M4 over the I2S interface. I did not find any templates for 
the initialization on the net, so I implemented it ;).

The mic needs a clock of up to 3MHz and is sending out pulse density 
coded bits ( the more ones, the higher the signal, sort of sigma-delta 
coded ). The clock and the bitstream are read over the SPI/I2S of a 
Cortex M4. I use the SPI-2 interface, because SPI-1 is occupied by the 
JTAG adapter. The SPI2 is configured for I2S protocol and packs the 
bitstream to 16Bit words (PCM mode, I2S receive master). For a completed 
16Bit word an interrupt is generated. I use a 80MHz clock and a 1/32 
prescaler, so the clock for my mic is 2.5MHz. With a single interrupt 
for 16Bits we get an interrupt load of 156250 interrupts/s.

The enclosed main.c for gcc is only a template for the setup of the 
GPIOs, the SPI/I2S and the interrupt controller. I stripped it but maybe 
some debug stuff is left. I do not claim that it can be compiled, just 
use it as a working example.

I fed the mic with a synchronus 2.441KHz = 2.5MHz/(16*64) test tone, see 
the picture. I recorded the bitstream (16384*16Bit) and made a FFT of 
it, see the screenshots, unit is dB. I got wonderful noise shaped 
sigma/delta spectra with 60dB SNR (well, roughly), see the zoomed 
spectrum.

The mems mics are all digital, high bandwidth and easy to read without 
analog preamps.

Nice stuff!
Cheers
Detlef

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Gibt es irgendeinen Grund dafür, warum Du das hier auf Englisch verfasst 
hast?

In Deinem anderen Thread zum gleichen Thema 
https://www.mikrocontroller.net/topic/goto_post/5010710 fandest Du das 
nicht nötig.

Englischsprachige Beiträge bitte auf http://embdev.net/ unterbringen.

von Detlef _. (detlef_a)


Lesenswert?

Möglicherweise bezweckte ich, dass der englischsprachige Sucher das 
einfacher findet.

Du bist in der Lage das an jeden beliebigen Ort des Forums zu schieben.

Cheers
Detlef

von koellomat (Gast)


Lesenswert?

Hallo,

ich stehe vor dem gleichen Problem auf einem F446.
Was bedeutet
I2S_InitStructure.I2S_AudioFreq=I2S_AudioFreq_192k;
wenn der Clock der I2S "händisch" über den Prescaler erzeugt wird?
Ist bei Deiner anschließenden Filterung von PDM zu PCM der "decimation 
factor" das Verhältnis von I2S-Clock zu Audio Frequency?

Gruß Matthias

von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

Hallo Matthias,

MEMS benutzen, eine sehr gute Idee.

Was diese Zeile
I2S_InitStructure.I2S_AudioFreq=I2S_AudioFreq_192k;
bedeutet weiss ich nicht mehr, ist aber auch nicht mehr wichtig, siehe 
unten.

Den Bitstrom 2MHz/1Bit vom MEMS kannst Du gedanklich als schnell 
abgetastetes Audiosignal mit minimal möglicher Auflösung betrachten.
Wenn Du von dem n-Stück aufsummierst ('add and dump') dezimiert Du um n 
mit einem brickwall-FIR  n-ter Ordnung (alle Koeffizienten 1), das ist 
ein mittelmäßiger Tiefpass.

In diesem Beitrag
Beitrag "FIR Filter Optimierung eines PDM Signals auf STM32F407 simuliert mit Matlab"
hatte ich schon mal probiert besser auf dem schnellen Bitstrom zu 
filtern, das hat wunderbar geklappt.

Just jetzt mache ich das wieder. Ich bestimme die Phase eines Tones mit 
Goertzel direkt aus dem schnellen Bitstrom. Das dauert zwar, aber ich 
muss nicht echtzeitfähig sein, weil der Bitstrom direkt per DMA weiter 
in den Speicher läuft.

Das ist jetzt auch nicht mehr so schwierig aufzusetzen und läßt sich in 
CubeIDE einfach zusammenklicken. Ich habe mein Projekt für einen F303 
mal angehängt, kuck Dir einfach die .ioc an und implementiere für Deinen 
uC entsprechend.

Cheers
Detlef

von koellomat (Gast)


Lesenswert?

Hallo Detlef,

danke für die Rückmeldung.
Ich glaube das Filtern ist mir zu hoch.
Ich werd wohl die I2S-Variante SPH0645LM4H verwenden.
Selbst da tue ich mich noch etwas schwer.
Laut Datenblatt ist das Oversampling 64.
Wenn ich mir den HAL-Code vom STM32 anschaue, ergibt sich der I2S-Clock 
aus der Audio Frequency * Datenbreite.
Ich muss also die Datenbreite auf 24Bit stellen. Der STM32 macht daraus 
2 * 32 Bit. Das passt zum Oversampling laut Datenblatt.
Die zweiten 32Bit vom anderen Kanal muss ich halt ignorieren.
Zur Not muss das Oszi ran.

Gruß Matthias

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]
  • [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.