Sonneries Atmega8. Sirènes sonores simples sur MK AVR. Utiliser le module de son

L'article décrit les principes de la synthèse musicale sur un AVR. Le logiciel inclus vous permet de convertir n'importe quel fichier midi en source en C pour les microcontrôleurs AVR pour ajouter la lecture de fragments musicaux aux développements prêts à l'emploi. Un exemple d'utilisation d'un logiciel dans une boîte à musique est considéré.

Tout d'abord, une courte vidéo montrant comment tout cela fonctionne :

Ce que permet le logiciel

Le logiciel PC permet d'obtenir une source C pour CodeVision AVR, qui lit le fichier midi sélectionné :

1. Connectez common\hxMidiPlayer.h, common\hxMidiPlayer.c à votre projet. Copiez les modèles ATMega8Example\melody.h, ATMega8Example\melody.c, ATMega8Example\hxMidiPlayer_config.h et connectez-vous.
2. Lancez MidiToC.exe
3. Chargez le fichier Midi.
4. Configurez le lecteur : taux d'échantillonnage, nombre de canaux, forme d'onde, etc. Le logiciel joue la mélodie de la même manière que l'AVR le fera.
5. Cliquez sur « Créer une configuration de lecteur » et collez la source dans hxMidiPlayer_config.h.
6. Cliquez sur « Créer un code mélodique » et collez la source dans melody.c.
7. Dans notre projet, nous implémentons la méthode Player_Output() pour produire du son via PWM ou un DAC externe.
8. Réglez la minuterie sur la fréquence d'échantillonnage et appelez Player_TimerFunc() à partir de l'interruption.
9. Appelez Player_StartMelody(&s_melody, 0).

La mélodie est jouée à partir de l'interruption du minuteur. Cela signifie que pendant la lecture, le microcontrôleur peut également effectuer un travail utile.

Comment ça fonctionne

Dans la suite de l’article je vais essayer d’expliquer brièvement comment tout cela est mis en œuvre. Malheureusement, ce ne sera pas très court – il y a beaucoup de matière. Si vous n’êtes pas intéressé, vous pouvez immédiatement vous rendre dans les sections « Description du logiciel » et « API du lecteur ».

Qu'est-ce que la musique

La musique est une séquence de sons de fréquences et de durées variables. La fréquence de l'harmonique fondamentale d'un son doit correspondre à la fréquence d'une certaine note. Si la fréquence de vibration des sons diffère de celle des notes, il nous semble que le musicien est « désaccordé ».

Tableau. Notez les fréquences, Hz.

Toutes les notes sont divisées en octaves, 7 notes dans chacune + 5 demi-tons (touches noires du piano). Les fréquences des notes dans les octaves adjacentes diffèrent exactement de 2 fois.

Le lecteur de musique le plus simple contient un tableau avec la séquence de notes (note + durée) d'une mélodie et un tableau avec les fréquences des notes. Pour synthétiser le son, on utilise l'un des canaux du timer, qui forme un méandre :

Malheureusement, un tel joueur primitif a une forme d'onde fixe (onde carrée), qui n'est pas très similaire aux vrais instruments de musique, et ne peut jouer qu'une seule note à la fois.

Une vraie mélodie contient au moins deux parties (solo + basse), et lorsqu'elle est jouée au piano, la note précédente continue de résonner lorsque la suivante a commencé. Ceci est facile à comprendre en se souvenant de la structure d’un piano : chaque note correspond à une corde distincte. On peut faire sonner plusieurs cordes en même temps en passant nos mains sur les touches.

Certains microcontrôleurs disposent de plusieurs canaux de minuterie, ceux-ci peuvent être utilisés pour jouer plusieurs notes simultanément. Mais ces canaux constituent généralement une ressource précieuse et il n’est pas conseillé de tous les utiliser. À moins, bien sûr, que nous fassions simplement une boîte à musique.
Au total, pour obtenir une polyphonie et des sons variés d'instruments de musique, il faut utiliser la synthèse sonore.

Synthèse sonore sur AVR

hxMidiPlayer utilise la synthèse audio et peut jouer de la polyphonie avec différentes formes d'onde. Le lecteur calcule l'amplitude du signal de sortie dans le gestionnaire d'interruption de minuterie avec une fréquence de 8 à 22 kHz (la puissance du processeur suffisante ; dépend également de la forme d'onde et du nombre de canaux).

Le principe de la synthèse sonore peut être expliqué à l’aide de l’exemple de la synthèse sinusoïdale.

Prenons un tableau de taille 64, dans chaque cellule dont les valeurs de l'amplitude sinusoïdale sont écrites aux points indice * 2 * PI/64 (une période) :

Flash const statique uint8_t s_sineTable[ 64 ] = ( 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x93, 0x93, 0x94, 0x95, 0x95, 0x 9 5, 0x95, 0x95, 0x94 , 0x93, 0x93, 0x91, 0x90, 0x8F, 0x8D, 0x8C, 0x8A, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7E, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0 x7 1, 0x70, 0x6F, 0x6D, 0x6D, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6C, 0x6D, 0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E );

128 (0x80) correspond à zéro, 255 (0xff) au plus grand point positif, 0 au plus grand point négatif.

Disons maintenant que nous allons afficher les valeurs du tableau vers un DAC externe lors d'une interruption de minuterie appelée à une fréquence de 1000 Hz :

Statique uint8_t s_index = 0 ; // Comparaison de la sortie Timer1 Une routine de service d'interruption interruption void timer1_compa_isr(void) ( SetDac(s_sineTable[ s_index]); if (s_index == 63) ( s_index = 0; ) else ( s_index++; ) )

Qu’obtiendrons-nous en conséquence ? Nous obtiendrons des oscillations sinusoïdales avec une fréquence de 1000/64 Hz.

Augmentons maintenant l'index de l'interruption non pas de 1, mais de deux.
Évidemment, la fréquence d'oscillation de sortie sera déjà de 1000/64 * 2 Hz.

En général, pour obtenir la fréquence F, il faut augmenter l'indice dans le tableau de :
ajouter = F / 1000 * 64

Ce nombre peut être fractionnaire, mais pour obtenir une vitesse élevée, l'arithmétique à virgule fixe est utilisée.

Le nombre d'entrées dans le tableau et la fréquence de la minuterie affectent la qualité du son synthétisé. Dans notre cas, 64 entrées dans le tableau par période suffisent et la fréquence du timer est de 12 kHz. La fréquence de minuterie minimale acceptable est de 8 kHz, l'idéal est de 44 kHz.

Évidemment, avec une fréquence de minuterie de 12 kHz, nous pouvons générer un maximum d'ondes carrées de 6 kHz, puisqu'il faut effectuer au moins deux commutations par période. Cependant, les fréquences plus élevées seront toujours reconnaissables si l'état de sortie est correctement calculé à chaque tick de minuterie.

