Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> VHDL

Cara membuat pengontrol PWM di VHDL

Modulasi lebar pulsa (PWM) adalah cara yang efisien untuk mengontrol elektronik analog dari pin FPGA digital murni. Alih-alih mencoba mengatur tegangan analog, PWM dengan cepat menghidupkan dan mematikan arus suplai dengan daya penuh ke perangkat analog. Metode ini memberi kita kontrol yang tepat atas rata-rata bergerak energi yang diberikan ke perangkat konsumen.

Contoh kasus penggunaan yang merupakan kandidat yang baik untuk PWM adalah modulasi audio (speaker), kontrol intensitas cahaya (lampu atau LED), dan motor induksi. Yang terakhir termasuk motor servo, kipas komputer, pompa, motor DC brushless untuk mobil listrik, dan masih banyak lagi.

Lihat juga:
Pengontrol servo RC menggunakan PWM dari pin FPGA

Cara kerja PWM

Dengan menghidupkan dan mematikan catu daya ke perangkat dengan frekuensi tinggi, kita dapat secara akurat mengontrol arus rata-rata yang mengalir melaluinya. Ilustrasi di bawah ini menunjukkan dasar-dasar cara kerja PWM. Output PWM mengontrol sakelar biner yang dapat mengatur daya ke 100% atau 0%. Dengan cepat bergantian antara dua ekstrem, rata-rata jendela geser akan menjadi fungsi dari waktu yang dihabiskan di masing-masing negara bagian.

Siklus tugas

Siklus tugas adalah kunci untuk mengontrol daya yang diberikan ke perangkat analog di PWM. Istilah siklus tugas berarti berapa banyak waktu yang dihabiskan output PWM pada posisi ON. Ini umum untuk menggambarkan siklus tugas sebagai persentase, seperti yang ditunjukkan pada gambar di bawah ini. Namun, dalam contoh VHDL saya, saya akan menggunakan bilangan biner yang tidak ditandatangani nanti di artikel ini. Lebih masuk akal bagi kami untuk menggunakan angka biner, yang dapat mewakili resolusi penuh dari siklus tugas dalam implementasi VHDL kami.

Dengan duty cycle 0, output PWM akan tetap pada posisi OFF terus menerus, sedangkan pada 100% akan non-stop pada posisi ON. Tingkat akurasi yang dapat diberikan oleh pengontrol PWM pada efek muatan berhubungan langsung dengan panjang penghitung PWM. Kita akan melihat cara kerjanya dalam kode VHDL saat kita mengimplementasikan pengontrol PWM nanti di artikel ini.

Rumus untuk mengubah representasi biner dari duty cycle ke persentase ditunjukkan di bawah ini.

\mathit{duty\_cycle\_percentage} =\frac{\mathit{commanded\_duty\_cycle} * 100}{2^\mathit{pwm\_bits} - 1}

Frekuensi PWM

Ketika berbicara tentang frekuensi switching PWM, yang kami maksud adalah seberapa sering output PWM bergantian antara status ON dan OFF, berapa lama waktu yang dibutuhkan penghitung PWM untuk membungkus. Seperti biasa, frekuensi adalah kebalikan dari periode PWM penuh:

\mathit{pwm\_freq} =\frac{1}{\mathit{pwm\_period}}

Frekuensi PWM yang ideal tergantung pada jenis perangkat yang Anda kendalikan. Setiap angka yang lebih besar dari beberapa ratus Hertz akan terlihat seperti sumber cahaya yang stabil dengan mata telanjang jika konsumennya adalah LED. Untuk motor DC brushless, sweet spot terletak pada kisaran puluhan kilohertz. Atur frekuensi terlalu rendah, dan Anda mungkin mengalami getaran fisik. Dengan osilasi yang terlalu cepat, Anda membuang-buang daya.

Masalah yang perlu diingat adalah bahwa elektronika daya analog tidak secepat pin FPGA digital. Pengaturan PWM biasa menggunakan MOSFET daya sebagai sakelar untuk mengontrol arus yang mengalir melalui perangkat analog.

