Memprogram ATtiny13 sebagai osilator audio dengan frekuensi variabel dan lebar pulsa

8

Saya ingin membuat osilator gelombang persegi sederhana yang mirip dengan apa yang akan dilakukan dengan 555, tetapi saya ingin menggunakan dukungan PWM berbasis interupsi untuk mengontrol lebar dan frekuensi pulsa.

Saya telah mempelajari datasheet, API AVR, dan contoh PWM apa pun yang dapat saya temukan, tetapi saya belum dapat menggabungkan semuanya.

Apakah mungkin untuk membuat osilator dengan fungsi AVR PWM bawaan dan, jika ya, bagaimana? Saya teman saya melakukan sesuatu yang mirip dengan PIC 8 pin.

Alasan saya adalah bahwa saya akan mendapatkan suara yang menarik dengan mengubah lebar pulsa dan karena itu bentuk gelombang pada frekuensi yang diberikan. Mirip dengan cara Konsol Punk Atari bekerja tetapi mudah-mudahan dengan cara yang lebih stabil, yaitu mengubah lebar pulsa, tetapi membiarkan frekuensi konstan atau sebaliknya.

kebisingan
sumber
2
bisakah Anda menjelaskan apa pertanyaan Anda?
Jason S
Saya tidak yakin seberapa menariknya mereka, tetapi mudah untuk dicoba dan Anda bisa menilai. Ketika pulsa menyempit, amplitudo harmonik meningkat. Tetap persempit nadi dan Anda mendapatkan white noise. Saya pikir Anda akan memiliki pilihan yang lebih menarik melakukan osilator yang dikontrol secara numerik. Anda dapat mengubah bentuk gelombang yang dimuat ke wavetable.
jluciani

Jawaban:

5

Ini akan membuat Anda cukup jauh dan sisanya dapat Anda lakukan dengan lembar data. Mulailah membangun sepotong demi sepotong, dari blinky ke waveform ke waveform yang berubah seiring waktu menjadi nada. Beberapa sumber mungkin membantu dengan memfilter dan menggerakkan output audio (LPF aktif mungkin melakukan keduanya dengan rapi).

Saya sarankan kembali dengan pertanyaan yang lebih spesifik.

tissit
sumber
4

Periode PWM ditentukan oleh tingkat luapan timer Anda. Ada banyak pengaturan pada bagian Mode Operasi untuk dipikirkan. Jika semua yang ingin Anda lakukan adalah menghasilkan gelombang persegi periode konstan, dengan siklus tugas variabel, saya pikir Anda akan ingin menggunakan mode CTC (Clear Timer on Compare Match). Ide dasarnya adalah untuk menetapkan OCR0A ke jumlah kutu waktu sampai Anda ingin pin untuk beralih berikutnya, dan gunakan interupsi Bandingkan Pertandingan untuk mengubah nilai itu untuk waktu berikutnya. Jadi dalam avr-gcc akan terlihat seperti:

#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;
  }
}

Peringatan, ini kode yang belum diuji tetapi saya pikir idenya benar. Tidak berarti apakah ini satu - satunya cara untuk melakukannya juga.

Ada satu hal yang harus Anda ketahui tentang ATTiny13. RC Oscillator internal hanya dijamin akurat hingga 10% dari lantai pabrik. Ada proses kalibrasi pengguna yang dapat Anda lalui (dijelaskan oleh atmel appnote ) yang akan membawa Anda ke akurasi 2% untuk ATTiny13. Jika Anda ingin melakukan yang lebih baik dari itu, Anda mungkin perlu menggunakan chip yang mengakomodasi kristal eksternal ...

vicatcu
sumber
1
Jawaban Anda membantu untuk mengklarifikasi hal serupa yang saya punya masalah dengan - terima kasih. Hanya satu poin (bagi siapa pun yang membaca ini lama setelah utas asli): Pilihan Anda 0b100 untuk WGM0 [2,1,0] tidak akan mengatur mode CTC. (Bahkan itu akan mengatur mode yang disediakan oleh Atmel.) Lembar data ATtiny13 mengatakan mode CTC membutuhkan nilai 2; Anda secara tidak sengaja memberikannya bit_number 2 sebagai gantinya (yaitu nilai 4). Karena itu perlu juga tidak hanya mengubah (yaitu menghapus) WGM02 di TCCR0B tetapi juga untuk mengatur bit WGM01 dan WGM00 masing-masing menjadi 1 dan 0. Bit-bit itu ada di TCCR0A, jadi tidak cukup untuk mengatur TCCR
3

Bukan jawaban langsung untuk pertanyaan Anda, tetapi ini mungkin tepat dan berikan beberapa petunjuk -

Saya baru saja membuat osilator yang dikontrol secara numerik (NCO) menggunakan ATmega UC dan DAC. Array bilangan bulat digunakan untuk menyimpan satu siklus bentuk gelombang (wavetable). Akumulator fase (long int) digunakan untuk menentukan alamat data output di wavetable. Setiap pengatur waktu menambah akumulator fase dengan nilai tetap. Peningkatan fase menentukan frekuensi.

Dalam aplikasi saya, saya menggunakan wavetable 64 byte yang berisi satu siklus gelombang sinus. Sangat mudah untuk memperpanjang goyangan dan menambahkan lebih banyak resolusi ke sampel. Catatan aplikasi saya ada di http://wiblocks.com/docs/app-notes/nb1a-nco.html

jluciani
sumber
1

Pada dasarnya PWM tidak mengubah frekuensi. PWM sebagian besar digunakan untuk mengontrol "intensitas" suatu sinyal.

Untuk menghasilkan interupsi untuk frekuensi yang berbeda, saya sarankan Anda menggunakan timer dalam mode CTC.

Ini akan berjalan ke nilai perbandingan Anda, beralih interupsi, hapus dan mulai ulang sendiri - sampai berjalan kembali ke nilai perbandingan Anda ...

Setelah setiap interupsi, Anda dapat beralih satu atau beberapa port dan sisa waktu (timer masih berjalan secara otomatis), Anda dapat melihat input apa pun ...

Anda mungkin masih "memodulasi" gelombang persegi Anda dengan PWM untuk mengontrol "gain". Tetapi salah satu dari mereka harus dilakukan "dengan tangan" karena ATtiny13 hanya memiliki satu pengatur waktu perangkat keras ...

Greenonline
sumber
1
sebagian besar perangkat keras PWM memungkinkan Anda memilih frekuensi; jika Anda menjaga siklus tugas konstan maka PWM masih dapat memberikan Anda kontrol frekuensi variabel
Jason S
1
Mengubah lebar pulsa tidak mengubah frekuensi dasar tetapi itu mengubah harmonik.
jluciani