Vous pouvez saisir des valeurs pour la période d'oscillations non sinusoïdales dans le tableau et obtenir un son différent.

Atténuation

Si un instrument de musique est basé sur des cordes (par exemple, un piano), après avoir appuyé sur une touche, le son s'estompe doucement. Pour obtenir un son de synthétiseur plus naturel, vous devez réduire progressivement l'amplitude des vibrations après le début de la note (« envelopper » les vibrations dans une forme d'atténuation – « enveloppe »).

Le lecteur contient une table de décroissance qu'il utilise pour réduire l'amplitude de la sinusoïde (ou d'une autre forme d'onde) à partir du moment où la note commence.
« Sine » « enveloppé » dans une telle coque ressemble au son d'une boîte à musique mécanique.

Synthèse de méandres

La forme particulière de l’onde méandrique permet de simplifier considérablement la synthèse. Les tableaux ne sont pas utilisés dans ce cas. Il suffit de calculer quel état (1 ou 0) la sortie doit avoir à une fréquence donnée au tick de minuterie actuel. Cela se fait à l'aide de l'arithmétique entière et fonctionne très rapidement, ce qui explique la popularité de l'utilisation d'une onde carrée pour lire des morceaux dans des décodeurs 8 bits.

Exemple : déclarer un compteur :

Statique uint16_t s_counter = 0 ;

que nous augmenterons de 0x8000 à chaque interruption de la minuterie, et le bit le plus significatif du compteur sera envoyé au port :

// Comparaison de la sortie Timer1 Une routine de service d'interruption interruption void timer1_compa_isr(void) ( PORTA.0 = (s_counter >> 15) & 1; s_counter += 0x8000; )

Puisque 0x8000 + 0x8000 = 0x10000, la variable s_counter déborde, le 17ème bit est ignoré et 0x0000 est écrit dans la variable.
Ainsi, avec une fréquence de minuterie de 8 KHz, la sortie sera une onde carrée de 4 KHz.
Si vous augmentez le compteur de 0x4000, vous obtenez une onde carrée de 2KHz.

En général, vous pouvez obtenir la fréquence F en ajoutant :
ajouter = F / 8000 * 0x10000

Par exemple, pour obtenir une onde carrée avec une fréquence de 1234 Hz, vous devez ajouter 0x277C. La fréquence réelle sera légèrement différente de celle donnée, car nous arrondissons le terme à un nombre entier. Ceci est acceptable dans un synthétiseur.

Synthèse de sons d'instruments réels

Vous pouvez numériser le son de la note devant le piano (à l'aide d'un CAN pour stocker les valeurs d'amplitude sonore en mémoire à intervalles réguliers) :
puis jouez le son (en utilisant le DAC pour sortir les valeurs enregistrées à intervalles réguliers).

En général, pour synthétiser de la batterie, vous devez enregistrer les sons de batterie et les reproduire au bon moment. Dans les consoles 8 bits, le « bruit blanc » est utilisé à la place des sons de batterie. Les valeurs d'amplitude du « bruit blanc » sont obtenues à l'aide d'un générateur nombres aléatoires. Les coûts de mémoire sont minimes.
hxMidiPlayer utilise le « bruit blanc » pour la synthèse de batterie.

Mixage des canaux

L'amplitude sonore à un tick de minuterie donné est calculée pour chaque canal séparément. Pour obtenir la valeur d'amplitude finale, vous devez additionner les valeurs de tous les canaux. Il est correct d'ajuster la somme, car le volume perçu obéit à une dépendance logarithmique, mais dans un synthétiseur aussi simple, vous devrez vous contenter d'une simple addition. Par conséquent, l’amplitude maximale de chaque canal est de 255/N.

Sortie du son depuis l'AVR

Après avoir effectué tous les calculs nécessaires, le lecteur reçoit le niveau de signal qui doit être converti en analogique. À ces fins, vous pouvez utiliser un DAC externe ou un PWM.
Il convient de noter ici que dans les deux cas, il est conseillé de filtrer le signal reçu - pour éliminer le bruit haute fréquence dû à la basse fréquence de synthèse et d'arrondi.

Sortie vers DAC parallèle externe

Comme cela n'a pas de sens d'utiliser des puces DAC précises, de tels projets se contentent généralement d'une matrice R2R :

Avec ce schéma, nous transmettons simplement l'amplitude calculée au port :

PORTB = échantillon ;

Défauts:
1) la sortie de la matrice R2R est également signal faible, l'utilisation d'un amplificateur analogique est obligatoire ;
2) il faut utiliser au moins 5 broches (et de préférence 8) ;
Cette méthode n'est justifiée que lorsqu'il n'y a pas de canaux PWM libres.

(pour enregistrer les broches, vous pouvez utiliser un ADC externe avec une interface SPI).

MLI

S'il existe un canal PWM gratuit, le moyen le plus simple consiste à utiliser cette méthode.

Initialisation PWM (ATMega8) :

// Initialisation du minuteur/compteur 2 // Source d'horloge : horloge système // Valeur d'horloge : 20 000,000 kHz // Mode : PWM rapide top=0xFF // Sortie OC2 : PWM non inversé ASSR=0x00 ; TCCR2=0x69 ; TCNT2=0x00 ; ROC2=0x00 ; Et l'exemple de sortie : void Player_Output(uint8_t sample) ( OC2 = sample. )

La pratique courante d'utilisation du PWM consiste à lisser le signal de sortie à l'aide d'un filtre RC :

Malheureusement, après filtrage, le signal est trop affaibli, il faut donc fabriquer un amplificateur analogique pour connecter le haut-parleur.

Pour simplifier le circuit, mieux vaut rester « numérique » jusqu’à l’enceinte elle-même. Puisqu’un haut-parleur bon marché ne peut toujours pas reproduire les fréquences supérieures à 30 kHz, il n’est pas nécessaire de les filtrer. Le diffuseur lui-même « filtrera » les hautes fréquences PWM.

Si vous avez besoin de plus de courant, vous pouvez utiliser un amplificateur à transistor. R1 est sélectionné pour fournir le courant requis au haut-parleur.

Voici comment connecter de petites enceintes à des jouets :

Pour les enceintes plus grosses, il est préférable d'assembler le variateur à l'aide de 2 transistors et d'installer un filtre LC pour supprimer le bruit :

Le condensateur C1 sert à limiter le courant traversant le haut-parleur lorsque le PWM ne fonctionne pas. De plus, grâce à l'inclusion d'un condensateur série, un signal symétrique par rapport à zéro atteint le haut-parleur. Ainsi, le cône du haut-parleur se déplacera par rapport à la position centrale « détendue », ce qui a un effet positif sur la qualité sonore.
Dans ce cas, les transistors fonctionnent en mode commutation, il n'est donc pas nécessaire de compenser le décalage de base.

