EUR | USD

Audioverarbeitung mit STM32

STMicroelectronics (ST) hat seinem leistungsstarken ARM-Cortex-M7-Portfolio kürzlich ein neues Mitglied hinzugefügt, den STM32H735, der für die ersten 30 Tage nach seiner Veröffentlichung exklusiv über Digi-Key erhältlich ist. Wenn neue Versionen wie diese auf meinen Schreibtisch kommen, teste ich die unterschiedlichen Funktionen gerne in einem kleinen Projekt. Für diesen Blog habe ich mich dafür entschieden, die verschiedenen Audio-Peripheriekomponenten zu untersuchen und die Ergebnisse über das Discovery-Kit STM32H735G-DK anzuzeigen. Einen kurzen Überblick über das Kit und eine sofort einsatzbereite Demo finden Sie in dem Video von einem meiner Kollegen unten.

Tonaufnahme

Der STM32H735G verfügt über zwei dedizierte serielle Audioschnittstellen (SAI), die eine große Flexibilität bieten. Jeder SAI hat zwei Unterblöcke, die unabhängig voneinander als Master oder Slave und entweder als Sender oder Empfänger für die Kommunikation vom Typ I2S konfiguriert werden können. Alternativ können sie einen Takt für PDM-Mikrofone bereitstellen und die Ausgabe in PCM umwandeln.

Andere Peripheriekomponenten des Geräts können ebenfalls für Audio verwendet werden. Vier der SPI-Schnittstellen des Geräts können für I2S konfiguriert werden. Der eingebettete Sigma-Delta-Filter (DFSDM) kann anstelle der SAIs auch die Konvertierung für PDM-Mikrofone übernehmen.

Auf dem Discovery-Kit sind beide oben erwähnten SAI-Konfigurationen in Aktion zu sehen. Eine der SAI-Schnittstellen ist über I2S mit einem WM8994-Codec von Cirrus Logic verbunden. Mit dem Codec wird das Audiosignal über den Line-In-Anschluss empfangen und über die Kopfhörerbuchse oder die verstärkten Lautsprecherausgänge wiedergegeben. Die zweite SAI arbeitet im PDM-Modus und ist direkt an das Bordmikrofon angeschlossen.

ST stellt ein Beispielprojekt (BSP) im STM32CubeMX-Framework zur Verfügung, um schnell mit der Verwendung dieser Audio-Peripheriekomponenten in eigenen Projekten beginnen zu können. Das Projekt enthält Low-Level-Treiber für die Peripheriekomponenten und Higher-Level-Treiber für Funktionen des Discovery-Kits wie den Audio-Codec. Beispielsweise ist die Konfiguration des Audio-Eingangs über den Line-In-Anschluss mit Hilfe der BSP-Treiber sehr einfach:

Kopieren
#define BUFFER_SIZE    2048

int16_t audio_buffer[BUFFER_SIZE]
BSP_AUDIO_Init_t  AudioInInit;

/* Initialize audio interface to use line in port for input */
AudioInInit.Device = AUDIO_IN_DEVICE_ANALOG_LINE1;
AudioInInit.ChannelsNbr = 2;
AudioInInit.SampleRate = 44100;
AudioInInit.BitsPerSample = AUDIO_RESOLUTION_16B;
AudioInInit.Volume = 80;

/* Initialize audio in on Instance 0 (SAI I2S) */
BSP_AUDIO_IN_Init(0, &AudioInInit);

/* Start DMA recording into buffer */
BSP_AUDIO_IN_Record(0, (uint8_t *) audio_buffer, 2* BUFFER_SIZE);

Verwendung des ARM CMSIS-DSP

Wenn Sie bereits mit ARM entwickelt haben, ist Ihnen wahrscheinlich der CMSIS (Cortex Microcontroller Software Interface Standard) bekannt. Es handelt es sich um eine Hardware-Abstraktionsschicht mit Code, der über verschiedene ARM-Cortex-Implementierungen hinweg konsistent ist. In diesem Fall bin ich an der CMSIS-DSP-Bibliothek interessiert, die allgemeine Signalverarbeitungsfunktionen enthält, die für die ARM-Architektur optimiert sind.

