Programmer un ATtiny13 en tant qu'oscillateur audio à fréquence et largeur d'impulsion variables

8

Je veux créer un simple oscillateur à onde carrée similaire à ce que l'on ferait avec un 555, mais je veux utiliser le support PWM basé sur les interruptions pour contrôler la largeur et la fréquence des impulsions.

J'ai étudié la fiche technique, les API AVR et tous les exemples PWM que je peux trouver, mais je n'ai pas tout à fait pu tout rassembler.

Est-il possible de créer un tel oscillateur avec la fonctionnalité AVR PWM intégrée et, si oui, comment? Mon ami a fait quelque chose de similaire avec un PIC à 8 broches.

Mon raisonnement est que j'obtiendrai des sons intéressants en changeant la largeur d'impulsion et donc la forme d'onde à une fréquence donnée. Semblable à la façon dont la console Atari Punk fonctionne mais, espérons-le, de manière plus stable, c'est-à-dire en modifiant la largeur d'impulsion, mais en laissant la fréquence constante ou vice versa.

bruit
la source
2
pourriez-vous préciser quelle est votre question?
Jason S
Je ne sais pas à quel point ils seront intéressants, mais il est facile d'essayer et vous pouvez juger. Lorsque l'impulsion se rétrécit, les amplitudes des harmoniques augmentent. Continuez à réduire le pouls et vous obtenez un bruit blanc. Je pense que vous auriez des options plus intéressantes en faisant un oscillateur à commande numérique. Vous pouvez modifier les formes d'onde chargées dans la table d'ondes.
jluciani

Réponses:

5

Ceux-ci devraient vous mener assez loin et le reste que vous pouvez faire avec la fiche technique. Commencez à construire morceau par morceau, de clignotant à forme d'onde en forme d'onde qui change au fil du temps en tons. Certaines sources peuvent aider à filtrer et à piloter les sorties audio (le LPF actif peut parfaitement faire les deux).

Je suggère de revenir avec des questions plus spécifiques.

tissit
la source
4

La période du PWM est déterminée par le taux de débordement de votre minuterie. Il y a beaucoup de paramètres dans la section Modes de fonctionnement auxquels penser. Si tout ce que vous voulez faire est de générer une onde carrée à période constante, avec un rapport cyclique variable, je pense que vous allez vouloir utiliser le mode CTC (Clear Timer on Compare Match). L'idée de base est de définir OCR0A sur le nombre de tics de minuterie jusqu'à ce que vous souhaitiez que la broche bascule ensuite, et utilisez l'interruption Compare Match pour modifier cette valeur pour la prochaine fois. Donc, en avr-gcc, cela ressemblerait à quelque chose comme:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

// global variables defining number of ticks on and off
uint8_t on_time_ticks, off_time_ticks, csxx_bits=0; 


void setup_timer(double p_ms, double duty){
  TCCR0A = _BV(COM0A0) // toggle OC0A on Compare Match
  TCCR0B = _BV(WGM02); // set CTC mode WGM0[2,1,0] = 0b100

  // ... do some stuff based on your CPU frequency
  // to define the csxx_bits of TCCR0B when the timer is running
  // and consequently, to set on_time_ticks and off_time_ticks
  OCR0A = on_time_ticks;
  TCCR0B |= your_settings_here;
}


void start_timer(){
  //start the timer running at the desired rate
  TCCR0B |= csxx_bits; 
}


int main(int argc, char **argv){
  double period_ms, duty_cycle;
  setup_timer(period_ms, duty cycle);
  start_timer();  
  for(;;){
    //spin or sleep or whatever
  }
}


ISR(TIM0_COMPA_vect){
  if(OCR0A == on_time_ticks){
    OCR0A = off_time_ticks;
  }
  else{
    OCR0A = on_time_ticks;
  }
}

Attention, c'est du code non testé mais je pense que l'idée est juste. Ce n'est en aucun cas la seule façon de le faire.

Soit dit en passant, il y a une chose que vous devez savoir sur l'ATTiny13. L'oscillateur RC interne n'est garanti que pour être précis à 10% près du sol de l'usine. Il existe un processus de calibrage utilisateur que vous pouvez suivre (décrit par une note atmel ) qui vous permettra d'obtenir une précision de 2% pour l'ATTiny13. Si vous voulez faire mieux, vous devrez probablement utiliser une puce qui accueille un cristal externe ...

vicatcu
la source
1
Votre réponse a aidé à clarifier quelque chose de similaire avec lequel j'avais des problèmes - merci. Juste un point (pour toute personne lisant ceci longtemps après le fil d'origine): votre choix de 0b100 pour WGM0 [2,1,0] ne définira pas le mode CTC. (En fait, cela définira un mode réservé par Atmel.) La fiche technique ATtiny13 indique que le mode CTC a besoin de la valeur 2; vous l'avez accidentellement donné bit_number 2 à la place (c'est-à-dire la valeur 4). Pour cette raison, il est également nécessaire non seulement de changer (c.-à-d. D'effacer) WGM02 dans TCCR0B, mais également de mettre les bits WGM01 et WGM00 à 1 et 0 respectivement. Ces bits sont dans TCCR0A, il n'est donc pas suffisant de régler TCCR
3

Pas une réponse directe à votre question, mais cela peut être à propos et fournir quelques conseils -

Je viens de créer un oscillateur à commande numérique (NCO) utilisant un ATmega uC et un DAC. Un tableau d'entiers est utilisé pour stocker un cycle d'une forme d'onde (table d'onde). Un accumulateur de phase (long int) est utilisé pour déterminer l'adresse des données de sortie dans la table d'ondes. Chaque interruption de temporisation incrémente l'accumulateur de phase d'une valeur fixe. L'incrément de phase détermine la fréquence.

Dans mon application, j'ai utilisé une table d'onde de 64 octets qui contenait un cycle d'une onde sinusoïdale. Il est facile d'étendre la table d'ondes et d'ajouter plus de résolution aux échantillons. Ma note d'application est à http://wiblocks.com/docs/app-notes/nb1a-nco.html

jluciani
la source
1

Fondamentalement, un PWM ne change pas la fréquence. Les PWM sont principalement utilisés pour contrôler l '"intensité" d'un signal.

Pour générer une interruption pour différentes fréquences, je vous suggère d'utiliser la minuterie en mode CTC.

Il fonctionnera à votre valeur de comparaison, basculera une interruption, effacera et redémarrera lui-même - jusqu'à ce qu'il s'exécute à nouveau à votre valeur de comparaison ...

À chaque interruption, vous pouvez commuter un ou plusieurs ports et le reste du temps (la minuterie fonctionne toujours automatiquement), vous pouvez regarder vos entrées de toute sorte ...

Vous pouvez toujours "moduler" votre onde carrée avec un PWM pour contrôler le "gain". Mais l'un d'eux doit être fait "à la main" car l'ATtiny13 ne dispose que d'un seul timer matériel ...

Greenonline
la source
1
la plupart des périphériques matériels PWM vous permettent de sélectionner la fréquence; si vous gardez le rapport cyclique constant, alors PWM peut toujours vous donner un contrôle à fréquence variable
Jason S
1
Changer la largeur d'impulsion ne change pas la fréquence fondamentale mais cela change les harmoniques.
jluciani