PWM, connexion à deux broches

L'inconvénient des deux premiers circuits est que le haut-parleur est alimenté en courant dans un sens. Si l'on change le sens du courant, le volume peut être augmenté de 2 fois sans dépasser la puissance admissible. Pour ce faire, le haut-parleur est connecté à deux broches du microcontrôleur - non inversées et inversées, par exemple OC1A et /OC1A. S'il n'y a pas de sortie non inversée, vous pouvez utiliser la deuxième voie en mode inversé (OC1B) :

// Initialisation du minuteur/compteur 1 // Source d'horloge : horloge système // Valeur d'horloge : 24 500 000 kHz // Mode : PWM rapide top=0x00FF // Sortie OC1A : Non-Inv. // Sortie OC1B : Inversée // Suppresseur de bruit : Désactivé // Capture d'entrée sur front descendant // Interruption de débordement du minuteur 1 : Désactivé // Interruption de capture d'entrée : Désactivée // Comparaison d'une interruption de correspondance A : Désactivée // Comparaison d'une interruption de correspondance B : Désactivée TCCR1A =0xB1; TCCR1B = 0x09 ; TCNT1H=0x00 ; TCNT1L=0x00 ; ICR1H=0x00 ; ICR1L=0x00 ; OCR1AH=0x00 ; OCR1AL=0x00 ; OCR1BH=0x00 ; OCR1BL=0x00 ; void Player_Output(uint8_t échantillon) ( OCR1A = échantillon; OCR1B = échantillon; )

PWM, deux broches, amplificateur de classe D

L'inconvénient des circuits proposés est la consommation de courant pendant le silence.
Le « silence » correspond pour nous à un niveau de signal de 128, c'est-à-dire PWM avec un remplissage à 50 % - le courant circule toujours à travers le haut-parleur !

En modifiant légèrement le logiciel, vous pouvez obtenir un amplificateur logiciel et matériel de classe D assez puissant :

