Mesurer l'harmonie - Analyseur de spectre sonore à la découverte du STM32L4

LCD STM32L4 Discovery. - , , . , FreeRTOS, , 12 , 53 , 12.






, (FPU ) LCD ' '. . , , — , , . , , STM32Cube, DFSDM_AudioRecord. DFSDM? Digital Filter for Sigma-Delta Modulation. , , , Discovery, , , . , . , . , , , — . , . . DFSDM_AudioRecord.



Le son numérisé à l'aide de DMA tombe dans le tampon en anneau. DMA provoque une interruption deux fois: une fois - lorsque le tampon est à moitié plein, la deuxième fois - lorsqu'il est plein. La routine d'interruption définit simplement l'indicateur approprié. La fonction main () après l'initialisation exécute une boucle infinie où ces indicateurs sont vérifiés et, si l'indicateur est défini, la moitié correspondante du tampon est copiée. Un exemple copie des données dans un autre tampon, d'où elles, à nouveau à l'aide de DMA, sont envoyées à l'amplificateur pour casque. J'ai quitté cette fonctionnalité, en ajoutant le calcul du spectre du signal audio.

Lorsqu'il y a de nombreuses tâches


La manière simple d'ajouter de nouvelles fonctionnalités à notre code consiste à ajouter d'autres indicateurs et à écrire des fonctions qui seront appelées si ces indicateurs sont définis. Le résultat est généralement un gâchis de drapeaux, de fonctions de gestionnaire et du contexte global, qui est forcé d'être global, car la solution d'un problème est divisée en plusieurs petites étapes implémentées par des fonctions individuelles - les gestionnaires d'événements. Une autre manière consiste à confier la gestion des tâches à un système d'exploitation, tel que FreeRTOS. Cela vous permet de simplifier considérablement la logique du fait que chaque tâche est résolue dans son propre cycle d'événements de traitement qui interagissent les uns avec les autres via les fonctions du système d'exploitation. Par exemple, nous pouvons ajouter une tâche de traitement des données en tant que cycle distinct,qui attendra que les données soient prêtes sur la primitive de synchronisation - sémaphore. Le sémaphore est très simple: vous pouvez le passer si le drapeau est coché, et le drapeau est automatiquement omis. Dans notre cas, la source de données lèvera un indicateur lorsqu'elle préparera des données pour une autre tâche. De la même manière, vous pouvez créer des chaînes arbitraires à partir des tâches de source de données et des tâches de consommateur de données, comme cela se produit, par exemple, dans le système d'exploitation Linux.dans le système d'exploitation Linux.dans le système d'exploitation Linux.



Bien sûr, l'exécution simultanée de tâches est une illusion, surtout lorsque le cœur de calcul n'est qu'un. Dans ce cas, nous pouvons dire que nous avons un seul thread d'exécution de programme par le processeur. Les sémaphores, comme d'autres primitives de synchronisation, jouent le rôle d'un trou de lapin magique, dans lequel le flux d'exécution ne parvient pas à émerger dans une autre tâche.

Connecter FreeRTOS à votre projet est assez simple. Il suffit de remplacer la boucle sans fin, qui termine généralement la fonction main () dans le microcontrôleur, par un appel à osKernelStart (). Après cela, le compilateur vous expliquera exactement ce qui lui manque pour la compilation. Toutes les actions que vous avez précédemment effectuées dans la boucle doivent être transférées vers une tâche distincte et enregistrées avec l'appel xTaskCreate. Après cela, vous pouvez ajouter autant de tâches que vous le souhaitez. Il convient de garder à l'esprit qu'entre les appels à xTaskCreate et osKernelStart, il est préférable de ne pas placer de code qui fonctionne avec le matériel, car ici le temporisateur système peut ne pas fonctionner correctement. L'appel au gestionnaire de temporisation du système d'exploitation osSystickHandler () doit être ajouté à SysTick_Handler (), et les deux fonctions SVC_Handler et PendSV_Handler doivent être supprimées de leur code,car ils sont implémentés dans le code OS. Lors de l'enregistrement des tâches, il est important de ne pas se tromper avec la taille de la pile. S'il s'avère trop petit, vous obtiendrez des plantages dans les endroits les plus inattendus. Le premier lorsque la pile déborde est la structure elle-même qui décrit la tâche. IAR a la possibilité d'afficher une liste de tâches. Si vous voyez une tâche avec un nom modifié, vous devez augmenter la taille de la pile.


