Elaborazione audio con STM32
STMicroelectronics (ST) ha appena rilasciato un nuovo prodotto della linea ad alte prestazioni Arm Cortex-M7, STM32H735, disponibile esclusivamente attraverso DigiKey per i primi 30 giorni dall'introduzione sul mercato. Quando arrivano sulla mia scrivania nuovi prodotti come questo, mi piace provarne le caratteristiche in un piccolo progetto. Per questo blog, ho deciso di studiare le diverse periferiche audio e visualizzare i risultati utilizzando il kit Discovery STM32H735G-DK. Per una breve panoramica del kit e una demo rapida, potete guardare il video qui sotto di uno dei miei colleghi.
Acquisizione audio
STM32H735G ha due interfacce audio seriali dedicate (SAI) che garantiscono un'elevata flessibilità. Ogni SAI ha due blocchi secondari configurabili in modo indipendente come master o slave e come trasmettitore o ricevitore per comunicazioni di tipo I2S. In alternativa, possono fornire il clock per microfoni PDM e convertire l'uscita in PCM.
Anche altre periferiche del dispositivo possono essere utilizzate per l'audio. Quattro delle interfacce SPI del dispositivo possono essere configurate per I2S. Il filtro sigma-delta embedded (DFSDM) può gestire anche la conversione per i microfoni PDM al posto delle SAI.
Nel kit Discovery è possibile vedere in azione entrambe le configurazioni SAI riportate sopra. Una delle interfacce SAI è collegata tramite I2S a un codec WM8994 di Cirrus Logic. Con il codec, l'audio viene ricevuto tramite la porta Line In e riprodotto attraverso la presa per cuffie sulle uscite degli altoparlanti amplificate. La seconda SAI opera in modalità PDM ed è collegata direttamente al microfono su scheda.
ST offre un progetto di esempio BSP nel framework STM32CubeMX per iniziare rapidamente a sviluppare con queste periferiche audio. Il progetto contiene driver di basso livello per le periferiche e di livello più alto per le funzionalità del kit Discovery, come il codec audio. Ad esempio, la configurazione dell'ingresso audio dal connettore Line In mediante i driver BSP è molto semplice:
Copy
#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);
Utilizzo di Arm CMSIS-DSP
Se avete già usato Arm per lo sviluppo, conoscerete probabilmente CMSIS (Cortex Microcontroller Software Interface Standard). In caso contrario, si tratta di un Hardware Abstraction Layer con codice che rimane invariato tra diverse implementazioni Arm Cortex. In questo caso, mi interessa la libreria CMSIS-DSP che contiene funzioni comuni di elaborazione dei segnali, ottimizzate per l'architettura Arm.
Per me, il modo più semplice per incorporare le librerie CMSIS è stato direttamente dalla sorgente. L'intero repository CMSIS può essere clonato da GitHub di Arm, ma per iniziare solo le directory CMSIS/DSP/Include e CMSIS/DSP/Include devono essere aggiunte al vostro progetto ST. In genere, nella struttura predefinita del progetto, devono essere copiate nella directory Drivers/CMSIS.
Ci sono due modifiche rapide da apportare prima di compilare. Anzitutto, aggiungete la nuova directory CMSIS/DSP/Include nei percorsi Include del progetto. L'intestazione arm_math.h è ciò che dovete aggiungere all'applicazione per accedere alle funzioni DSP.
In secondo luogo, ci sono due #define che la libreria DSP utilizza per le informazioni sull'architettura hardware: __FPU_PRESENT e ARM_MATH_CM7. Ho capito che, per trovarli, il modo migliore è aggiungerli ai simboli di progetto globali come indicato di seguito.
Figura 1. Definizioni dei simboli di progetto.
A questo punto, per calcolare un FFT servono solo poche righe:
Copy
#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);
L'unione delle parti
Una volta calcolato l'FFT, vedere i risultati graficamente è appagante. La funzione seguente combina funzioni dai driver ST BSP e dalla libreria CMSIS-DSP per disegnare un grafico in stile visualizzatore minimalista sul display del kit Discovery.
Figura 2. Visualizzatore mostrato sul kit Discovery.
Copy
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);
}
}
Conclusione
STM32H735 è un potente microcontroller con svariate funzionalità specialmente per la multimedialità e le applicazioni di elaborazione del segnale. DigiKey è distributore esclusivo fino alla fine del mese, quindi date un'occhiata al nostro sito Web se pensate che il prodotto possa fare al caso vostro per il prossimo progetto.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum


Taylor Roorda, Associate Applications Engineer presso DigiKey, è entrato a far parte dell'azienda nel 2015 e le sue principali aree di interesse sono i sistemi embedded, la logica programmabile e l'elaborazione di segnale. Ha conseguito una laurea in ingegneria elettrica presso North Dakota State University e passa il tempo libero a suonare la chitarra e a scrivere musica.