Void Player_Output(uint8_t sample) ( if (sample >= 128) ( TCCR2=0x21; //normal, effacé lors de la comparaison TCCR2=0x21 | 0x80; //CLEAR OC2 PORTC.0 = 0; TCCR2=0x69; //non -inversion PWM OCR2 = (échantillon-128) * 2; ) else // if (échantillon< 128) { TCCR2=0x31; //normal, set on compare match TCCR2=0x31 | 0x80; //SET OC2 PORTC.0 = 1; TCCR2=0x79; //inverting PWM OCR2 = (128-sample) *2; } }

Dans ce cas, une paire de transistors est connectée à la sortie PWM, la seconde à une sortie numérique ordinaire.

Comme vous pouvez le voir dans le code, nous considérons un signal supérieur à 128 comme un courant dirigé dans un sens, et un signal inférieur à 128 comme un courant dirigé dans l'autre sens. En 128, les deux broches du haut-parleur sont connectées à la même broche d'alimentation et il n'y a pas de courant. En s'écartant du niveau 128, le remplissage PWM augmente et un courant de polarité correspondante traverse le haut-parleur.

Un point important dans la mise en œuvre est la commutation forcée de la sortie PWM à l'état souhaité au moment de la commutation de la deuxième broche (numérique normale) (PORTC.0). L'écriture dans le registre OCR2 est mise en mémoire tampon pour éliminer les problèmes PWM. Nous devons commuter la sortie PWM immédiatement, sans attendre la fin de la période.

Ce dernier circuit est à mon humble avis la meilleure option en termes de simplicité, d'économies d'énergie et de puissance de sortie.

Sortie sonore avec forme d'onde SquareWave

Lors de la synthèse d'un méandre, des algorithmes simplifiés sont utilisés.

Chaque canal (y compris la batterie) produit soit 0, soit 1. Ainsi, une platine vinyle à 3 canaux produit des valeurs comprises entre 0 et 3. Par conséquent, lors de l’utilisation de PWM, la procédure de sortie ressemble à :

Void Player_Output (échantillon uint8_t) ( OCR2 = échantillon * (255 / HXMIDIPLAYER_CHANNELS_COUNT); )

Si vous n'utilisez pas PWM, alors pour produire une mélodie à 3 canaux, deux sorties numériques ordinaires et une matrice R2R 2 bits suffisent.

Format MIDI

Si vous regardez le code mélodique résultant, vous pouvez facilement voir que le tableau utilise des nombres répétitifs dans une petite plage. C'est compréhensible : la mélodie utilise un nombre limité de notes dans 1 à 2 octaves, le tempo de la mélodie est fixe - des délais égaux, le nombre de canaux est compris entre 0 et 15.
Tout cela signifie que le tableau résultant peut être considérablement réduit en appliquant une sorte d'algorithme de compression.
Des algorithmes comme ZIP offrent une bonne compression, mais nécessitent également beaucoup de mémoire pour fonctionner (dictionnaire ZIP - 64 Ko). Nous pouvons utiliser une méthode de compression très simple qui ne nécessite pratiquement aucune mémoire, dont l'essence est la suivante.

Dans un octet, tous les nombres sont répartis uniformément dans la plage 0...255 et chaque nombre est représenté par 8 bits. Dans notre cas, certains chiffres sont beaucoup plus courants que d’autres. Si vous codez des nombres fréquents avec moins de bits et des nombres moins fréquents avec plus, vous pouvez obtenir un gain de mémoire.

Nous choisissons une méthode de codage fixe : les combinaisons de bits 000,001 et 010 (longueur - 3 bits) représenteront les 3 nombres les plus fréquents. Combinaisons de bits 0110, 0111 (longueur – 4 bits) – les 2 nombres suivants les plus courants, etc. :

//000..010 - 0..2 //011 x 3..4 //100 xx 5..8 //101 xxx 9..16 //110 xxx 17..24 //111 immédiat

La combinaison commençant par 111 (longueur – 11 bits) codera tous les autres nombres.
La méthode de codage des bits peut être différente. J'ai essayé plusieurs méthodes et j'ai choisi celle-ci comme donnant les meilleurs résultats sur de telles données.

La procédure de compression ressemble à ceci :
1. Calculez le nombre total de nombres X dans le flux pour X = .
2. Trier par fréquence décroissante d'apparition dans le flux.
3. Prenez les 25 premiers nombres. Ils seront codés sur moins de bits.
4. Encodez le flux d'entrée.

La sortie est un tableau des 25 nombres les plus fréquents et un flux binaire.
Cette compression vous permet d'obtenir une compression de 50 % avec des coûts de mémoire et de performances minimes. Malheureusement, cela augmente le code du lecteur, la compression n'est donc pas recommandée pour les mélodies courtes.

Stockage des fréquences de notes

Il est assez coûteux de stocker les fréquences de toutes les notes dans un tableau à partir de la mémoire. En fait, il existe une formule pour déterminer la fréquence d'une note par son numéro midi :

F = 2^((N - 69)/12) * 440, Hz

Mais calculer la puissance fractionnaire est assez difficile. Au lieu de cela, le lecteur stocke 12 fréquences de notes dans l'octave supérieure. Les fréquences des notes dans les octaves inférieures sont déterminées en diminuant la fréquence de 2 ^ Y fois supplémentaires, où Y est le nombre d'octaves vers le bas.

Développement ultérieur de la compression

La mélodie contient souvent des fragments répétitifs (« refrains », « couplets »). En trouvant des fragments répétitifs et en présentant la mélodie sous forme de fragments, vous pouvez réduire la mélodie de 50 % supplémentaires, sans perdre de temps. RAM et la productivité. Je n'ai pas implémenté un tel algorithme pour ne pas compliquer le projet.

Description du logiciel

Fenêtre principale du programme de conversion :

Le bouton Load Midi permet de charger un fichier midi. Le programme commence immédiatement à lire le fichier avec les paramètres actuellement sélectionnés, simulant le son qui sera dans le matériel.

La fenêtre d'information (4) affiche :
– Durée – durée du fragment mélodique sélectionné en ms ;
– Canaux de synthétiseur actifs maximum – nombre maximum de canaux de synthétiseur actifs simultanément ;
– Nombre maximum de canaux de batterie actifs – le nombre maximum de canaux de synthétiseur actifs simultanément qui reproduisent la « batterie » ;
– Max notes stéréo actives – nombre maximum de canaux reproduisant la même note (voir ci-dessous) ;
– Taille estimée, octets – taille de la mélodie en octets. En mode « Custom Sample », la taille est affichée sous la forme A+B, où A est la taille de la mélodie, B est la taille de l'échantillon. La taille du code du joueur n'est pas précisée ici.

La fenêtre de progression affiche la position de lecture actuelle.
Vous pouvez cliquer sur la barre de progression pour démarrer la lecture à partir du point spécifié.
Les zones de saisie à gauche et à droite vous permettent de spécifier le début et la fin du fragment mélodique en ms.

L'étiquette « Pas assez de canaux pour jouer la mélodie » en rouge indique qu'il n'y a pas assez de canaux de synthétiseur pour jouer la mélodie avec les paramètres actuels. Si le joueur ne trouve pas de chaîne libre, il désactive la note la plus ancienne. Dans de nombreux cas, cela fonctionnera bien. Il n'est logique d'augmenter le nombre de canaux que lorsque la mélodie semble incorrecte à l'oreille.

Les paramètres peuvent être divisés en paramètres du lecteur et paramètres de traitement des fichiers midi. Le lecteur pourra jouer le code mélodique résultant si la configuration du lecteur et le code mélodique ont été créés avec les mêmes paramètres du lecteur. De plus, le lecteur pourra jouer une mélodie dont le code a été créé pour un lecteur avec un nombre de canaux plus petit (mais pas plus grand).

Les paramètres matériels du lecteur incluent :

– Taux d'échantillonnage – fréquence de synthèse. La fréquence maximale de fusion est déterminée expérimentalement. Basé sur Atmega 16 MHz, vous pouvez commencer à 12 000 Hz pour un lecteur à 6 canaux et l'augmenter à votre guise jusqu'à ce que la distorsion de la mélodie devienne perceptible dans le lecteur matériel. La fréquence maximale dépend du nombre de canaux, de la forme d'onde et de la complexité de la mélodie elle-même.

– Forme d'onde – forme d'onde :
– Onde carrée – méandre ;
– Sinus – sinus ;
– Sine + Enveloppe – sinus avec atténuation ;
– Forme d'onde * + Enveloppe – diverses options pour les ondes non sinusoïdales avec et sans atténuation ;
– Échantillon personnalisé – utilisez un échantillon de l’instrument.

Le bouton « Load Sample » vous permet de charger un échantillon à partir d’un fichier WAV. Le fichier WAV doit être en PCM 8 bits mono, 4173 Hz, C-5. Astuce : vous pouvez augmenter la fréquence et diminuer la note, mais modifiez la hauteur dans les paramètres du lecteur. Il n'y a pas de vérification du format : si le format est différent, le son ne sera pas lu correctement.
Pitch – vous permet de modifier la hauteur du son. Par exemple, pour jouer 1 octave plus haut, vous devez régler le Pitch +12.

Utiliser la compression – utilisez la compression mélodique.
Activer le synthétiseur de batterie – active le synthétiseur de batterie.

Canaux du lecteur : le nombre de canaux du synthétiseur (le nombre maximum de notes qui retentiront simultanément).

Les paramètres de traitement des fichiers Midi incluent :

Généralement, un tel réglage n’est pas nécessaire. Ces paramètres peuvent être laissés par défaut.

API du lecteur

L'implémentation du lecteur se trouve dans les fichiers Common\hxMidiPlayer.c et Common\hxMidiPlayer.h. Ces fichiers doivent être inclus dans le projet. Vous devez également créer un fichier hxMidiPlayer_config.h, dans lequel vous devez placer la configuration.
Le lecteur est écrit en C sans inserts d'assemblage, ce qui facilite son portage sur d'autres microcontrôleurs.

Extern void Player_StartMelody(const flash TMelody* _pMelody, uint16_t _delay);

Commencez à jouer la mélodie. _delay définit le délai initial avant la lecture, 255 unités = 1 seconde.

Vider Player_Stop();

Arrêtez de jouer la mélodie.

Externe bool Player_IsPlaying();

Renvoie false si la mélodie a fini de jouer.

Externe void Player_WaitFinish();

Attendez que la mélodie ait fini de jouer.

Extern void Player_TimerFunc();

Cette fonction doit être appelée lors d'une interruption de minuterie à la fréquence d'échantillonnage spécifiée dans la configuration. Une fois la mélodie terminée, vous n'avez plus besoin de passer d'appels.

Extern void Player_Output (échantillon uint8_t);

Doit être implémenté par l'utilisateur. Appelé par le lecteur lorsque le prochain échantillon doit être sorti.

Externe void Player_Started();

Doit être implémenté par l'utilisateur. Appelé lorsque le joueur commence à jouer une mélodie. Peut être utilisé pour configurer des interruptions de minuterie.

Extern void Player_Finished();

Doit être implémenté par l'utilisateur. Appelé lorsque le joueur a fini de jouer la mélodie. Peut être utilisé pour désactiver les interruptions de la minuterie ou commencer à jouer une autre mélodie.

//#define NOTES_TO_EEPROM //#define SINETABLE_TO_EEPROM //#define ENVELOPE_TO_EEPROM

Ces lignes doivent être décommentées dans le fichier hxMidiPlayer_config.h si la table des notes, la table des sinus et la table d'atténuation doivent être situées dans l'eeprom.

Exemples de projets

ATMega644Example – projet pour ATMega644, 25 MHz, sortie PWM sur PB3.

Exigences de mémoire

Tableau. Taille du lecteur et mélodies en flash.

*lors de l'ajout d'un lecteur à un projet existant non vide, la taille du code sera plus petite

**il n'y a pas assez de canaux pour une lecture normale de la mélodie

Mélodie 1 : bach_minuet_in_g.mid, 35 sec
Mélodie 2 : yiruma-river_flows_in_you.mid, 165 sec
Mélodie 3 : Franz Schubert – Serenade.mid, 217 sec

Comme vous pouvez le voir sur le tableau, dans la configuration minimale, vous pouvez insérer une mélodie assez longue même dans l'ATTiny2313. La compression peut réduire la mélodie de plus de deux fois, mais la taille du code du lecteur augmente d'environ 600 octets.

Les tables de notes sinusoïdales et de décroissance peuvent être placées dans l'EEPROM, économisant respectivement environ 16, 50 et 100 octets de flash.

Lorsque vous utilisez un échantillon d'un fichier wav, vous devez ajouter la taille de l'échantillon en octets à la taille du code du lecteur.

Exemple d'utilisation

À titre d'exemple d'utilisation d'un lecteur, considérons le processus de création d'une boîte à musique.

Nous prenons une boîte MDF prête à l'emploi :

En tant que microcontrôleur, nous considérons ATTiny85 dans le boîtier SO-8 comme le moins cher avec une quantité de mémoire suffisamment grande. Nous allons l'overclocker à 27MHz pour obtenir une fréquence de synthèse de 18KHz avec 4 canaux Sine+Envelope.

L'amplificateur sera de classe D avec 4 transistors pour économiser les piles.

Les transistors fonctionnent en mode commutation et peuvent être de n'importe quel type. L'inductance L1 et le condensateur C6 sont sélectionnés selon vos goûts pour obtenir un son sans bruit haute fréquence. R1 et R2 peuvent être augmentés jusqu'à 2K pour baisser le volume et réduire le rebond du haut-parleur.

Le fin de course du lecteur de disque s'adapte parfaitement, comme s'il avait été créé spécifiquement pour la boîte (il fonctionne pour s'ouvrir - lorsque vous ouvrez le couvercle, l'alimentation est fournie à la carte) :

Les sources du firmware se trouvent dans le répertoire ATTiny85MusicBox.

8 Ko convient :
1) lecteur : 18000Hz, 4 canaux, Sine+Envelope, Pitch+12, compression, joue les mélodies une par une (la dernière est stockée en EEPROM)
2) Yiruma – La rivière coule en vous
3) Franz Schubert – Sérénade
4) P.I. Tchaïkovski « Octobre »