Perhatikan skema yang ditunjukkan pada gambar. Ini adalah bagian dari rangkaian driver LED yang digunakan dalam kursus VHDL Dot Matrix lanjutan saya. Pin FPGA mengontrol gerbang MOSFET, bertindak sebagai pemutus sirkuit ke LED seri. Dengan frekuensi switching yang lebih tinggi, transistor akan menghabiskan lebih banyak waktu untuk tidak sepenuhnya terbuka atau tertutup sepenuhnya. Itu berarti daya yang terbuang dan produksi panas berlebih di MOSFET.

Modul generator PWM

Mari kita buat implementasi standar dan generik dari pengontrol PWM di VHDL. Apa yang saya maksud dengan standar adalah bahwa ini mendekati apa yang akan dibuat oleh desainer VHDL paling berpengalaman jika Anda meminta mereka untuk menulis pengontrol PWM di VHDL. Ini umum dalam arti bahwa frekuensi PWM dapat disesuaikan agar sesuai dengan sebagian besar aplikasi.

Untuk menguji generator PWM kami pada FPGA nyata, kami akan membutuhkan beberapa modul lagi selain pengontrol PWM. Saya akan menyajikannya nanti ketika menggunakan modul PWM untuk mengontrol penerangan LED pada papan pengembangan FPGA iCEstick Lattice. Tapi pertama-tama, mari kita bicara tentang modul generator PWM.

Entitas modul PWM

Untuk membuat modul dapat disesuaikan, saya telah menambahkan port generik yang memungkinkan Anda menentukan dua konstanta pada waktu instantiasi.

Yang pertama, bernama pwm_bits , menentukan panjang penghitung PWM internal. Konstanta ini menetapkan panjang bit, bukan nilai penghitung maksimum. Anda tidak akan dapat menentukan frekuensi PWM sebagai jumlah periode jam tertentu. Tapi biasanya, kita tidak perlu mengatur frekuensi PWM dengan akurasi 100%. Frekuensi PWM yang ideal adalah rentang yang bekerja dengan baik daripada satu angka pasti.

Konstanta generik lainnya bernama clk_cnt_len . Ini menentukan panjang penghitung kedua yang secara efektif menurunkan frekuensi PWM. Ini bertindak sebagai pembagi jam, tetapi tanpa benar-benar membuat sinyal jam yang diturunkan. Perhatikan bahwa ada nilai default 1 yang ditetapkan untuknya. Menyetel konstanta ini ke 1 akan menonaktifkan pembagi jam, dan juga menghilangkan logika tambahan yang menanganinya.

Saya akan menjelaskan ini dan menyajikan rumus untuk menghitung frekuensi PWM yang tepat nanti di artikel.

entity pwm is
  generic (
    pwm_bits : integer;
    clk_cnt_len : positive := 1
  );
  port (
    clk : in std_logic;
    rst : in std_logic;
    duty_cycle : in unsigned(pwm_bits - 1 downto 0);
    pwm_out : out std_logic
  );
end pwm;

Karena ini adalah modul yang sepenuhnya sinkron, dua sinyal pertama adalah jam dan reset.

Input ketiga pada daftar deklarasi port adalah siklus tugas. Seperti yang Anda lihat dari kode VHDL di atas, panjang duty_cycle sinyal mengikuti pwm_bits konstanta generik. Ini berarti bahwa pwm_bits konstanta mengatur seberapa tepat Anda dapat mengatur daya ke perangkat analog.

Sinyal terakhir pada entitas adalah pwm_out . Itu adalah sinyal kontrol termodulasi PWM, yang Anda rutekan ke pin FPGA dan sambungkan ke gerbang MOSFET Anda.

Sinyal internal modul PWM

Modul PWM hanya berisi dua sinyal internal. Yang pertama adalah penghitung PWM, yang identik dengan duty_cycle memasukkan. Sama seperti yang terakhir, pwm_bits konstanta juga menentukan panjang sinyal ini.

signal pwm_cnt : unsigned(pwm_bits - 1 downto 0);
signal clk_cnt : integer range 0 to clk_cnt_len - 1;

Sinyal internal kedua bernama clk_cnt , dan seperti namanya, ini untuk menghitung siklus clock. Ini bertipe integer, dan jika Anda menyetel clk_cnt_len ke 1, rentang penghitungan akan dievaluasi menjadi (0 hingga 0) —hanya angka 0.