Für mich war der einfachste Weg, die CMSIS-Bibliotheken direkt von der Quelle einzubinden. Das gesamte CMSIS-Repository kann von ARMs GitHub geklont werden, aber nur die Verzeichnisse CMSIS/DSP/Include und CMSIS/DSP/Include müssen zu Ihrem ST-Projekt hinzugefügt werden, um zu beginnen. Im Allgemeinen sollten diese in das Drivers/CMSIS Verzeichnis in der Standard-Projektstruktur kopiert werden.

Vor der Kompilierung müssen zwei schnelle Projektanpassungen vorgenommen werden. Fügen Sie zunächst das neue Verzeichnis CMSIS/DSP/Include in die Include-Pfade des Projekts ein. Der dort befindliche Header „arm_math.h“ ist das, was Sie in Ihre Anwendung einbinden werden, um auf die DSP-Funktionen zuzugreifen.

Zweitens gibt es zwei #defines, die die DSP-Bibliothek für Informationen über die Hardware-Architektur verwendet: __FPU_PRESENT und ARM_MATH_CM7. Ich habe festgestellt, dass der einfachste Weg, um sicherzustellen, dass sie gefunden werden, darin besteht, sie zu den globalen Projektsymbolen hinzuzufügen, wie unten dargestellt.

Abbildung 1. Definitionen der Projektsymbole.

Danach bedarf es für die Berechnung einer FFT nur noch weniger Zeilen:

Kopieren
#include “arm_math.h”

#define FFT_SIZE    256

arm_rfft_fast_instance_f32 fft_inst;
float32_t fft_in[FFT_SIZE], fft_out[FFT_SIZE];
float32_t fft_mag[FFT_SIZE>>1];

/* Initialize ARM FFT instance with num points */
arm_rfft_fast_init_f32(&fft_inst, FFT_SIZE);

/* Fill the fft_in buffer from Line In or Microphone input */

/* Perform forward direction 32-bit FFT */
arm_rfft_fast_f32(&fft_inst, fft_in, fft_out, 0);

/* Calculate magnitude (buffer size is half because real + imag parts are merged) */
arm_cmplx_mag_f32(fft_out, fft_mag, FFT_SIZE >> 1);

Alles zusammenbringen

Wenn die FFT berechnet ist, ist es schön, die Ergebnisse grafisch zu betrachten. Die folgende Funktion kombiniert Funktionen aus den ST-BSP-Treibern und der CMSIS-DSP-Bibliothek, um eine minimalistische Grafik im Visualizer-Stil auf dem Display des Discovery-Kits zu zeichnen.

Abbildung 2. Visualizer auf dem Discovery-Kit angezeigt.

Kopieren
static void Display_FFT(float32_t *fft_mag)
{
	uint8_t i;
	float32_t max_val;
	uint32_t max_idx;
	uint32_t box_height;
	uint8_t box_width = 2;

	/* Draw horizontal axis */
	UTIL_LCD_FillRect(10, 135, 460, 2, UTIL_LCD_COLOR_WHITE);

	/* Use max value in the results for scale */
	arm_max_f32(fft_mag, FFT_SIZE >> 1, &max_val, &max_idx);

	/* Draw frequency bins */
	for(i = 0; i < 230; i++)
	{
		box_height = 100 * (fft_mag[i] / max_val);
		UTIL_LCD_FillRect(10 + box_width*i, 135, box_width, box_height, UTIL_LCD_COLOR_WHITE);
	}
}

Fazit

Der STM32H735 ist ein leistungsfähiger Mikrocontroller mit einer Vielzahl von integrierten Funktionen, insbesondere für Multimedia- und Signalverarbeitungsanwendungen. Digi-Key ist bis zum Ende des Monats der exklusive Distributor für das Produkt, also schauen Sie doch einmal auf unserer Website nach, ob es für Ihr nächstes Projekt geeignet ist.

Über den Autor

Image of Taylor Roorda Taylor Roorda, Associate Applications Engineer bei Digi-Key Electronics, ist seit 2015 im Unternehmen tätig und befasst sich hauptsächlich mit eingebetteten Systemen, programmierbarer Logik und Signalverarbeitung. Er hat einen Bachelor-Abschluss in Elektrotechnik von der North Dakota State University und verbringt seine Freizeit mit Gitarre spielen und dem Komponieren von Musik.
More posts by Taylor Roorda