Résultat en vidéo :

La poursuite du développement

En principe, le lecteur peut être développé davantage, pour en faire un lecteur Midi ou MOD à part entière. Personnellement, je pense que pour obtenir une mélodie de haute qualité, il serait plus facile de connecter une carte SD et de lire tous les fichiers WAV à partir de celle-ci, avec bien plus encore. meilleure qualité qu'il est généralement possible d'obtenir par synthèse logicielle. Et un tel lecteur est beaucoup plus simple en termes de logiciel et de matériel. Le créneau de hxMidiPlayer ajoute un bon son aux projets prêts à l'emploi lorsqu'il reste quelques jambes et un peu d'espace dans le flash. Il s’acquitte de cette tâche « excellent » déjà sous sa forme actuelle.

Je pense que cela peut résoudre le problème de la création de toutes sortes de boîtes à musique/cloches sur AVR :)

La suite du cours a pris beaucoup de temps, ce qui est compréhensible ; j'ai dû maîtriser le travail avec les cartes mémoire et les fichiers Système FAT. Mais quand même, c'est arrivé, la leçon est prête - en fait, un miracle du Nouvel An.

Afin de ne pas surcharger l'article d'informations, je ne décrirai pas la structure du format de fichier wav, il y a largement assez d'informations dans les moteurs de recherche. Qu'il suffise de dire que si vous ouvrez un fichier avec une sorte d'éditeur Hex, les 44 premiers octets contiennent toutes les informations sur le type de fichier, la fréquence d'échantillonnage, le nombre de canaux, etc. Si vous avez besoin d'analyser le fichier, lisez ceci en-tête et vous serez heureux.

Les données de charge utile commencent à 44 octets, contenant essentiellement les niveaux de tension qui composent le son. Nous avons déjà parlé des niveaux de tension dans la dernière partie de la leçon. Ainsi, tout est simple, vous devez transmettre ces étapes au haut-parleur à la fréquence d'échantillonnage du fichier.

Comment faire trembler physiquement une enceinte ? Vous devez produire ces niveaux de tension en utilisant PWM ou utiliser R2R. Dans tous les cas, c'est très simple à utiliser, lisez le numéro, mettez-le soit en OCR, soit en PORTx. Puis, après un certain temps, j'ai remplacé la valeur suivante et ainsi de suite jusqu'à la fin du fichier.

Exemple, un certain fichier wav, les données proviennent des octets 44=0x2C, le nombre 0x80 y est écrit, on reproduit le son, par exemple, par PWM du premier timer, on écrit OCR1A=0x80 ; Disons que la fréquence d'échantillonnage de l'échantillon est de 8 kHz, l'interruption doit donc être réglée sur la même fréquence. Dans l'interruption, remplacez la valeur suivante 0x85 après 1/8000 = 125 µs.

Comment régler l'interruption sur 8 kHz ? Rappelons que si le temporisateur fonctionne à une fréquence de 250 kHz, alors le registre de comparaison d'interruptions doit être remplacé par (250/8)-1=31-1 ou 0x1E. Avec le PWM, tout est également simple : plus la fréquence à laquelle il fonctionne est élevée, mieux c'est.

Pour que le firmware fonctionne, nous conviendrons que la clé USB est formatée en FAT32, en utilisant la lib PetitFat de la leçon 23.2. Le fichier est au format wav, soit 8 kHz ou 22,050 kHz, mono. Nom du fichier 1.wav. Analysons le firmware.