Proses penghitung siklus jam PWM

Proses yang mengimplementasikan penghitung jam sangatlah mudah. Jika modul tidak direset, logika akan menghitung siklus clock secara terus-menerus, kembali ke nol pada nilai maksimal yang clk_cnt bilangan bulat dapat menampung.

CLK_CNT_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      clk_cnt <= 0;
      
    else
      if clk_cnt < clk_cnt_len - 1 then
        clk_cnt <= clk_cnt + 1;
      else
        clk_cnt <= 0;
      end if;
      
    end if;
  end if;
end process;

Perhatikan bahwa jika Anda menggunakan nilai default 1 untuk clk_cnt_len generik, proses ini harus menguap selama sintesis. Pernyataan if internal akan selalu salah karena 0 < 1 - 1 adalah palsu. Nilai clk_cnt maka selalu 0. Sebagian besar alat sintesis akan mengenali ini dan mengoptimalkan seluruh proses.

Proses keluaran PWM

Proses yang mengatur sinyal output PWM juga mengontrol penghitung PWM. Ini menambah penghitung PWM ketika penghitung siklus jam adalah 0. Begitulah cara kerja mekanisme pembatasan frekuensi PWM.

Awalnya, saya hanya ingin menulis if clk_cnt = 0 then pada baris 9, tetapi saya menemukan bahwa alat sintesis tidak menghapus semua logika yang terkait dengan penghitung jam ketika saya menggunakan clk_cnt_len default nilai 1. Namun, termasuk clk_cnt_len dalam pernyataan if berhasil. Seharusnya tidak memiliki efek buruk pada sintesis karena clk_cnt_len adalah sebuah konstanta. Alat sintesis dapat mengetahui nilainya pada waktu kompilasi, dan kemudian memutuskan apakah konten proses tersebut berlebihan atau tidak.

