Menggunakan pengontrol PSBC UDB Cypress untuk mengurangi interupsi pada printer 3D



Dalam komentar pada terjemahan dokumentasi hak milik pada UDB, dengan tepat dicatat bahwa fakta kering tidak berkontribusi pada pemahaman materi. Tapi dokumen itu justru mengandung fakta kering. Untuk melemahkannya dengan latihan, mari kita berhenti sejenak dari penerjemahan. Mari kita putar blok ini di tangan kita dan lihat apa dan bagaimana itu dapat dicapai dalam praktek.

Pengantar panjang


Artikel ini adalah bagian kedua dari trilogi yang dikandung. Bagian pertama terletak di sini (kontrol LED RGB melalui unit mikrokontroler Cypress UDB PSoC).

Selain pengontrol PSBC UDB Cypress, di mana antarmuka tertentu diimplementasikan pada mereka, akan menarik untuk memeriksa bagaimana blok ini dapat membuat hidup lebih mudah bagi programmer dengan menurunkan prosesor pusat dari tugas-tugas intensif sumber daya tertentu. Tetapi untuk memperjelas apa yang akan saya lakukan, saya harus menulis kata pengantar yang luas.

Pada musim gugur 2015, saya membeli printer 3D MZ3D yang baru, dan pada musim semi 2016 saya bosan dengan bagaimana motor loncatannya berderak. Masa-masa itu liar, kami bertahan sebaik mungkin, jadi satu-satunya solusi adalah beralih dari microstep 1/16 ke 1/32. Korespondensi dengan pabrik menunjukkan bahwa ini tidak mungkin di Arduino. Ternyata, ada pembatasan dalam "firmware" tahun-tahun itu, dengan frekuensi langkah lebih tinggi dari 10 KHz, bukan langkah virtual yang diambil, tetapi dua langkah virtual, jika tidak sistem tidak punya cukup waktu untuk memproses semua "langkah" interupsi. Hanya ada satu jalan keluar - untuk menyeret semuanya ke platform ARM. Itu adalah drag and drop, bukan unduhan, karena tidak ada solusi ARM yang siap pakai saat itu. Dalam beberapa minggu saya mentransfer semua ini ke STM32F4, suara mesin menjadi lebih menyenangkan, masalah terselesaikan.

Kemudian pengembangan OS dimulai di perusahaan kami, dan pada pertemuan itu saya harus membuktikan untuk waktu yang lama bahwa pendekatan khas untuk memproses interupsi tidak selalu dapat diterima dalam hal kecepatan, menarik hanya untuk kasus yang khas, tetapi sangat rakus. Diskusi tentang hal ini diterbitkan dalam artikel saya tentang interupsi di OS di sini (Tinjauan satu RTOS Rusia, bagian 8. Bekerja dengan interupsi). Secara umum, masalah telah ada di kepala saya untuk waktu yang lama: gangguan tambahan yang sering melayani satu subsistem memperlambat segalanya. Penyempurnaan sederhana dari prosesor sentral, tentu saja, menghilangkan masalah, tetapi tidak membawa Kepuasan Moral Dalam bahwa semuanya dilakukan dengan benar.

Secara berkala, saya kembali ke pertanyaan ini dalam pengertian teoretis semata. Misalnya, suatu hari pikiran itu merayap ke kepala saya bahwa alih-alih menggunakan pengontrol yang mahal, Anda dapat mengambil tiga STM32F103C8T6, di mana papan tempat memotong roti yang sudah jadi harganya 110 rubel, dengan memperhitungkan pengiriman akun, dan chip itu sendiri bahkan lebih murah. Di salah satunya hanya mengeluarkan fungsi kontrol mesin. Biarkan dia menghabiskan semua daya komputasi untuk fungsi ini. Beberapa yang lain (bahkan mungkin satu) menyelesaikan tugas-tugas lain (memproses perintah, bekerja dengan PWM, mempertahankan suhu, dll.) Dalam lingkungan yang tenang. Solusi ini juga memiliki sisi besar plus - jumlah pin untuk beberapa pengontrol cukup besar. Pada satu STM32, saya harus membuat solitaire untuk waktu yang lama, untuk leg yang mana. Meskipun kaki-kaki pengatur waktu dan kaki-kaki ADC dari ARM ditetapkan lebih fleksibel daripada pengontrol lama (satu output dari unit perangkat keras dapat menuju ke salah satu dari beberapa kaki fisik), tetapi ketika melipat solitaire yang sangat, Anda memahami bahwa fleksibilitas mungkin tidak cukup. Jika ada banyak pengontrol, maka pilihan meningkat. Pada motor yang melayani stepper motor, secara umum, kami hanya menetapkan semua kaki sebagai output digital. Yang lain juga punya tempat untuk berbalik.