#inclure #include "diskio.h" #include "pff.h" tampon de caractères non signé[ 512 ] ; /* tampon dans lequel les informations sont copiées depuis le lecteur flash */ nombre int volatile non signé ; //compteur de données copié interrompre [TIM2_COMP] void timer2_comp_isr(void) //interruption dans laquelle les valeurs sont substituées( OCR1A = tampon[ nombre] ; // émet le son vers le haut-parleur si (++ nombre >= 512 ) //augmenter le compteur compte = 0 ; //si 512 est réinitialisé) void main(void) ( unsigned int br; /* compteur de lecture/écriture de fichier */ caractère non signé buf = 0 ; //variable définissant quelle partie du tampon est lue FATFS fs; /* Espace de travail (objet système de fichiers) pour les lecteurs logiques */ PORTB= 0x00 ; DDRB = 0x02 ; //cale de saut ocr1a // Initialisation du Timer/Compteur 1// Source d'horloge : Horloge système // Valeur d'horloge : 8 000 000 kHz // Mode : Fast PWM top=0x00FF // Sortie OC1A : Non-Inv. TCCR1A= 0x81 ; TCCR1B = 0x09 ; TCNT1=0x00 ; OCR1A=0x00 ; // Initialisation du Timer/Compteur 2// Source d'horloge : Horloge système // Valeur d'horloge : 250 000 kHz // Mode : CTC top=OCR2 TCCR2= 0x0B ; TCNT2=0x00 ; //OCR2=0x1E; //mise en place du registre de comparaison pour 8kHz OCR2= 0xA ; //pour 22 kHz #asm("sei") // Initialisation du(des) Timer(s)/Compteur(s) Interruption(s) si (disk_initialize() == 0 ) //initialise la clé USB( pf_mount(&fs) ; //monter système de fichiers pf_open("1.wav" ) ; //ouvre un fil de discussion pf_lseek(44) ; //déplace le pointeur vers 44 pf_read(tampon, 512 ,& br) ; //pour la première fois, nous avalons 512 octets d'un coup TIMSK= 0x80 ; //allumer la musique pendant que (1) ( if (! buf && count> 255 ) //si plus de 255 octets sont reproduits,( pf_read(& buffer[ 0 ], 256 ,& br) ; //puis nous lisons les informations du lecteur flash dans la première moitié du tampon buf= 1 ; si (br< 256 ) //si le buffer ne contient pas 256 valeurs, cela signifie la fin du fichier casser ; ) si (buf && compte< 256 ) { pf_read(& buffer[ 256 ] , 256 ,& br) ; // lit la deuxième partie du tampon depuis le lecteur flash buf = 0 ; si (br< 256 ) break ; } } TIMSK = 0x00 ; //глушим все pf_mount(0x00 ) ; //démonter le voile) tandis que (1 ) ( ) )

#inclure #include "diskio.h" #include "pff.h" tampon de caractères non signés ; /* tampon dans lequel les informations sont copiées à partir du lecteur flash */ volatile unsigned int count ; //compteur d'interruption de données copiées void timer2_comp_isr(void) //interruption dans laquelle les valeurs sont substituées ( OCR1A = buffer; //sortie du son vers le haut-parleur if (++count >= 512) //augmenter le compteur = 0; //if 512 reset ) void main(void) ( unsigned int br; /* compteur de lecture/écriture de fichier */ unsigned char buf = 0; //variable définissant quelle partie du tampon est lue FATFS fs; /* Working zone (objet du système de fichiers) pour les lecteurs logiques */ PORTB=0x00; DDRB=0x02; //sauter la cale ocr1a // Initialisation de la minuterie/compteur 1 // Source d'horloge : horloge système // Valeur d'horloge : 8 000 000 kHz // Mode : PWM rapide top=0x00FF // Sortie OC1A : Non-Inv. TCCR1A=0x81 ; TCCR1B=0x09 ; TCNT1=0x00 ; OCR1A=0x00 ; // Initialisation de la minuterie/compteur 2 // Source d'horloge : Horloge système // Valeur de l'horloge : 250 000 kHz // Mode : CTC top= OCR2 TCCR2=0x0B; TCNT2=0x00; //OCR2=0x1E; //réglage du registre de comparaison pour 8kHz OCR2=0xA; //pour 22kHz #asm("sei") // Minuterie(s)/Compteur(s) Interruption(s) initialisation if(disk_initialize()==0) //initialise le lecteur flash ( pf_mount(&fs); //monte le système de fichiers pf_open("1.wav"); //ouvre la branche pf_lseek(44); //déplace le pointeur vers 44 pf_read(buffer, 512,&br); //pour la première fois, nous avalons 512 octets d'un coup TIMSK=0x80; //allume la musique while(1) ( if(!buf && count>255) //si plus de 255 octets ont été lus, ( pf_read(&buffer, 256,&br);//puis lis les informations du flash conduire dans la première moitié du tampon buf=1 ; if (br< 256) //если буфер не содержит 256 значений значит конец файла break; } if(buf && count<256) { pf_read(&buffer, 256,&br); // читаем во вторую часть буфера с флешки buf = 0; if (br < 256) break; } } TIMSK = 0x00; //глушим все pf_mount(0x00); //демонтируем фат } while (1) { } }

Pour vérifier, on connecte un haut-parleur à la broche OCR1A via un condensateur de 100uF, "+" à la broche du microcontrôleur, "-" au haut-parleur. « - » haut-parleur à la masse, « + » au condensateur.

Ne vous attendez pas à un signal fort à la sortie ; vous avez besoin d’un amplificateur pour avoir un son fort. Ceci est clairement visible dans la vidéo. Pour le test, j'ai chargé le coq en 8 kHz et la piste en 22 kHz.

Ceux qui le souhaitent peuvent augmenter en toute sécurité la fréquence de timer2 afin de lire des fichiers à 44 kHz ; les expériences montrent qu'une assez bonne qualité sonore peut être obtenue. Dans la vidéo, le son est faible et la qualité est mauvaise, mais en fait cela est dû au fait que je l'ai filmé avec une caméra.

Je publie également des documents aimablement fournis par Apparatchik - le code source de GCC, à partir duquel le firmware de CAVR a été écrit.

Et vidéo avec lecture 44 kHz.

J'en profite pour féliciter tout le monde pour la nouvelle année, je souhaite que tous les firmwares et appareils fonctionnent pour vous :)

projet de lecteur wav sur Atmega8

J'ai écrit un module logiciel qui vous permet d'ajouter la fonction de lecture de mélodies ou de séquences sonores à presque n'importe quel projet sur le microcontrôleur AVR.

Caractéristiques des modules :

Intégration facile avec un projet prêt à l'emploi

Seul le temporisateur 8 bits t2 est utilisé, alors qu'il reste possible de l'utiliser pour du polling ou pour former des intervalles de temps.

Le module est réglable sur presque toutes les fréquences du générateur d'horloge

La hauteur des notes est spécifiée sous forme de constantes symboliques (C0, A2, etc.) ou en Hertz

Les durées sont précisées sous forme standard (quarts, huitièmes, etc.) ou en millisecondes

Il est possible de régler le tempo de lecture de la mélodie et le nombre de ses répétitions

Pendant la lecture, la mélodie peut être mise en pause


Connecter un module de son