PWM_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      pwm_cnt <= (others => '0');
      pwm_out <= '0';

    else
      if clk_cnt_len = 1 or clk_cnt = 0 then

        pwm_cnt <= pwm_cnt + 1;
        pwm_out <= '0';

        if pwm_cnt = unsigned(to_signed(-2, pwm_cnt'length)) then
          pwm_cnt <= (others => '0');
        end if;

        if pwm_cnt < duty_cycle then
          pwm_out <= '1';
        end if;

      end if;
    end if;
  end if;
end process;

Kapan clk_cnt_len lebih besar dari 1, pwm_cnt sinyal berperilaku seperti penghitung yang berjalan bebas, bertambah ketika clk_cnt adalah 0. Ini adalah tipe yang tidak ditandatangani, yang akan membungkus kembali ke 0 secara otomatis saat meluap. Tapi kita harus memastikan bahwa itu melewati nilai tertinggi sebelum membungkus ke nol.

Pada baris 14 pada kode di atas, saya memeriksa apakah penghitung berada pada nilai tertinggi kedua. Jika ya, kami menetapkannya ke 0 pada saat ini. Saya menggunakan trik yang akan berhasil, tidak peduli berapa lama pwm_cnt sinyal adalah. Dengan menggunakan untuk_ditandatangani fungsi, saya membuat konstanta bertanda tangan baru dengan panjang yang sama dengan pwm_cnt , tetapi dengan nilai -2.

Angka -2 yang ditandatangani dalam VHDL, dan komputer pada umumnya, akan selalu berupa rangkaian 1, dan 0 di posisi paling kanan. Itu karena cara kerja ekstensi tanda. Baca lebih lanjut tentang itu di tutorial saya sebelumnya:

Cara menggunakan ditandatangani dan tidak ditandatangani di VHDL

Terakhir, dengan mentransmisikan jenis yang ditandatangani ke yang tidak ditandatangani, kami mendapatkan nilai tertinggi kedua yang pwm_cnt bisa tahan.

Pada baris 18, kami memeriksa apakah penghitung PWM yang berjalan bebas lebih besar dari input siklus kerja. Jika itu benar, kita set output PWM ke '1' karena kita berada dalam periode ON dari duty cycle.

Itu sebabnya kami harus membungkus penghitung PWM kembali ke 0 pada nilai tertinggi kedua. Jika penghitung PWM dapat mencapai nilai setinggi mungkin yang dapat dimiliki oleh siklus kerja, tidak mungkin untuk mengatur siklus tugas ke 100%. pwm_cnt < duty_cycle baris akan selalu salah jika pwm_cnt berada pada nilai maksimalnya.

Masuk akal karena kita harus merepresentasikan status OFF dan ON sepenuhnya selain langkah-langkah siklus kerja perantara. Bayangkan pwm_bits adalah set ke 2, dan jalankan seluruh urutan penghitungan sebagai latihan mental untuk melihat apa yang saya maksud!

\mathit{pwm\_hz} =\frac{\mathit{clk\_hz}}{(2^\mathit{pwm\_bits} - 1) * \mathit{clk\_cnt\_len}}

Dengan memperhatikan fakta-fakta ini, kita dapat memperoleh rumus yang ditunjukkan di atas untuk menghitung frekuensi PWM yang tepat. Sementara clk_hz adalah frekuensi jam sistem FPGA, dua variabel lainnya adalah konstanta input generik.

Modul teratas

Untuk menguji modul PWM pada perangkat keras nyata, saya membuat implementasi yang akan mengatur pencahayaan LED penyalaan pada iCEstick Lattice. Saya menggunakan papan pengembangan FPGA yang terjangkau ini di kursus pemula VHDL Fast-Track saya dan untuk kursus FPGA Dot Matrix lanjutan saya.

Gambar di atas menunjukkan bagian depan iCEstick yang dapat dicolokkan USB dengan LED penyalaan yang ditunjukkan oleh panah. Ada lima LED pada iCEstick yang diatur dalam pola bintang. LED power-on berwarna hijau, sementara yang lain memancarkan cahaya warna merah. Di iCEstick, ada pin FPGA khusus untuk setiap LED. Lihat panduan pengguna iCEstick untuk melihat nomor pin yang tepat untuk mengontrolnya.

Diagram di bawah ini menunjukkan bagaimana submodul di modul atas terhubung. Kita sudah membicarakan modul PWM, dan saya akan menjelaskan secara singkat modul penghitung dan reset nanti di artikel ini.

Entitas modul teratas

Alih-alih membuat hardcoding konstanta di dalam modul teratas, saya mendeklarasikannya sebagai generik di entitas tingkat atas. Kemudian, saya menetapkan nilai default yang sesuai untuk iCEstick. Salah satu keuntungan dari pendekatan ini adalah Anda dapat mengganti nilai-nilai ini di testbench untuk mempercepat simulasi. Saya tidak menetapkan apa pun ke obat generik ketika saya mensintesis desain. Dengan demikian, nilai default yang benar akan berakhir di desain yang dirutekan.

Kami akan meneruskan pwm_bits dan clk_cnt_len ke obat generik pada entitas modul PWM dengan nama yang sama. Frekuensi clock osilator iCEstick adalah 12 Mhz. Dengan menggunakan rumus yang disajikan sebelumnya, kita dapat memasukkan nilai-nilai ini untuk menghitung frekuensi PWM:\frac{12e6}{(2^8 - 1) * 47} \approx 1 \mathit{kHz}

entity pwm_led is
  generic (
    pwm_bits : integer := 8;
    cnt_bits : integer := 25;
    clk_cnt_len : positive := 47
  );
  port (
    clk : in std_logic;
    rst_n : in std_logic; -- Pullup

    led_1 : out std_logic;
    led_2 : out std_logic;
    led_3 : out std_logic;
    led_4 : out std_logic;
    led_5 : out std_logic
  );
end pwm_led;

Anda mungkin telah memperhatikan bahwa ada konstanta ketiga, cnt_bits , dalam deklarasi generik dalam kode di atas. Ini mengontrol panjang penghitung gigi gergaji yang dapat dibungkus sendiri. Kami akan menggunakan penghitung tambahan ini untuk membuat penerangan bertahap dari LED pengaktifan sehingga kami dapat mengamati modul PWM bekerja secara real-time.

Kami akan menghubungkan bit tinggi penghitung baru ini ke input siklus tugas modul PWM. Karena penghitung ini akan menghitung siklus jam, cnt_bits generik menentukan frekuensi denyut dari LED power-on. Rumusnya, yang merupakan fungsi dari frekuensi clock dan panjang counter, ditunjukkan di bawah ini.

\frac{2^{\mathit{cnt\_bits}}}{\mathit{clk\_hz}} =\frac{2^{25}}{12e6} \kira-kira 2,8 \mathit{Hz}

Dalam deklarasi port, saya telah memperbaiki input reset dengan _n , menunjukkan bahwa reset eksternal memiliki polaritas negatif. Kami akan mengonfigurasi Lattice FPGA untuk menggunakan resistor pull-up internal pada pin ini.

Terakhir, Anda dapat melihat bahwa saya telah mencantumkan semua LED yang ada di iCEstick dalam deklarasi port. Kami hanya akan menggunakan LED nomor 5, tetapi kami harus menggerakkan LED lainnya secara aktif. Jika dibiarkan tidak terhubung, mereka akan menyala dengan warna merah samar.

Jika Anda ingin melihat lebih dekat pada kode VHDL dan file batasan, masukkan email Anda pada formulir di bawah ini. Anda akan menerima file Zip dengan kode lengkap dengan proyek ModelSim dan Lattice iCEcube2.

Sinyal internal modul teratas

Saya ingin menjaga modul teratas saya bebas dari logika RTL. Ini adalah konsep yang disebut modul struktural . Dalam pengalaman saya, lebih mudah untuk mempertahankan proyek VHDL terstruktur ketika Anda memisahkan logika RTL dan interkoneksi. Kode di bawah ini menunjukkan deklarasi sinyal di modul atas dan penetapan sinyal bersamaan.

architecture str of pwm_led is

  signal rst : std_logic;
  signal cnt : unsigned(cnt_bits - 1 downto 0);
  signal pwm_out : std_logic;

  alias duty_cycle is cnt(cnt'high downto cnt'length - pwm_bits);

begin

  led_1 <= '0';
  led_2 <= '0';
  led_3 <= '0';
  led_4 <= '0';

  led_5 <= pwm_out;

Pertama, kami mendeklarasikan sinyal reset yang akan menjadi versi non-terbalik dan sinkron dari reset eksternal kami.

Sinyal kedua yang dideklarasikan, bernama cnt , adalah penghitung siklus jam yang membungkus tanpa batas. Ini adalah tipe tidak bertanda yang akan mempertahankan status gelombang gigi gergaji intensitas LED kami pada waktu tertentu.

Berikutnya adalah pwm_out sinyal. Kita bisa menghubungkan pwm_out sinyal dari modul PWM langsung ke led_5 output, tapi saya ingin mengamati pwm_out di simulatornya. Alat sintesis akan mengetahui bahwa kedua sinyal tersebut termasuk dalam jaring yang sama. Tidak memerlukan sumber daya tambahan.

Akhirnya datanglah deklarasi duty_cycle vector—kali ini, saya menggunakan alias kata kunci alih-alih membuat sinyal baru. Alias ​​​​VHDL bekerja seperti makro di C. Saat kita menggunakan duty_cycle nama mulai sekarang, kompiler akan menggantikannya dengan bit tinggi cnt vektor.

Setelah mulai kata kunci, kami menetapkan pwm_out sinyal ke led_5 keluaran. Semua LED lainnya disambungkan ke '0' untuk mencegahnya menerangi cahaya warna merah.

Instansiasi

Sebelum menggunakan sinyal eksternal di dalam FPGA, kita harus selalu menyinkronkannya dengan jam sistem internal. Jika tidak, kami mungkin mengalami masalah metastabilitas, masalah yang sulit untuk di-debug.

RESET : entity work.reset(rtl)
  port map (
    clk => clk,
    rst_n => rst_n,
    rst => rst
  );

Reset eksternal tidak terkecuali, tetapi karena saya tidak mengizinkan logika RTL apa pun di modul struktural tingkat atas, kami menerapkan sinkronisasi reset sebagai modul yang berdiri sendiri.

Instansiasi berikutnya adalah modul PWM, seperti yang ditunjukkan pada cuplikan kode di bawah ini. Dalam instantiasi modul PWM, kami menggunakan duty_cycle alias untuk menetapkan bit paling signifikan dari cnt vektor ke duty_cycle memasukkan. Itu akan membuat kecerahan LED meningkat hingga penghitung mencapai nilai maksimalnya. Ketika cnt kembali ke nol, LED mati sebentar, dan siklus berulang.

PWM : entity work.pwm(rtl)
  generic map (
    pwm_bits => pwm_bits,
    clk_cnt_len => clk_cnt_len
  )
  port map (
    clk => clk,
    rst => rst,
    duty_cycle => duty_cycle,
    pwm_out => pwm_out
  );

Instansiasi ketiga dan terakhir di modul atas adalah penghitung siklus jam, seperti yang ditunjukkan di bawah ini. Untuk membuat modul ini lebih umum, saya telah menyertakan count_enable sinyal. Namun dalam desain ini, kita akan menyetelnya ke konstanta '1' karena kita ingin menghitung setiap siklus clock.

COUNTER : entity work.counter(rtl)
  generic map (
    counter_bits => cnt'length
  )
  port map (
    clk => clk,
    rst => rst,
    count_enable => '1',
    counter => cnt
  );

Tinggalkan alamat email Anda di formulir di bawah ini jika Anda memerlukan kode VHDL lengkap untuk proyek ini.

Mensimulasikan LED PWM berdenyut

Keuntungan signifikan dari membuat panjang penghitung dapat disesuaikan melalui obat generik adalah memungkinkan Anda untuk mempercepat simulasi. Sebagian besar waktu, kami tertarik untuk menguji transisi dan peristiwa dalam logika kami. Kami tidak begitu tertarik untuk berlari melalui penghitung ultra-panjang sementara tidak ada hal lain yang terjadi dalam desain.

Dengan obat generik, kami dapat mengubah hal-hal ini dengan cara non-invasif dari testbench. Kode di bawah ini menunjukkan nilai yang saya tetapkan ke peta generik saat membuat instance modul PWM di testbench.

DUT : entity work.pwm_led(str)
  generic map (
    pwm_bits => 8,
    cnt_bits => 16,
    clk_cnt_len => 1
  )

Saat kami mensimulasikan menggunakan konstanta ini di ModelSim, cukup untuk berjalan selama 1400 mikrodetik pada 100 MHz untuk mengungkapkan dua siklus PWM penuh. Jika kami menggunakan nilai sebenarnya, kami harus mensimulasikan hampir 6 detik. Itu adalah 32 juta siklus jam yang hampir tidak ada apa-apanya selain terus bertambah. Butuh selamanya di ModelSim.

Gambar di bawah ini menunjukkan bentuk gelombang dari simulasi PWM di ModelSim. Saya telah mengubah format duty_cycle sinyal dari jenis nomor default ke presentasi gelombang analog. Anda dapat melakukannya di ModelSim dengan mengklik kanan pada sinyal dalam bentuk gelombang dan memilih Format->Analog (custom)… , dan atur tinggi piksel dan rentang data agar sesuai dengan nilai minimum dan maksimum sinyal Anda.

Dalam bentuk gelombang, kita dapat melihat mengapa itu disebut sinyal gigi gergaji. Penghitung pembungkus yang berjalan bebas menyerupai gigi pada mata gergaji.

Perhatikan bagaimana durasi periode tinggi keluaran PWM (led_5 ) meningkat seiring bertambahnya siklus kerja. Kita juga dapat melihat bahwa led_5 adalah kontinu '1' sangat singkat di ujung gigi gergaji. Saat itulah siklus tugas adalah 255, nilai maksimal.

Jika kita tidak menambahkan pernyataan if ekstra dalam modul PWM, pernyataan yang membungkus pwm_cnt sinyal kembali ke nol pada nilai tertinggi kedua, kami tidak akan melihat ini. Kami tidak akan pernah bisa mencapai output daya maksimum. Ini adalah kesalahan umum saat mengimplementasikan generator PWM. Saya juga pernah melakukannya sekali atau dua kali.

Penerapan FPGA

Saya menerapkan desain pada iCEstick Lattice menggunakan iCEcube2, perangkat lunak desain dari Lattice. Daftar di bawah ini menunjukkan penggunaan sumber daya yang dilaporkan setelah tempat dan rute. Meskipun FPGA iCE40 berukuran kecil, PWM dan modul pendukung hanya menggunakan 5% dari LUT yang tersedia.

Resource Usage Report for pwm_led 

Mapping to part: ice40hx1ktq144
Cell usage:
GND             3 uses
SB_CARRY        31 uses
SB_DFF          5 uses
SB_DFFSR        39 uses
SB_GB           1 use
VCC             3 uses
SB_LUT4         64 uses

I/O ports: 7
I/O primitives: 7
SB_GB_IO       1 use
SB_IO          6 uses

I/O Register bits:                  0
Register bits not including I/Os:   44 (3%)
Total load per clock:
   pwm_led|clk: 1

@S |Mapping Summary:
Total  LUTs: 64 (5%)

Setelah menghasilkan bitstream pemrograman di iCEcube2, saya menggunakan programmer mandiri Lattice Diamond untuk mengonfigurasi FPGA melalui USB.

Animasi Gif di bawah ini menunjukkan bagaimana sinyal siklus kerja gelombang gigi gergaji membuat LED penyalaan pada iCEstick berperilaku. Itu menyala dengan intensitas yang meningkat sampai cnt bungkus kontra. Kemudian, siklus tugas menjadi nol, dan LED mati sebentar. Setelah itu, siklus berulang tanpa batas.

iCEstick adalah papan pengembangan FPGA yang murah dan serbaguna. Ini bagus untuk pemula, tetapi juga cocok untuk proyek tertanam tingkat lanjut. Selain itu, perangkat lunak Lattice tidak rumit dan mudah digunakan. Itulah mengapa saya menggunakan iCEstick di kursus VHDL pemula dan kursus FPGA lanjutan.

Jika Anda sudah memiliki iCEstick, Anda dapat menggunakan formulir di bawah ini untuk mengunduh proyek iCEcube2.

Siklus tugas gelombang sinus untuk efek pernapasan LED

Sekarang Anda tahu cara mengontrol iluminasi LED menggunakan PWM.

LED berdenyut dalam pola gelombang gigi gergaji bisa dibilang lebih keren daripada aplikasi kedip ON/OFF sederhana. Itu adalah tugas pertama yang biasa dilakukan oleh siswa VHDL, dan saya yakin Anda telah menyalakan LED pada suatu saat.

Namun, kedipan LED menjadi lebih mengesankan jika Anda menggunakan gelombang sinus untuk mengontrol siklus kerja. Animasi Gif di bawah ini menunjukkan modul PWM kami yang menggerakkan LED dengan variasi intensitas sinusoid dari waktu ke waktu.

Saya yakin Anda pernah melihat efek "pernapasan" semacam ini pada LED sebelumnya. Begitulah perilaku LED notifikasi di ponsel saya, dan menurut saya itu terlihat wajar karena tidak ada perubahan mendadak dalam intensitas cahaya.

Dalam posting blog saya berikutnya, saya akan menunjukkan cara membuat generator gelombang sinus dengan menggunakan RAM blok di FPGA. Dan kita akan memodifikasi pwm_led modul untuk menggerakkan LED pada iCEstick dengan intensitas gelombang sinus.

Klik di sini untuk masuk ke entri blog berikutnya:
Cara membuat efek LED pernapasan menggunakan gelombang sinus yang disimpan di blok RAM

Lihat juga:
Pengontrol servo RC menggunakan PWM dari pin FPGA


VHDL

  1. Pengontrol Daya PWM
  2. Cara membuat daftar string di VHDL
  3. Cara membuat testbench berbasis Tcl untuk modul kunci kode VHDL
  4. Bagaimana menghentikan simulasi di testbench VHDL
  5. Cara menghasilkan angka acak di VHDL
  6. Cara membuat penyangga cincin FIFO di VHDL
  7. Cara membuat testbench pemeriksaan mandiri
  8. Cara membuat Daftar Tertaut di VHDL
  9. Cara menggunakan Prosedur dalam Proses di VHDL
  10. Bagaimana Cara Mengisi Kapasitor?