Satu masalah dengan pendekatan ini adalah bagaimana cara menyinkronkan pengontrol ini? Secara teori, MAX Max RTOS berisi semua yang Anda butuhkan. Pawang perintah menghasilkan daftar tugas untuk memindahkan kepala. Secara berkala, ia memodifikasi mereka (dengan mengkoordinasikan akselerasi dengan tugas yang baru tiba). Jadi memori untuk pembentuk dan pemain harus dibagikan. RTOS MAX berisi fungsionalitas untuk mengatur memori bersama tersebut. Saya jelaskan di sini (Tinjauan satu RTOS Rusia, bagian 7. Cara bertukar data antar tugas). Namun dalam praktiknya, satu nuansa merusak segalanya: servis motor stepper adalah jenis tugas yang sangat menentukan waktu. Penundaan sedikit pun, dan kami mendapatkan aliran plastik untuk printer 3D, untuk mesin CNC lainnya - baik, misalnya, ulir yang salah. Komunikasi apa pun melalui antarmuka serial bukan yang tercepat. Plus - waktu untuk arbitrasi dan kebutuhan resmi lainnya. Dan ternyata semua keuntungan dari penghapusan fungsionalitas dari prosesor utama menjadi overhead. Tentu saja, saya mengambil keuntungan dari posisi resmi saya: saya pergi dan membahas masalah ini dengan para pengembang subsistem ini. Sayang Mereka mengatakan bahwa ada sinkronisasi tanpa banyak overhead di OS, tetapi untuk peralatan yang mendukung bus yang sesuai. Sekarang, jika saya mengambil arsitektur TigerShark sebagai dasar, OS akan mengatur segalanya untuk saya tanpa overhead. Hanya pengontrol yang dibuat menurut arsitektur ini yang beberapa kali lebih mahal daripada seluruh printer 3D yang ingin saya masukkan ke dalamnya. Secara umum, sekali lagi tidak dapat diterima.

Kami mendekati akhir dari pengantar yang berlarut-larut. Seseorang akan mengatakan bahwa karena alasan tertentu aku masih mencari pangeran di atas kuda putih. Anda dapat mengambil dan melakukan semuanya tanpa OS, dan di sini saya sedang mempertimbangkan segala macam pilihan ... Anda bisa, tetapi Anda bisa, tetapi ketika masalah praktis "Bosan mendengarkan tabrakan printer" muncul, itu cepat diperbaiki. Itu saja. Dia tidak ada lagi. Selain itu, sejak itu ada driver motor stepper baru yang umumnya menyelesaikan masalah itu dengan cara yang sama sekali berbeda (mereka mendapatkan microstep 1/16, dan membagikan 1/256). Dan dalam pengantar ini, saya menjelaskan dengan tepat bahwa "Tidak ada solusi yang bagus untuk masalah seringnya gangguan." Keputusan jelek telah lama dibuat. Saya tidak ingin membuang waktu memeriksa keputusan buruk lainnya. Mereka hanya menggulir di kepalaku.

Tetapi ketika saya berurusan dengan blok UDB, saya merasa bahwa masalahnya dapat diselesaikan dengan indah dan dramatis. Anda cukup membawa pemrosesan gangguan dari perangkat lunak ke tingkat firmware, meninggalkan bagian komputasi pada hati nurani prosesor utama. Tidak diperlukan pengontrol tambahan! Semuanya ditempatkan pada chip yang sama! Jadi, mari kita mulai.

Kuda bulat dalam ruang hampa


