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


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

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.