- Apakah Isyarat PWM?
- Memprogram PIC untuk menghasilkan PWM pada GPIO Pin
- Rajah Litar
- Simulasi
- Persediaan Perkakasan untuk mengawal Motor Servo menggunakan PIC Microcontroller
Penjanaan isyarat PWM adalah alat penting dalam setiap gudang jurutera tertanam, mereka sangat berguna untuk banyak aplikasi seperti mengawal kedudukan motor servo, menukar beberapa IC elektronik berkuasa dalam penukar / penyongsang dan bahkan untuk kawalan kecerahan LED yang sederhana. Dalam mikrokontroler PIC, isyarat PWM dapat dihasilkan menggunakan modul Bandingkan, Tangkap dan PWM (CCP) dengan menetapkan Daftar yang diperlukan, kita sudah belajar bagaimana melakukannya dalam tutorial PIC PWM. Tetapi ada satu kelemahan dengan kaedah itu.
The PIC16F877A boleh menjana isyarat PWM hanya pada pin RC1 dan RC2, jika kita menggunakan modul PKC. Tetapi kita mungkin menghadapi situasi, di mana kita memerlukan lebih banyak pin untuk mempunyai fungsi PWM. Sebagai contoh dalam kes saya, saya ingin mengawal 6 motor servo RC untuk projek lengan robot saya yang modul CCP tidak ada harapan. Dalam senario ini kita dapat memprogram pin GPIO untuk menghasilkan isyarat PWM menggunakan modul pemasa. Dengan cara ini kita dapat menghasilkan seberapa banyak isyarat PWM dengan pin yang diperlukan. Terdapat juga peretasan perkakasan lain seperti menggunakan IC multiplexer, tetapi mengapa melabur pada perkakasan apabila perkara yang sama dapat dicapai melalui pengaturcaraan. Jadi dalam tutorial ini kita akan belajar bagaimana menukar pin PIC GPIO menjadi pin PWM dan untuk mengujinya kita akan mensimulasikannya pada proteus dengan osiloskop digital dan jugamengawal kedudukan motor Servo menggunakan isyarat PWM dan mengubah putaran tugasnya dengan memvariasikan potensiometer.
Apakah Isyarat PWM?
Sebelum kita mengetahui dengan terperinci, mari kita jelaskan mengenai apakah Isyarat PWM. Pulse Width Modulation (PWM) adalah isyarat digital yang paling biasa digunakan dalam litar kawalan. Isyarat ini ditetapkan tinggi (5v) dan rendah (0v) dalam masa dan kelajuan yang telah ditetapkan. Masa di mana sinyal tetap tinggi disebut "tepat waktu" dan masa di mana isyarat tetap rendah disebut "waktu mati". Terdapat dua parameter penting untuk PWM seperti yang dibincangkan di bawah:
Kitaran tugas PWM
Peratusan masa di mana isyarat PWM kekal TINGGI (tepat pada waktunya) disebut sebagai kitaran tugas. Sekiranya isyarat sentiasa AKTIF, ia berada dalam kitaran tugas 100% dan jika sentiasa mati, ia adalah kitaran tugas 0%.
Duty Cycle = Hidupkan waktu / (Hidupkan waktu + Matikan masa)
Nama Pembolehubah |
Merujuk kepada |
PWM_Frekuensi |
Kekerapan Isyarat PWM |
T_TOTAL |
Jumlah masa yang diambil untuk satu pusingan lengkap PWM |
T_ON |
Pada masa isyarat PWM |
T_OFF |
Waktu keluar isyarat PWM |
Kitar tugas |
Kitaran tugas isyarat PWM |
Jadi sekarang, mari kita buat matematik.
Ini adalah formula standard di mana frekuensi hanyalah timbal balik masa. Nilai frekuensi harus diputuskan dan ditetapkan oleh pengguna berdasarkan keperluan aplikasinya.
T_TOTAL = (1 / PWM_Frekuensi)
Apabila pengguna mengubah nilai kitaran Duti, program kami harus secara automatik menyesuaikan waktu T_ON dan waktu T_OFF sesuai dengan itu. Jadi formula di atas boleh digunakan untuk mengira T_ON berdasarkan nilai Duty_Cycle dan T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Oleh kerana Jumlah masa isyarat PWM untuk satu kitaran penuh akan menjadi jumlah masa masa dan waktu rehat. Kami dapat mengira waktu tutup T_OFF seperti yang ditunjukkan di atas.
T_OFF = T_TOTAL - T_ON
Dengan rumusan ini, kita dapat mula memprogram mikrokontroler PIC. Program ini melibatkan Modul PIC Timer dan PIC ADC untuk membuat isyarat PWM berdasarkan kitaran Tugas yang berbeza-beza mengikut nilai ADC yang membentuk POT. Sekiranya anda baru menggunakan modul ini, sangat disarankan untuk membaca tutorial yang sesuai dengan mengklik pada pautan tersebut.
Memprogram PIC untuk menghasilkan PWM pada GPIO Pin
Program lengkap untuk tutorial ini boleh didapati di bahagian bawah laman web seperti biasa. Dalam bahagian ini mari kita fahami bagaimana program ini sebenarnya ditulis. Seperti semua program, kita mulakan dengan menetapkan bit konfigurasi. Saya telah menggunakan pilihan paparan memori untuk menetapkannya untuk saya.
// CONFIG #pragma config FOSC = HS // Oscillator Selection bit (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit ( WDTabled ) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT dilumpuhkan) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Voltan Rendah (Bekalan Tunggal) In-Circuit Serial Programming Enable bit (RB3 adalah digital I / O, HV pada MCLR mesti digunakan untuk pengaturcaraan) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bit (Tulis perlindungan mati; semua memori program boleh ditulis oleh kawalan EECON) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // # penyataan konfigurasi pragma harus mendahului fail projek termasuk. // Gunakan enum projek dan bukannya #define untuk ON dan OFF. #sertakan
Kemudian kami menyebutkan frekuensi jam yang digunakan dalam perkakasan, di sini perkakasan saya menggunakan kristal 20MHz, anda boleh memasukkan nilai berdasarkan perkakasan anda. Diikuti oleh itu adalah nilai frekuensi isyarat PWM. Oleh kerana tujuan saya di sini adalah untuk mengawal motor servo RC hobi yang memerlukan frekuensi PWM 50Hz, saya telah menetapkan 0.05KHz sebagai nilai Frekuensi, anda juga dapat mengubahnya berdasarkan keperluan aplikasi anda.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0.05 // dalam KHz (50Hz)
Sekarang, kita mempunyai nilai Frekuensi, kita dapat mengira T_TOTAL menggunakan formula yang dibincangkan di atas. Hasilnya dijauhkan oleh 10 untuk mendapatkan nilai masa dalam mili saat. Dalam kes saya, nilai T_TOTAL akan menjadi 2 mili saat.
int T_TOTAL = (1 / PWM_Frequency) / 10; // hitung Jumlah Masa dari kekerapan (dalam mil mil)) // 2msec
Diikuti dengan itu, kami menginisialisasi modul ADC untuk membaca kedudukan Potensiometer seperti yang dibincangkan dalam tutorial ADC PIC kami. Selanjutnya kita mempunyai rutin perkhidmatan Interrupt yang akan dipanggil setiap kali, timer melimpah akan kita kembali ke ini kemudian, untuk sekarang mari kita periksa fungsi utama.
Di dalam fungsi utama kita mengkonfigurasi modul pemasa. Di sini saya telah mengkonfigurasi modul Pemasa untuk melimpah setiap 0.1ms. Nilai untuk masa dapat dikira dengan menggunakan formula di bawah
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) kelewatan dalam saat dan Fosc dalam hz
Dalam kes saya untuk kelewatan 0.0001 saat (0.1ms) dengan preskalaar 64 dan Fosc 20MHz nilai daftar saya (TMR0) mestilah 248. Jadi konfigurasi kelihatan seperti ini
/ ***** Konfigurasi Port untuk Pemasa ****** / OPTION_REG = 0b00000101; // Timer0 dengan freq luaran dan 64 sebagai prescalar // Juga Membolehkan PULL UPs TMR0 = 248; // Muatkan nilai masa untuk 0.0001s; delayValue boleh antara 0-256 hanya TMR0IE = 1; // Aktifkan bit gangguan pemasa dalam daftar PIE1 GIE = 1; // Dayakan Global Interrupt PEIE = 1; // Dayakan Periferal Interrupt / *********** ______ *********** /
Maka kita harus menetapkan konfigurasi Input dan Output. Di sini kita menggunakan pin AN0 untuk membaca nilai ADC dan pin PORTD untuk mengeluarkan isyarat PWM. Oleh itu, mulailah mereka sebagai pin output dan buatnya rendah dengan menggunakan baris kod di bawah.
/ ***** Konfigurasi Port untuk I / O ****** / TRISD = 0x00; // Arahkan MCU bahawa semua pin pada PORT D adalah output PORTD = 0x00; // Memulakan semua pin ke 0 / *********** ______ *********** /
Di dalam loop sementara yang tidak terhingga, kita harus mengira nilai tepat pada masanya (T_ON) dari kitaran tugas. Yang pada masa dan kewajipan kitaran berbeza-beza mengikut kedudukan POT jadi kami melakukannya berulang kali di dalam manakala gelung seperti yang ditunjukkan di bawah. 0.0976 adalah nilai yang harus dikalikan dengan 1024 untuk mendapatkan 100 dan untuk mengira T_ON kita telah mengalikannya dengan 10 untuk mendapatkan nilai dalam mil saat.
sementara (1) { POT_val = (ADC_Read (0)); // Baca nilai POT menggunakan ADC Duty_cycle = (POT_val * 0.0976); // Peta 0 hingga 1024 hingga 0 hingga 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Hitung Pada Masa menggunakan unit formula dalam mili saat __delay_ms (100); }
Oleh kerana pemasa ditetapkan untuk aliran lebih untuk setiap 0.1ms, ISR rutin perkhidmatan pemasa akan dipanggil untuk setiap 0.1ms. Di dalam rutin perkhidmatan kami menggunakan pemboleh ubah yang disebut hitungan dan menambahnya untuk setiap 0.1ms. Dengan cara ini kita dapat menjejaki masa. Untuk mengetahui lebih lanjut mengenai gangguan dalam mikrokontroler PIC, ikuti pautan
if (TMR0IF == 1) // Bendera pemasa telah dipicu kerana limpahan pemasa -> ditetapkan untuk meluap untuk setiap 0.1ms { TMR0 = 248; // Muatkan pemasa Nilai TMR0IF = 0; // Hapus kiraan bendera gangguan pemasa ++; // Kenaikan kiraan untuk setiap 0.1ms -> kiraan / 10 akan memberikan nilai kiraan dalam ms }
Akhirnya tiba masanya untuk menukar pin GPIO berdasarkan nilai T_ON dan T_OFF. Kami mempunyai pemboleh ubah kiraan yang mencatat masa dalam mil saat. Oleh itu, kami menggunakan pemboleh ubah tersebut untuk memeriksa sama ada waktu kurang daripada tepat pada waktunya , jika ya maka kami tetap menghidupkan pin GPIO jika tidak, kami mematikannya dan mematikannya sehingga kitaran baru bermula. Ini dapat dilakukan dengan membandingkannya dengan jumlah masa satu kitaran PWM. Kod untuk melakukan perkara yang sama ditunjukkan di bawah
if (hitung <= (T_ON)) // Sekiranya masa kurang daripada waktu RD1 = 1; // Hidupkan GPIO lain RD1 = 0; // Jika tidak, matikan GPIO jika (kiraan> = (T_TOTAL * 10)) // Tetap dimatikan sehingga kitaran baru mula dihitung = 0;
Rajah Litar
Gambarajah litar untuk menghasilkan PWM dengan pin GPIO mikrokontroler PIC sangat mudah, cukup power PIC dengan pengayun dan sambungkan potensiometer ke pin AN0 dan Motor Servo ke pin RD1, kita boleh menggunakan pin GPIO untuk mendapatkan isyarat PWM, saya telah memilih RD1 tidak secara rawak. Kedua-dua Potensiometer dan motor Servo dikuasakan oleh 5V yang diatur dari 7805 seperti yang ditunjukkan di bawah dalam rajah litar.
Simulasi
Untuk mensimulasikan projek, saya menggunakan perisian proteus saya. Bina litar yang ditunjukkan di bawah dan pautkan kod ke simulasi anda dan jalankan. Anda harus mendapat isyarat PWM pada pin GPIO RD1 sesuai program kami dan kitaran tugas PWM harus dikendalikan berdasarkan kedudukan potensiometer. GIF di bawah menunjukkan bagaimana isyarat PWM dan motor servo bertindak balas apabila nilai ADC diubah melalui potensiometer.
Persediaan Perkakasan untuk mengawal Motor Servo menggunakan PIC Microcontroller
Penyediaan perkakasan saya yang lengkap ditunjukkan di bawah, bagi orang yang mengikuti tutorial saya, papan ini semestinya tidak asing lagi, ia adalah papan yang sama yang saya gunakan dalam semua tutorial saya setakat ini. Anda boleh merujuk tutorial LED Berkedip jika anda berminat untuk mengetahui bagaimana saya membinanya. Jika tidak, ikuti rajah litar di atas dan semuanya mesti berjalan lancar.
Muat naik program dan ubah potensiometer dan anda akan melihat servo mengubah kedudukan berdasarkan kedudukan potensiometer. Kerja- kerja lengkap projek ditunjukkan dalam video yang diberikan di akhir halaman ini. Harap anda memahami projek ini dan senang membina, jika anda mempunyai pertanyaan, sila hantarkannya di forum dan saya akan mencuba yang terbaik dalam menjawabnya.
Saya merancang untuk meneruskan projek ini dengan menambahkan pilihan untuk mengawal pelbagai motor servo dan dengan itu membina lengan robot daripadanya, serupa dengan Arduino Robotic Arm yang telah kita bina. Jadi sampai jumpa ya !!