mercredi 31 octobre 2012

expérimentation avec PIC10F322, partie 3

Dans cette 3ième partie de mes expérimentations avec le PIC10F322, je l'utilise pour produire des sons. Il y a 2 programmes, soundfx.asm et pwm_synth.asm.
Les 2 programmes utilisent le fichier de macros pic10f322_m.inc

Pour réaliser ces expériences j'ai ajouté un petit potentiomètre de 5K sur la platine d'expérimentation présentée en partie 1 de cette série. Ce potientiomètre sert dans le mode VCO du programme soundfx.asm et dans pwm_synth.asm.

effets sonores

Pour réaliser cette expérience vous avez besoin du matériel suivant:

  • 1 PIC10F322 ou LF322
  • 1 petit haut-parleur
  • 1 résistance de 100 ohm
  • 1 potientiomètre de 5K (la valeur n'est pas critique)
  • 1 bouton à contact momentanée
  • 1 platine d'expérimentation sans soudure
  • 1 programmeur pickit 3 ou équivalent.

Le montage est le suivant:


Pour cette expérience tous les périphériques du PIC10F322 sont utilisés.

  • Le NCO sert de générateur de fréquence audio principal.
  • le PWM1 génère une fréquence audio fixe.
  • la CLC est utilisée pour additionner (mixer) les sorties du NCO et de PWM1
  • la sortie du CLC est connectée à RA2
  • Le convertisseur A/N fait la lecture du potentiomètre sur RA0
  • le timer 2 alimente le PWM
  • le timer 0 est utilisé pour mesurer le temps pour les intervalles.

Le programme a 5 modes de fonctionnement:
  1. Silence
  2. balayage de fréquence
  3. générateur de fréquence contrôlé par un voltage (VCO)
  4. gamme musicale
  5. mélodie

Le bouton branché sur RA3 permet de passer d'un mode à au suivant en boucle.
Le mode balayage de fréquence balaie de 100hz à 5Khz en montant et en descendant.
Ce signal est mélanger avec une fréquence fixe générée par PWM1 avec une fonction "ou exclusif" dans la cellule logique configurable. L'effet produit est très particulier.

Le mode VCO tant qu'à lui produit une fréquence qui est proportionnel au voltage lu sur le potentiomètre. En tournant le potentiomètre on fait varier la fréquence.

Le mode gamme utilise le NCO pour jouer la gamme musicale tempérée dont les valeurs de
fréquences sont inscrites dans la table scale_table.

Finalement le mode mélodie joue la mélodie We gonna fly now, musique thème du film Rocky 1.


synthès analogique par PWM

Le programme pwm_synth.asm est une illustration de l'utilisation de la modulation par largeur d'impulsion pour produire un signal analogique. Pour cette expérience le haut-parleur doit-être branché sur RA1 en série avec une résistance de 100R. Il faut aussi brancher un potentiomètre de 5K ou 10K aux bornes de l'alimentation avec le contact mobile (celui du centre) sur RA2. En tournant ce potentiomètre on sélectionne la note que le programme fait entendre.

Dans cette expérience le MCU est configuré pour fonctionner à sa vitesse maximale de 16Mhz et le canal PWM2 est utilisé pour générer une onde sinusoïdale. La fréquence du PWM est de 31Khz donc inaudible. J'ai utilisé OpenOffice calc pour calculer les valeurs de la table sine_table1. ainsi que les délais de transfert des échantillons au PWM. Ces valeurs détermine la largeur d'impulsion que doit générer le PWM au différents angles du cycle de l'onde et le délais de transmission des échantillons pour chaque fréquence. Il y a 90 échantillons, donc un échantillon à tous les 4 degrés considérant qu'un cycle complet représente 360 degrés. La fréquence de l'onde est déterminée par la vitesse avec laquelle on envoie les échantillons au PWM.

délais = (1/fr)/Ns

délais est le délais entre l'envoie de chaque échantillon au pwm.
fr est la fréquence qui doit-être générée.
Ns est le nombre d'échantillons.

exemple pour générer un fréquence 440hz avec les 90 échantillons de la table sine_table

délais = (1/440)/90 = 0,0023/90 = 25 uSec

les valeurs pour le timer0 sont calculées de la façon suivante.

T0val=256 - délais/Tcy + 9
T0val est la valeur d'initialisation du compteur timer0.
délais est la valeur calculée dans la formule précédente.
Tcy est la période de l'horloge système soit 1/(Fosc/4), ce qui à 16Mhz
donne 250nsec.
9 est le nombre de Tcy qui s'écoule avant que le timer0 ne soit réinitialisé par la routine d'interruption.

pour 440Hz on a donc:

T0val = 256 - 25e-6/250e-9 + 9 = 165

J'ai fait un fine tuning des valeurs en mesurant les fréquence réelle à l'oscilloscope, pour être le plus près possible des valeurs de la gamme tempérée.

On entend clairement la fréquence audio dans le haut-parleur mais si on branche un oscilloscope sur la broche RA1 le signale ressemble à ceci:


Ceci est le signal en p3 sur le schéma ci-bas. Difficile de voir une forme sinusoïdale ici.


Si on remplace le haut-parleur avec ce filtre passe-bas pour éliminer le signal PWM, voici ce qu'on voit à l'oscillope.

Au point 2 le signal PWM n'est pas complètement éliminé il chevauche la fréquence audio.

Au point 1 le signal PWM est à peine visible, il ne reste que la fréquence audio synthétisée.

Dans les années 80 tous les ordinateurs personnels n'avaient pas de carte son, un petit haut-parleur était branché à une sortie numérique et tout ce que l'ordinateur pouvait produire c'était des BEEP en ondes rectangulaires. Jusqu'à ce que quelqu'un est l'idée de créer un pilote de périphérique qui pouvait lire un fichier .WAV et le faire entendre dans le haut-parleur. La technique utilisée était celle décrite dans ce démo synthèse analogique par modulation de largeur d'impulsion.

Il faut faut donc pas s'étonner que les périphériques PWM soit si répandus sur les micro-controlleurs, après les minuteries ce sont les périphériques les plus utilisés sur MCU. Au cours de mes chroniques j'en ai illustrer plusieurs usages:

  • Contrôle de l'intensité lumineuse d'une DEL.
  • Contrôle de la position d'un servo-moteur.
  • Contrôle de la vitesse d'un moteur c.c.
  • Synthèse de signaux analogiques.

Il y a d'autres usages comme par exemple les régulateurs de tension. En fait le PWM est la méthode la plus efficace pour contrôler et produire des signaux analogiques avec du numérique.




NOTES:
1) Notez que pour la table sine_table j'ai utilisé une table da plutôt qu'une table dt. Ce type de table permet d'enregistrer des valeurs plus grandes que 255 dans une location mémoire flash. La mémoire flash étant de 14 bits on peut enregistrer des valeurs de 0 à 16383. j'économise ainsi 90 locations mémoire par rapport à l'utilisation d'une table dt, une réduction de 50%. De plus l'accès dans la routine d'interruption est plus rapide.





Aucun commentaire:

Publier un commentaire