Dalam artikel ini, bekerja dengan UDB sendiri akan berada di garis depan. Jika saya berbicara tentang terikat pada "firmware" tertentu, mereka dapat dengan tepat menunjukkan kepada saya bahwa saya salah dengan hub. Apa itu untuk GeekTimes. Oleh karena itu, UDB adalah yang utama, dan motor stepper adalah hal yang indah untuk digambarkan. Pada bagian ini saya umumnya akan membuat kuda bulat dalam ruang hampa. Dia akan memiliki kekurangan praktis, yang akan saya hilangkan di bagian kedua. Tetapi mengulangi tindakan saya, pembaca akan dapat menguasai metodologi pengembangan firmware untuk UDB.

Jadi Bagaimana cara kerja mekanisme kontrol motor stepper? Ada tugas yang mengatur segmen yang harus dilewati kepala dengan kecepatan linier. Sejauh ini, saya akan berpura-pura tidak ingat tentang akselerasi di awal dan akhir segmen. Hanya kepala yang harus dilaluinya. Segmen baru diletakkan di ujung antrian. Berdasarkan rekaman dari kepala, tugas terpisah mengirimkan sinyal LANGKAH ke semua mesin aktif.

Biarkan printer memiliki kecepatan head maksimum 200 mm / s. Biarkan 200 langkah diperlukan per 1 milimeter gerakan (angka ini sesuai dengan printer nyata MZ3D-256C dengan microstep 1/32). Maka pulsa harus dilengkapi dengan frekuensi hingga 200 * 200 = 40.000 Hz = 40 KHz. Ini dengan frekuensi sedemikian rupa sehingga tugas pulsa langkah pengiriman mungkin dipanggil. Ini harus secara terprogram membentuk pulsa sendiri, dan juga menghitung berapa lama setelah itu pengaktifan berikutnya harus dipanggil.

Saya ingat sebuah lelucon tentang Kolobok dan Tiga Bogatyrs, di mana Kolobok secara konsisten menyapa para Bogatyrs, kemudian secara konsisten mengajukan pertanyaan kepada mereka dan menerima jawaban. Kemudian berturut-turut mengucapkan selamat tinggal kepada mereka. Nah, kemudian dia bertemu dengan Tiga Puluh Tiga Ksatria. Prosesor dalam peran roti, dan motor stepper dalam peran Bogatyrs. Jelas bahwa di hadapan sejumlah besar blok UDB, dimungkinkan untuk memparalelkan pekerjaan dengan mesin, setelah setiap mesin diservis ke bloknya. Dan karena kita memiliki segmen di mana mesin akan bergerak secara merata, mari kita coba untuk membuat peralatan bekerja dengan transaksi seperti itu, dan tidak dengan setiap langkah.

Informasi apa yang diperlukan untuk kuda bulat untuk melintasi bagian linier dalam ruang hampa?

  • Jumlah langkah.
  • Periode waktu antar langkah.

Dua parameter. UDB hanya memiliki dua baterai dan dua register parameter D0 dan D1. Tampaknya semuanya dapat diwujudkan. Kami hanya memperkirakan kedalaman bit yang seharusnya dimiliki register ini.

Pertama, jumlah langkah. Jika ada 8 digit, maka dalam satu siklus operasi UDB, printer akan dapat menggerakkan kepala printer Cartesian sedikit lebih dari 1 mm (200 langkah mikro). Tidak cukup Jika kapasitasnya 16 bit, maka jumlah langkahnya adalah 65536. Ini adalah 65536/200 = 327 milimeter. Dapat diterima untuk sebagian besar model. Untuk Core, Delta dan lainnya perlu untuk memperkirakan, tetapi secara keseluruhan - untuk stroke penuh, segmen dapat dibagi menjadi beberapa bagian. Tidak akan ada begitu banyak (dua, yah, maksimal tiga).

Sekarang waktunya. Biarkan frekuensi clock menjadi 48 MHz. 48000000/65536 = 732. Artinya, frekuensi minimum yang diijinkan yang dapat diperoleh dengan menggunakan pembagi 16-bit adalah 732 Hz. Terlalu banyak Dalam Marlin Firmware, minimum adalah 120 Hz (yang kira-kira setara dengan 8 MHz dibagi dengan konstanta yang sama 65536). Kami harus membuat register 24 bit. Maka frekuensi minimum akan sama dengan 48000000 / (2 ^ 24) = 48000000/16777216 = 2,861 Hz.

Bagus Hentikan teori yang membosankan! Mari kita lanjutkan berlatih! Luncurkan PSoC Creator dan pilih File-> New-> Project:



Selanjutnya, saya memilih papan tempat memotong roti yang saya miliki, dari mana lingkungan akan mengambil informasi dasar tentang pengontrol yang digunakan dan pengaturannya:



Saya sudah merasa siap untuk membuat proyek dari awal, jadi saya pilih Kosong Skema :



Berikan lingkungan kerja nama PSoC3DTest :



Dan ini dia, proyek yang sudah selesai!



Hal pertama yang ingin saya lakukan adalah membuat komponen sendiri berdasarkan UDB. Oleh karena itu, sebagaimana telah disebutkan dalam artikel terakhir, saya perlu beralih ke tab Komponen :



Klik kanan pada proyek dan pilih Tambahkan Komponen :



Kami mengatakan bahwa kami perlu menambahkan Dokumen UDB , mengubah nama menjadi StepperController dan klik Buat Baru :



Komponen muncul di pohon, plus - editor komponen ini dibuka:



Tempatkan blok Datapath pada formulir:



Setelah memilih blok ini, kita pergi ke propertinya dan mengubah kedalaman bit dari 8 menjadi 24. Parameter yang tersisa dapat dibiarkan tidak berubah.



Untuk memulai semua blok (untuk semua mesin) secara bersamaan, saya akan memulai sinyal awal dari luar (tambahkan input Mulai ). Output: Saya akan membuat Langkah keluar secara langsung, sehingga saya bisa mengirimkannya ke driver motor stepper, serta Out_Idle . Berdasarkan sinyal ini, prosesor akan dapat menentukan bahwa pada saat unit telah selesai bekerja. Nama-nama sirkuit yang cocok dengan input dan output ini terlihat pada gambar.



Sebelum berbicara tentang logika automaton, saya akan menjelaskan masalah rekayasa murni: mengatur durasi pulsa. Dokumentasi driver DRV8825 mengharuskan lebar pulsa setidaknya 1,9 μs. Driver lain kurang menuntut pada lebarnya. Seperti yang sudah disebutkan di bagian teoretis, register yang ada sudah ditempati dengan menetapkan durasi langkah dan jumlah langkah. Suka atau tidak, penghitung tujuh-bit harus ditempatkan pada sirkuit. Kami menyebutnya one-shot, yang mengatur pulsa langkah. Pada frekuensi 48 MHz, untuk memastikan durasi 1,9 μs, penghitung ini harus menghitung setidaknya 91,2 langkah. Bulatkan hingga 92. Nilai apa pun yang melebihi ini akan menjadi tidak kurang. Ternyata pengaturan berikut:



Counter Name SingleVibrator . Ini tidak pernah diatur ulang, sehingga input Reset selalu terhubung ke nol, itu menganggap ketika mesin (dijelaskan di bawah) berada dalam keadaan Satu, itu memuat di semua negara lain (pada awalnya saya memilih negara bagian tertentu dari mesin, tetapi ternyata dengan metode yang rumit seperti itu , sumber daya PLD jauh lebih sedikit, tetapi hasilnya sama). Nilai muatnya adalah desimal 92. Benar, editor yang baik akan segera mengganti nilai ini dengan heksadesimal:



Ketika penghitung dihitung ke nol, itu akan melaporkan ini ke rantai dengan nama One_Finished . Dengan konter - itu saja.

Apa jenis bendera status yang akan digunakan mesin kami? Saya mendapatkannya seperti ini (saya mengingatkan Anda untuk mengklik dua kali pada daftar output di Datapath untuk mengaturnya):





Saya akan menggunakan baterai A0 sebagai penghitung untuk durasi pulsa, jadi ketika nilainya mencapai nol, sebuah bendera akan dikokang, yang saya beri nama Pulse_Finished . Baterai A1 akan menghitung pulsa untuk saya. Oleh karena itu, penekanannya akan memiringkan bendera Process_Finished .

Kami membuat grafik transisi automaton:



Variabel yang menetapkan negaranya disebut State . Segera memetakan variabel ini ke register alamat dari instruksi ALU. Awalnya saya lupa melakukan ini, jadi untuk waktu yang lama saya tidak bisa mengerti mengapa mesin saya tidak berfungsi. Klik dua kali pada blok entri dalam Datapath:



Dan mencocokkan:



Kami mulai berurusan dengan grafik transisi dan instruksi ALU yang terkait dengannya.