1. Copiez tous les fichiers du module (tone.h, sound.h, sound.c) dans le dossier du projet.

2. Connectez le fichier sound.c au projet.

Pour IAR `a – cliquez avec le bouton droit dans la fenêtre de l’espace de travail et sélectionnez Ajouter > Ajouter des fichiers…

Pour WINAVR c'est à peu près pareil, seul sound.c doit être ajouté au makefile :

SRC = $(TARGET).c son.c

3. Incluez le fichier d'en-tête sound.h dans le module correspondant. Par exemple, dans main.c

#include "son.h"

4. Définissez les paramètres du module dans le fichier sound.h

//si vous commentez, la durée des notes sera

//calculé à partir du BPM spécifié dans la mélodie

//si laissé, alors à partir de la valeur spécifiée ci-dessous

//#définir SOUND_BPM 24

//fréquence d'horloge μ

#définir SOUND_F_CPU 16U

//sortie du microcontrôleur sur laquelle le son sera généré

#définir PORT_SOUND PORTB

#définir PINX_SOUND 0

//nombre de mélodies spécifiées.

#définir SOUND_AMOUNT_MELODY 4

5. Ajoutez vos mélodies à sound.c et écrivez les noms des mélodies dans le tableau des mélodies.

Ajout de sonneries

La mélodie est un tableau de nombres de 16 bits et a la structure suivante

BPM (noires par minute) est une constante utilisée pour calculer la durée des notes et détermine la vitesse à laquelle la mélodie est jouée.

Le BPM peut aller de 1 à 24, ce qui correspond respectivement à 10 et 240 noires par minute.

Si la durée des notes/sons est spécifiée en millisecondes, alors le BPM écrit dans le tableau doit être égal à 1.

Si la constante SOUND_BPM est commentée dans le fichier d'en-tête sound.h, alors la durée des notes est calculée lors de l'exécution du programme en fonction du BPM spécifié dans le tableau. Si SOUND_BPM n'est pas commenté, la durée des notes est calculée dès la compilation, en fonction de la valeur de cette constante, et toutes les mélodies seront jouées au même tempo. Cela limite les fonctionnalités, mais économise quelques octets de code.

Nombre de répétitions. Peut prendre les valeurs 1 ... 254 et LOOP (255). LOOP - signifie que la mélodie se répétera sans fin jusqu'à ce que la commande SOUND_STOP ou SOUND_PAUSE soit donnée.

Durée de la note– le temps pendant lequel une tonalité sonore donnée est générée ou une pause est maintenue. Peut être spécifié en ms, à l'aide de la macro ms(x), ou en valeurs de notes standard : croches, doubles croches, etc. Vous trouverez ci-dessous une liste des durées prises en charge. Si vous avez besoin de durées exotiques, vous pouvez toujours les ajouter dans le fichier Tone.h.

n1 - note entière

n2 - blanche

n4 - quart

n8 - huitième

n3 - huitième triplet

n16 - seizième

n6 - sextole

n32 - trente-deuxième

Hauteur de note est spécifié à l'aide de constantes symboliques décrites dans le fichier Tone.h, par exemple C2, A1, etc. De plus, la hauteur des notes peut être spécifiée en Hertz à l'aide de la macro f(x).

Le programme a des restrictions sur la fréquence sonore minimale et maximale !

Marqueur de fin de mélodie. La valeur du dernier élément du tableau doit être nulle.

Utiliser le module de son

Au début de main, vous devez appeler la fonction SOUND_Init(). Cette fonction définit la broche de sortie du microcontrôleur, configure la minuterie T2 et initialise les variables du module.

Ensuite, vous devez définir l'indicateur d'activation d'interruption - __enable_interrupt(), car le module utilise des interruptions de débordement de minuterie T2 et de coïncidence.

Après cela, vous pouvez commencer à jouer des mélodies.

Par exemple, comme ceci :

SOUND_SetSong(2);

SOUND_Com(SOUND_PLAY); //joue une mélodie

// place le pointeur sur la 2ème mélodie

//et lance la lecture

SOUND_PlayChanson(2);

La lecture de la mélodie peut être arrêtée à tout moment en émettant la commande SOUND_STOP.
Vous pouvez également mettre la mélodie en pause à l'aide de la commande SOUND_PAUSE. L'émission ultérieure de la commande SOUND_PLAY reprend la lecture de la mélodie à partir du point où elle a été arrêtée.

En principe, cette fonctionnalité n'est pas particulièrement nécessaire (je viens de l'inventer) et lorsque vous travaillez avec le module, la fonction SOUND_PlaySong(unsigned char numSong) suffit ;

Des dossiers

Vous pouvez télécharger des exemples d'utilisation du module de sons à partir des liens ci-dessous. Je n’ai pas fait de schéma car tout y est simple. connecté à la broche PB0, le bouton de démarrage des mélodies est connecté à la broche PD3. Il y a 4 mélodies définies dans les projets. En appuyant sur le bouton, une nouvelle mélodie démarre à chaque fois. Le microcontrôleur atmega8535 est utilisé. Au départ, je voulais m'embêter avec un projet avec quatre boutons - PLAY, STOP, PAUSE et NEXT, mais j'ai ensuite pensé que c'était inutile.

PS : Le module n'a pas subi de tests approfondis et est fourni « tel quel ». S'il y a des propositions rationnelles, finalisons-les.

Dans cet article, nous verrons comment jouer des sons et apprendre à jouer une mélodie monophonique.

Préparation au travail

Le programme déclare deux tableaux. Tableau avec des notes Remarques contient une simple liste de notes. Ces notes correspondent à la durée du son dans le tableau Beats. La durée en musique est déterminée par le diviseur d'une note par rapport à la note entière. La valeur prise dans son ensemble est 255 . Les moitiés, quarts, huitièmes sont obtenus en divisant ce nombre.
Attention, la durée de la première note ne s'obtient pas en divisant 255 par une puissance de deux. Ici, vous devrez passer au solfège. Les notes de la mélodie originale peuvent être visualisées. Ces notes sont combinées en triolets. Lorsqu’elles sont combinées de cette manière, trois croches sonnent de la même manière qu’une noire. Leur durée relative est donc de 21.
L'utilisateur doit également spécifier explicitement le nombre de notes dans la séquence avec la directive :

# définir SEQU_SIZE 19

Dans le programme principal, tout d'abord, les tableaux de fréquences sont recalculés ainsi que la durée en périodes de signaux et la durée des notes.
Avec périodes de signal (tableau signal_période) c'est simple. Pour obtenir la durée de la période en microsecondes, divisez simplement 1 000 000 par la fréquence du signal.
Pour calculer la durée absolue des notes, il faut préciser le tempo de l’œuvre musicale. Cela se fait par directive

# définir le TEMPO 108

Le tempo en musique est le nombre de noires par minute. En ligne

# définir WHOLE_NOTE_DUR 240000 / TEMPO

La durée d'une note entière en millisecondes est calculée. Il suffit maintenant de recalculer les valeurs relatives du tableau à l'aide de la formule Beats au tableau absolu note_durée.
Dans la boucle principale, la variable temps écoulé est incrémenté après chaque période du signal joué de la durée de cette période jusqu'à dépasser la durée de la note. Il convient de prêter attention à cette entrée :

pendant que(temps_écoulé< 1000 * ((uint32_t) note_duration[ i] ) )

Variable temps écoulé 32 bits et les éléments du tableau notes_durée 16 bits. Si un nombre de 16 bits est multiplié par 1000, alors un débordement est garanti et la variable temps écoulé sera comparé à des déchets. Modificateur (uint32_t) convertit un élément du tableau notes_durée[i] dans un nombre de 32 bits, il n'y a pas de débordement.
Vous pouvez voir une autre fonctionnalité dans la boucle audio. Il ne sera pas possible d'utiliser la fonction _delay_us(), puisque son argument ne peut pas être une variable.
Pour créer de tels délais, utilisez la fonction VarDelay_us(). Dans celui-ci, une boucle avec un retard de 1 μs défile un nombre de fois spécifié.

void VarDelay_us(uint32_t takt) ( while (takt- - ) ( _delay_us(1 ) ; ) )

Lors de la lecture d'une mélodie, deux délais supplémentaires sont utilisés. Si les notes sont jouées sans pause, elles fusionneront en une seule. Pour ce faire, un délai de 1 ms est inséré entre eux, précisé par la directive :

# définir NOTES_PAUSE 1

Après chaque cycle complet de lecture de la mélodie, le programme fait une pause pendant 1 seconde et recommence à jouer.
En conséquence, nous avons reçu un code dans lequel il est facile de changer le tempo, d'ajuster la durée ou de réécrire complètement la mélodie. Pour ce faire, il suffira de transformer uniquement la partie du programme comportant des directives et des déclarations de variables.

Tâches individuelles

  1. Dans la mélodie proposée, essayez de changer le tempo et faites une pause de 5 secondes entre les répétitions.
  2. Éléments du tableau Beats n'acceptez que les valeurs de 0 à 255. Modifiez la largeur de bits des éléments du tableau et regardez dans la sortie du compilateur pour voir comment cela affecte la quantité de mémoire occupée par le programme.
  3. Essayez maintenant de changer la mélodie vous-même. Par exemple, voici "Imperial March" du même film : int notes = ( A4, R, A4, R, A4, R, F4, R, C5, R, A4, R, F4, R, C5, R, A4, R, E5, R, E5, R, E5, R, F5, R, C5, R, G5, R, F5, R, C5, R, A4, R); int battements = ( 50 , 20 , 50 , 20 , 50 , 20 , 40 , 5 , 20 , 5 , 60 , 10 , 40 , 5 , 20 , 5 , 60 , 80 , 50 , 20 , 50 , 20 , 50 , 20, 40, 5, 20

    Si votre voiture n’est pas équipée d’une sirène sonore et que vous ne parvenez toujours pas à décider laquelle acheter et installer, cet article est fait pour vous. Pourquoi acheter des alarmes coûteuses si vous pouvez tout assembler vous-même de manière assez simple ?

    J'en présente deux circuits simples sur les microcontrôleurs AVR ATmega8 et Attiny2313, ou plutôt le même circuit est simplement implémenté pour fonctionner sur ces deux microcontrôleurs. À propos, dans les archives, vous trouverez deux versions du firmware du microcontrôleur Atmega8, dont la première reproduit un son similaire à alarme de voiture, et le deuxième son est similaire à une alarme de sécurité d'un bâtiment (signal rapide et précis).

    Vous pouvez télécharger tous les firmwares ci-dessous dans l'archive (ils sont tous signés), dans l'archive vous trouverez également une simulation de circuits dans Proteus, ce qui signifie qu'après avoir écouté tous les morceaux, vous pourrez choisir dans la liste ce que vous préférez .

    Vous trouverez ci-dessous le schéma de signalisation pour Atmega8

    Liste des composants radio utilisés dans le circuit Atmega8

    U1- Microcontrôleur AVR ATmega8-16PU 8 bits, quantité. 1,
    R1- Résistance d'une valeur nominale de 47 Ohms, non. 1,
    R2, R3 - Résistance d'une valeur nominale de 270 Ohms, non. 2,
    D2, D3-LED, non. 2,
    Haut-parleur LS1, non. 1,
    Capteur S1.

    Et dans le circuit de signalisation sur Attiny2313, seul MK a été modifié.
    U1- Microcontrôleur AVR 8 bits ATtiny2313-20PU, quantité. 1.

    Circuit imprimé pour Atmega8 ressemble à ceci :

    Comme vous pouvez le voir, le circuit est très simple, il n'y a qu'un seul microcontrôleur, 3 résistances, 2 LED et un haut-parleur supplémentaire. Au lieu d'un bouton, vous pouvez utiliser un interrupteur à lames ou un autre contact.

    Le principe de fonctionnement est le suivant. Dès que nous mettons sous tension, la LED (dans le circuit D3) s'allume immédiatement ou commence à clignoter (selon le firmware), et si nous ne touchons pas le capteur, l'alarme sera silencieuse. Désormais, si le capteur se déclenche, la sirène fonctionnera également, la LED clignotera également, mais D2.

    Si vous souhaitez que les phares de la voiture clignotent lorsque l'alarme fonctionne, vous devez pour ce faire connecter la broche du microcontrôleur 24 PC1 au relais via un transistor et le relais lui-même aux phares. Pour éteindre la sirène, vous devez éteindre et rallumer l'appareil, ou simplement appuyer sur le bouton. Pour faire fonctionner le microcontrôleur, vous avez besoin d'un oscillateur interne de 8 MHz,

    Si vous souhaitez améliorer d'une manière ou d'une autre le son de l'alarme, vous pouvez assembler un amplificateur avec des transistors et le connecter au circuit. C’est exactement ce que j’ai fait, mais je ne l’ai pas représenté dans ce schéma.

    Passons au circuit de l'Attiny 2313, comme je le disais plus haut, il a tous les mêmes détails et le même principe de fonctionnement, seul le MK a été changé, et par conséquent les broches connectées. Ce microcontrôleur fonctionne à partir d'un oscillateur interne de 4 MHz, bien qu'il puisse être flashé à 1 MHz.

    Ci-dessous le schéma de connexion déjà sur Attiny2313

    Pour ce MK, j'ai écrit une seule version du firmware, j'ai tout assemblé sur le circuit imprimé, je l'ai vérifié, tout fonctionne bien.
    Et les fusibles doivent être réglés comme indiqué ci-dessous :





Haut