. . , , . , , ( 0). , , . , . , , . , . , , , 44.1kHz. 6 — 20kHz, 10kHz, 5kHz, 2600Hz, 1300Hz, 650Hz. . / '', . (), , . FPU, - , , format pour représenter un nombre dans float32 . Le bit le plus significatif est un signe. Les 8 bits suivants sont l'exposant binaire plus 127. Les bits restants sont la partie fractionnaire de la mantisse malgré le fait que la partie entière soit 1 (nous omettons les nuances des nombres dénormalisés pour plus de simplicité). Ainsi, après avoir sélectionné l'exposant de float32 et saisi les plusieurs bits les plus significatifs de la mantisse, vous pouvez obtenir une bonne approximation du logarithme. En utilisant le tableau pré-préparé, nous convertissons le nombre résultant en un code RVB pour l'affichage sur l'écran LCD. Il se révèle une échelle de couleurs de 90 ou 60 décibels. Le niveau de volume correspondant au zéro de cette échelle peut être ajusté en poussant le joystick vers le haut et vers le bas.

Nous affichons une image - sur les avantages de la lecture des fiches techniques


Il ne nous reste plus qu'à afficher l'image et faire revivre notre «cascade». La façon la plus simple de le faire est de stocker l'image de tout l'écran dans un tampon, de la mettre à jour et de la redessiner à chaque fois que de nouvelles données apparaissent. Non seulement cette solution est extrêmement inefficace, mais nous n'avons pas non plus assez de mémoire pour stocker l'image entière. Il semblerait que l'écran LCD lui-même dispose de suffisamment de mémoire pour cela, et il devrait pouvoir faire quelque chose d'intéressant avec lui. En effet, l'étude de la fiche techniqueautorisé à détecter la commande de défilement jusqu'à présent inutilisée, ce qui vous permet de modifier dynamiquement la façon dont la mémoire du contrôleur LCD est affichée à l'écran. Imaginez que la mémoire est une bande enfermée dans un anneau que vous voyez sous la vitre de l'écran. La commande Vertical Scrolling Start Address (0x37) vous permet de définir la position sur le ruban correspondant au bord supérieur de l'écran. Donc, tout ce dont nous avons besoin pour faire revivre la «cascade» est d'enregistrer un nouveau spectre dans cette position et de faire défiler la bande mémoire. Le code correspondant a été ajouté au pilote LCD, emprunté au réputé Peter Drescher , et adapté comme décrit ici. Seul inconvénient de cette approche: le défilement ne fonctionne que sur le côté long de l'écran. Par conséquent, seul le côté court est disponible pour la sortie du spectre.

12 ?


Passons aux applications pratiques de notre appareil. La première chose qui est facile à voir sur le spectre est les harmoniques, c'est-à-dire les fréquences qui sont des multiples de la fréquence fondamentale. Surtout beaucoup d'entre eux dans la voix. Il y a aussi dans les sons qui font les instruments de musique. Il est facile de comprendre pourquoi les notes des octaves voisines diffèrent en fréquence par 2 fois: alors les notes d'une octave supérieure coïncident en fréquence avec la deuxième harmonique des notes d'une octave basse. Ils disent qu'en même temps ils sonnent "à l'unisson". Il est un peu plus difficile de comprendre pourquoi il y a 12 notes dans une octave - sept principales (touches blanches sur le clavier du piano) plus 5 supplémentaires (touches noires). Les notes supplémentaires sont indiquées par les notes principales avec des caractères nets et plats, bien qu'en fait il n'y ait pas de différence entre elles et les notes principales - les 12 notes forment une progression géométrique doncque le rapport des fréquences entre les notes adjacentes est égal à la racine du 12e degré de 2. La signification de cette division de l'octave en notes est que pour chaque note, il existe d'autres notes dont la fréquence diffère d'une fois et demie - cette combinaison est appelée la cinquième. Les notes qui composent la cinquième note sonnent à l'unisson car la deuxième harmonique d'une note coïncide en fréquence avec la troisième harmonique de l'autre note. La photo ci-dessous montre les spectres des notes Do et Sol, formant une cinquième, les harmoniques correspondantes sont entourées de jaune.formant un cinquième, les harmoniques correspondantes sont entourées de jaune.formant un cinquième, les harmoniques correspondantes sont entourées de jaune.



Comment se fait-il que les notes 12? Comme les notes forment une progression géométrique, nous passons aux logarithmes. ln (1,5) / ln (2) = 0,58496 ... Une valeur proche est obtenue pour la fraction 7/12 = 0,583 ... Autrement dit, sept demi-tons (intervalles entre les notes adjacentes) se révèlent être très proches d'une quint - 1,498. Fait intéressant, la fraction 31/53 = 0,58491 .. donne une précision beaucoup plus grande, de sorte que le cinquième n'est différent de 1,5 qu'à la cinquième décimale. Ce fait n'est pas passé inaperçu, mais les instruments de musique avec 53 notes dans une octave n'ont pas été distribués. Ils sont difficiles à régler, ils sont difficiles à jouer et le pourcentage de personnes qui peuvent ressentir la différence avec des outils conventionnels est extrêmement faible.

Code source


Se trouve ici . Pour la compilation, IAR Embedded Workbench pour ARM 7.50.2 a été utilisé. Aucune autre bibliothèque n'est requise pour la compilation.

Source: https://habr.com/ru/post/fr391311/


All Articles