Mari kita mulai dengan kondisi Idle . Cukup jenuh dalam aksinya.

Pertama, nilai register data D0 dan D1 secara konstan ditempatkan pada baterai A0 dan A1, masing-masing:



Dari entri ini, mata yang terlatih akan melihat semua yang Anda butuhkan. Karena mata kita masih belum diatur, kita klik dua kali pada entri dan melihat hal yang sama, tetapi lebih terinci:



Nilai utama di sini adalah mengisi baterai A1, penghitung pulsa. Ketika program memasukkan nilai D1, itu segera pergi ke A1. Program pasti tidak akan punya waktu untuk memulai proses sampai langkah selanjutnya. Nilai ini diperiksa untuk membentuk suatu kondisi untuk keluar dari keadaan ini, yaitu, tidak ada tempat lain untuk mengisinya.

Sekarang mari kita lihat apa yang dilakukan pada level grafik transisi:



Pemicu bantu Start_Prev memungkinkan Anda untuk menangkap sisi positif pada input Mulai , mengatur garis tunda selama 1 siklus. Itu akan selalu berisi keadaan input Mulai , yang pada ukuran sebelumnya. Seseorang yang lebih terbiasa melihat ini di Verilog:



Teks yang sama
always @ (posedge clock) begin : Idle_state_logic case(State) Idle : begin Start_Prev <= (Start); IsIdle <= (1); if (( Start&(!Start_Prev)&(!Process_Finished) ) == 1'b1) begin State <= One ; end end 


Dengan demikian, kondisi Mulai & (! Mulai_Prev) benar hanya ketika perbedaan garis Mulai positif terjadi di antara langkah-langkah .

Selain itu, ketika mesin berada dalam keadaan ini, output IsIdle dibawa ke dalam satu keadaan, menginformasikan lingkungan eksternal bahwa blok pasif. Dengan pendekatan ini, lebih sedikit sumber daya PLD yang dihabiskan daripada jika Negara == Konstruksi menganggur diserahkan ke output.

Ketika perbedaan sinyal Mulai berasal dari lingkungan eksternal, dan akumulator A1 memiliki nilai non-nol, mesin akan keluar dari status Idle . Jika nol dimasukkan dalam A1, maka mesin tidak terlibat dalam pengembangan segmen ini, sehingga perbedaan pada garis Start diabaikan. Ini berlaku untuk ekstruder yang tidak digunakan. Untuk beberapa printer, mesin Z-axis juga jarang digunakan. Biarkan saya mengingatkan Anda bagaimana kondisi terbentuk yang mengungkapkan nilai nol di A1 (dan bukan nol adalah inversinya):



Selanjutnya, mesin memasuki negara One :



Dalam keadaan ini, output Langkah diatur ke 1. Pulsa langkah diterapkan ke driver. Selain itu, nilai pemicu IsIdle diatur ulang . Lingkungan eksternal diinformasikan bahwa unit berada dalam fase aktif.

Keadaan ini dikeluarkan oleh sinyal One_Finished , yang akan dinaikkan menjadi satu ketika penghitung tujuh-bit dihitung menjadi nol. Biarkan saya mengingatkan Anda bahwa sinyal One_Finished dihasilkan oleh penghitung khusus ini:



Saat mesin dalam kondisi ini, ALU memuat ke dalam baterai A0 (mengatur durasi pulsa) nilai dari register D0. Biarkan saya menunjukkan kepada Anda hanya catatan singkat yang mengatakan ini:



Nilai yang dimuat akan digunakan dalam kondisi berikut. Berada di dalamnya, mesin menghasilkan penundaan yang menetapkan durasi pulsa:



Output Langkah diatur ulang ke nol. Baterai A0 berkurang, sebagaimana dibuktikan oleh entri singkat berikut:



Dan jika Anda mengklik dua kali di atasnya - entri lengkap:



Ketika nilai A0 mencapai nol, bendera Pules_Finished akan dinaikkan, dan mesin akan masuk ke status Pengurangan :



Dalam keadaan ini, dalam ALU, nilai akumulator A1 berkurang, yang menetapkan jumlah pulsa:



Versi lengkap dari catatan:



Bergantung pada hasilnya, transisi baik ke pulsa berikutnya atau ke kondisi Idle terjadi. Klik dua kali pada negara untuk melihat transisi dengan mempertimbangkan prioritas:



Sebenarnya, dengan UDB semuanya. Sekarang kita membuat simbol yang sesuai. Untuk melakukan ini, klik kanan pada editor dan pilih Generate Symbol :



Kami pergi ke diagram proyek:



Dan kami memperkenalkan sirkuit di mana ada sejumlah pengontrol ini. Saya memilih lima (tiga sumbu ditambah dua ekstruder). Printer dengan sejumlah besar pengekstrusi tidak akan dianggap murah. Anda dapat menempatkan FPGA pada mereka. Sepanjang jalan, untuk melihat kompleksitas sebenarnya, saya melemparkan blok USB-UART (untuk menerima data dari komputer atau Raspberry Pi yang sama) dan UART nyata (itu akan menyediakan komunikasi dengan modul Wi-Fi murah ESP8266 atau, katakanlah, layar cerdas yang dapat kirim GCODE melalui UART). Saya tidak menambahkan PWM dan sebagainya, karena kompleksitasnya kira-kira jelas, dan sistem yang sebenarnya masih jauh. Ternyata entah bagaimana seperti ini:



Register kontrol menghasilkan sinyal pemicu, yang pergi ke semua blok secara bersamaan. Selain itu, biarkan sinyal keluar darinya, yang statis selama pembentukan segmen. Saya mengumpulkan semua output Idle oleh "Dan" dan diterapkan pada input interupsi. Saya menunjuk gangguan di sisi positif. Jika setidaknya satu mesin mulai, input interupsi akan diatur ulang. Pada akhir mesin terakhir, itu akan dikokang, yang akan menginformasikan prosesor tentang kesiapan untuk kesimpulan dari segmen berikutnya. Sekarang sesuaikan frekuensinya dengan mengklik dua kali pada elemen pohon Jam :



Di tabel yang muncul, klik dua kali pada elemen PLL_OUT :



Kami akan mengisi tabel ini entah bagaimana (saya belum memahami aturan untuk menyiapkan tabel ini dengan cukup baik, itulah sebabnya saya menggunakan istilah "Sesuatu seperti itu"):



Sekarang klik dua kali pada garis Clock_1 :



Atur frekuensi clock dari blok UDB ke 48 MHz:



Karena proyek ini eksperimental, tidak masuk akal untuk membuat API untuk itu. Tetapi untuk mengkonsolidasikan materi yang dipelajari dalam artikel sebelumnya, kita kembali pergi ke tab Komponen dan untuk proyek StepperController, klik kanan melalui Tambahkan Komponen Item pertama kita menambahkan file header, dan kemudian file kode sumber C:





Saya akan menunjukkan secara dangkal dua fungsi inisialisasi dan mulai dari segmen yang saya tambahkan. Selebihnya bisa dilihat pada contoh artikel.

 void `$INSTANCE_NAME`_Start() { `$INSTANCE_NAME`_SingleVibrator_Start(); //"One" Generator start } void `$INSTANCE_NAME`_PrepareStep(int nSteps,int duration) { CY_SET_XTND_REG24(`$INSTANCE_NAME`_Datapath_1_D0_PTR, duration>92?duration-92:0); CY_SET_XTND_REG24(`$INSTANCE_NAME`_Datapath_1_D1_PTR, nSteps>1?nSteps-1:0); } 

Saya mengganti nama main.c dengan main.cpp untuk memverifikasi bahwa lingkungan pengembangan akan merespons C ++ secara normal, karena firmware Marlin berorientasi objek. Kesalahan tak terduga yang diprediksi yang dihilangkan dengan penambahan hal biasa:



Teks yang sama
 extern "C" { #include "project.h" } 


Untuk peluncuran mesin secara global, saya membuat fungsi seperti itu (sangat kasar, tetapi untuk eksperimen dengan kuda berbentuk bola dalam ruang hampa, itu akan dilakukan, dalam eksperimen waktu pengembangan lebih penting daripada keindahan):
 void StartSteppers() { Stepper_Control_Reg_Write (1); Stepper_Control_Reg_Write (1); Stepper_Control_Reg_Write (1); Stepper_Control_Reg_Write (0); } 

Dia memulai sinyal Mulai , untuk berjaga-jaga, segera untuk tiga langkah, lalu menjatuhkannya lagi.

Baiklah, mari kita mulai eksperimen. Pertama, cukup melangkahi mesin X dan Y (dalam contoh, grup panggilan pertama menginisialisasi semua pengontrol, yang kedua mengatur pengontrol X dan Y ke sejumlah langkah yang diperlukan dan memulai proses):

 int main(void) { CyGlobalIntEnable; /* Enable global interrupts. */ StepperController_X_Start(); StepperController_Y_Start(); StepperController_Z_Start(); StepperController_E0_Start(); StepperController_E1_Start(); StepperController_X_PrepareStep (10,1000); //    StepperController_Y_PrepareStep (50,500); StartSteppers(); //   for(;;) { } } 

Kami melihat hasilnya:



Periksa durasi pulsa positif:



Benar juga. Akhirnya, kami memeriksa seberapa baik interupsi bekerja. Tambahkan variabel penghitung global:

 static int nStep=0; 

Variabel ini ditugaskan untuk satu di fungsi utama , dan meningkatkan fungsi penangan interrupt. Handler interrupt akan memecat hanya sekali, murni untuk verifikasi. Saya membuatnya seperti ini:

 extern "C" { CY_ISR(StepperFinished) { if (nStep == 1) { StepperController_X_PrepareStep (5,500); StartSteppers(); nStep += 1; } } } 

Dan dalam fungsi utama , saya menambahkan dua baris: dimasukkannya interupsi dan penugasan variabel ini. Dan saya sudah menetapkan ketika mesin mulai. Kalau tidak, permintaan interupsi palsu datang. Tidak ada alasan khusus untuk melawannya sekarang. Proyek ini adalah proyek eksperimental.



Teks yang sama
 int main(void) { CyGlobalIntEnable; /* Enable global interrupts. */ isr_1_StartEx(StepperFinished); StepperController_X_Start(); StepperController_Y_Start(); StepperController_Z_Start(); StepperController_E0_Start(); StepperController_E1_Start(); /* Place your initialization/startup code here (eg MyInst_Start()) */ StepperController_X_PrepareStep (10,1000); StepperController_Y_PrepareStep (20,500); StartSteppers(); nStep = 1; for(;;) { } } 


Kami memeriksa hasilnya (pada langkah kedua hanya mesin X yang akan bekerja, dan langkah-langkahnya akan menjadi setengah lebih banyak):



Benar juga.

Kesimpulan


Secara umum, sudah jelas bahwa blok UDB dapat digunakan tidak hanya untuk mengatur fungsi perangkat keras yang cepat, tetapi juga untuk memindahkan logika dari perangkat lunak ke tingkat firmware. Sayangnya, volume artikel ternyata sangat besar sehingga tidak mungkin untuk menyelesaikan ulasan dan mendapatkan jawaban yang jelas apakah kemampuan UDB cukup untuk solusi akhir dari tugas tersebut. Sejauh ini, hanya kuda bulat yang siap dalam ruang hampa, tindakan yang pada prinsipnya sangat mirip dengan yang diperlukan, tetapi pembaca yang mengganggu akrab dengan teori kontrol motor stepper akan menemukan banyak kekurangan di dalamnya. Unit yang disajikan tidak mendukung akselerasi, yang tanpanya pengoperasian motor stepper sungguhan menjadi tidak mungkin. Sebaliknya, ini mendukung, tetapi pada tahap ini diperlukan tingkat interupsi yang tinggi, dan semuanya dirancang untuk menghindarinya.

Keakuratan pengaturan frekuensi blok yang disajikan jauh dari dapat diterima. Secara khusus, ini akan memberikan frekuensi pulsa 40.000 Hz dengan pembagi 1.200 dan 39966 Hz dengan pembagi 1201. Frekuensi menengah antara kedua nilai pada blok ini tidak dapat dicapai.

Mungkin ada beberapa kekurangan lain di dalamnya. Tetapi kita akan membahasnya di artikel berikutnya untuk memeriksa apakah ada cukup sumber daya UDB.

Sementara itu, pembaca telah menerima, antara lain, contoh nyata membuat blok berdasarkan UDB dari awal. Proyek pengujian yang diperoleh selama penulisan artikel ini dapat dilakukan di sini .

Source: https://habr.com/ru/post/id433800/


All Articles