Membuat bus bersama berperan sebagai ATAU


10

Untuk yang tidak sabar, Anda dapat melewati latar belakang.

Latar Belakang

Saya memprogram satu set mikrokontroler yang berkomunikasi dengan SPI. Ada satu tuan dan nbudak yang berbagi bus. Tidak ada chip yang dipilih. (Ini bukan desain yang buruk, tetapi nbesar dan tidak ada cukup ruang untuk njalur tambahan).

Karena itu merupakan tanggung jawab para budak untuk menjaga MISO mereka dalam impedansi tinggi dan paling banyak dari mereka berbicara. Ini dilakukan dengan merespons hanya ketika id mereka disurvei.

Sekarang kami ingin memiliki fase penemuan awal di mana master menemukan budak dengan id apa yang melekat padanya. Untuk membuat hidup lebih mudah (pada beberapa aspek), kami ingin memiliki id yang unik (dan karena itu misalnya 32 bit). Ini membuat mustahil bagi master untuk hanya mengumpulkan id satu per satu dan melihat siapa yang merespons (ada terlalu banyak kemungkinan).

Untuk mengatasi masalah ini, saya membuat variasi pencarian biner di mana budak secara kolektif merespons dan master dapat dengan cepat menemukan id minimum. Budak dengan id itu diberitahu untuk tidak berpartisipasi lagi dan algoritme berulang. (Detail tidak penting).

Tapi ada satu masalah. Respons kolektif harus logis ATAU (atau logis DAN) dari semua respons. Saya telah diberitahu bahwa saluran dapat dikonfigurasi sedemikian rupa sehingga bus MISO dapat bertindak sebagai OR logis. Yang saya tahu adalah:

  • Atur MISO pada master sebagai Pull-up dan
  • Atur MISO pada setiap budak sebagai Open-drain.

Saya sudah mencoba ini, tetapi bahkan dengan satu pun budak, konfigurasi ini tidak berfungsi (osiloskop menunjukkan nol konstan di telepon). Jika saya mengkonfigurasi MISO pada master sebagai input impedansi tinggi, saya dapat melihat dengan osiloskop bahwa tegangan turun menjadi setengah di mana bit output dari dua budak berbeda (pada dasarnya saya menganggap hubung singkat).

Catatan: mengkonfigurasi MISO pada master sebagai impedansi tinggi dan budak masing-masing sebagai push-pull, saya dapat berbicara dengan masing-masing secara individual bahkan jika ada banyak dari mereka di bus yang sama. Maksudku, aku ragu itu masalah garis itu sendiri.

Pertanyaan

Pertanyaan saya adalah, jika ini memungkinkan, dan jika demikian, bagaimana saya bisa mengkonfigurasi pin input dan output dari master dan slave sehingga garis MISO yang dibagikan akan bertindak sebagai logis OR (atau logis DAN)?


Edit

  1. Ternyata itu menjadi OR dengan logika negatif-benar (pada dasarnya AND).

  2. Masalah dengan slave tunggal diselesaikan dengan menulis 1 ke pin pull-up pada master. Sebelumnya memiliki keadaan awal 0.

Edit 2

Ternyata budak ST mengabaikan konfigurasi GPIO saya dari MISO sebagai saluran terbuka dan memaksanya tinggi ketika ada yang ditulis. Saya memutuskan untuk membungkam SPI dan mengeluarkan MISO dalam kasus khusus ini secara manual.


Saya benci bertanya, karena saya yakin Anda sudah memikirkannya, tetapi apakah Anda sudah mempertimbangkan untuk menggunakan I2C atau CAN? Mereka dirancang untuk perangkat n, sedangkan SPI benar-benar dirancang untuk digunakan dengan chip pilih untuk setiap perangkat.
Bob

@ Bob, ya. Mereka terlalu lambat. Bagaimanapun, jika jawaban atas pertanyaan saya adalah "tidak mungkin", maka kami hanya perlu melakukan sedikit pekerjaan manual, tetapi produk akhirnya masih jauh lebih baik dengan SPI.
Shahbaz

1
Sangat disayangkan bahwa Anda menggunakan 32 bit sebagai alamat karena jika Anda menggunakan 24 bit (16.772.216 variasi) Anda dapat mengirim perintah "temukan" dan tunggu 16.772.216 jam dan Anda dapat memiliki semua informasi budak Anda. Pada 10Mbps itu akan memakan waktu kurang dari 2 detik dan tidak ada bentrokan untuk mencari tahu. Hei ho - Anda membuat saya berpikir +1 untuk itu.
Andy alias

@ Andyaka, 24 bit mungkin juga tidak buruk (tapi 32 bit tentu lebih baik). jika saya memahami Anda dengan benar, maksud Anda setiap budak merespons pada jam id'th-nya dengan angka 1 dan master melihat jam mana yang menghasilkan jam? Itu tidak buruk, kecuali budak merespons dalam byte. Jadi setiap budak merespons dengan 8 bit, dan kecuali saya dapat membuat bus bertindak sebagai OR, tetap saja respons dari satu budak "hilang" di dalam respons oleh budak lain (1 dari satu budak akan ditarik ke bawah oleh 0s dari semua sisanya).
Shahbaz

@ Shahbaz jika Anda memiliki kontrol atas kode slave Anda bisa menjadikan ini "istimewa" di mana slave hanya merespons dengan 1 bit pada waktu yang dialokasikan. Ya, Anda mendapatkan intisari dari renungan saya.
Andy alias

Jawaban:


5

SPI-tanpa-pilih Anda adalah apa yang digunakan Microchip pada chip MCP23017 mereka (dan lainnya). Tidak ada yang salah dengan pendekatan itu.

Ya, apa yang Anda inginkan adalah mungkin, tetapi Anda harus membuat budak menjadi tiriskan. Anda bisa menipu dengan meletakkan dioda (schottky) secara seri dengan setiap output jika Anda tidak bisa membuatnya berperilaku sebagai tiriskan terbuka.

Pendekatan enumerasi Anda sama dengan yang digunakan oleh bus one-wire Dallas untuk enumereation, dan oleh bus CAN untuk arbitrasi.

Tetapi kelemahan serius dari pendekatan Anda adalah bahwa kecepatan sekarang dibatasi oleh waktu naik, didorong oleh resistor pull-up. Ini akan lebih lambat daripada saat digerakkan oleh output push-pull, dan kemungkinan akan membatasi kecepatan di mana Anda dapat mengoperasikan bus.

Jika Anda memiliki dua pin untuk cadangan pada setiap budak, Anda dapat membuat daisy-chain, dan memiliki skema enumerasi berdasarkan tempat mereka di rantai daisy.


Ya saya lupa menyebutkan bahwa saya juga diberitahu bahwa saya perlu mengurangi kecepatan (yang saya lakukan sekitar 20 kali lipat (turun dari 4Mpbs ke 128Kbps)). Itu adalah fase awal dan algoritma saya dapat menangani kecepatan yang lebih lambat (masih cukup cepat). Sayangnya, saya ragu kami akan mendesain ulang perangkat keras sekarang. Biaya lebih dari sekadar mengabaikan fase ini dan memberi tahu master apa yang harus diharapkan.
Shahbaz

Kembali ke pertanyaan, saya sudah mengkonfigurasi budak sebagai saluran terbuka. Bagaimana saya harus mengkonfigurasi master?
Shahbaz

1
Tidak ada yang istimewa pada pin MISO master, kecuali pullup. Saya ragu Anda akan mencapai 128Kbps dengan desain pull-up, tetapi YMMV. Membaca beberapa dokumen I2C yang mendalam bisa membantu, itu adalah bus kawat atau bus tarik, jadi setiap trik yang diterapkan di sana mungkin membantu Anda.
Wouter van Ooijen

Terima kasih banyak. Saya akan mencoba memperlambat bus lebih jauh untuk melihat apa yang terjadi. Saya kira saya akhirnya harus belajar dan mengerti apa yang dimaksud dengan pull-up, open-drain, dan yang lainnya. (Insinyur perangkat lunak di sini!)
Shahbaz

1
Letakkan osiloskop di bus dan periksa apa yang terjadi. Waktu naik mungkin terlalu lambat, tetapi mungkin juga ada dering.
Wouter van Ooijen

4
  • Atur MISO pada master sebagai Pull-up dan
  • Atur MISO pada setiap budak sebagai Open-drain.

Saya sudah mencoba ini, tetapi bahkan dengan satu pun budak, konfigurasi ini tidak berfungsi (osiloskop menunjukkan nol konstan di telepon).

Anda perlu memeriksa berapa resistansi setara pin master i / o dalam mode pull-up.

Biasanya, mode pull-up memiliki resistensi yang sangat tinggi, mungkin 50 kOhms atau lebih tinggi. Ini dimaksudkan untuk menjaga pin dari gangguan karena emi atau kebisingan lainnya, atau untuk menetapkan default untuk sinyal kontrol yang sangat lambat, dan pada saat yang sama tidak membuang terlalu banyak daya untuk melakukan itu.

Seperti yang ditunjukkan Wouter, dalam bus drain terbuka kecepatan dibatasi oleh pull-up resistor. Nilai resistor yang lebih tinggi membuat bus lebih lambat. Nilai khas dalam I2C (yang mendapat 100 atau 400 kHz) adalah 1 hingga 5 kOhms. Anda akan menginginkan resistensi pull-up yang sama untuk mencapai kecepatan yang sama.

Saya pikir Anda perlu menggunakan resistor pull-up eksternal (dari 1 sampai 5 kOhms atau lebih) daripada i / o pin pull-up master untuk membuat skema ini berfungsi.


Terima kasih atas petunjuknya. Saya bukan orang elektronik, tetapi saya harus meminta rekan kerja saya untuk melihat saran Anda. Saya memerlukan kabel-atau hanya untuk fase awal program dan pada fase normal pin tidak dikonfigurasi sebagai pull-up. Jadi mungkin resistor eksternal bukanlah suatu opsi.
Shahbaz

Jika Anda memiliki satu pin i / o gratis pada master mikro, Anda dapat menghubungkannya ke bus melalui, katakanlah, 5 kOhms. Kemudian putar tinggi saat enumerasi bus dan putar tinggi-Z selama komunikasi normal.
The Photon

1

Agar kabel dan bus berfungsi, node pada bus harus terbuka-tiriskan, yaitu mereka harus mengirimkan

  • logika rendah dengan menarik ke bawah dengan kuat, dan
  • logika tinggi dengan memutuskan koneksi dari bus.

Selanjutnya, bus harus ditarik ke atas dengan lemah.

Perilaku aneh yang Anda lihat dengan satu master yang tidak mentransmisikan dan satu budak yang mentransmisikan dapat dijelaskan baik oleh master yang menarik dengan kuat atau budak yang menarik ke bawah dengan lemah.

Anda perlu menentukan yang mana di atas yang terjadi.

Masukkan slave ke mode impedansi tinggi dan hubungkan bus ke ground melalui resistor 10k. Jika tegangan saluran tidak berubah secara signifikan, maka master menarik ke atas dengan kuat dan Anda harus memperbaikinya. Jika tidak, lakukan prosedur yang sama dengan slave (kali ini sambungkan resistor ke Vcc); jika tegangan saluran naik secara signifikan, budak menarik ke bawah dengan lemah (perbaiki itu). Jika tidak, cari distorsi ruang-waktu di area sekitar Anda.


Maafkan ketidaktahuan saya dalam bidang elektronik, tetapi jika budak itu menarik turun dengan kuat, bukankah itu membuat bus bertindak sebagai DAN? Saya katakan karena budak yang ingin tinggi memutuskan hubungan dan yang ingin rendah menarik ke bawah, sehingga hasil keseluruhan turun, bukan?
Shahbaz

@ Shahbaz, salahku, tentu saja bus akan ditransfer-dan, saya memperbaiki jawabannya. Jika Anda ingin kabel-atau, balikkan polaritasnya (master pull down dengan lemah, slave pull up dengan kuat).
avakar

Membaca di wikipedia, saya menyadari bahwa mereka menyebutnya dengan kabel-dan atau kabel-atau dengan logika negatif-benar.
Shahbaz

1

Saya akan menyarankan memiliki pull-up pasif atau pull-down di bus (saya akan menganggap pull-up), dan memiliki budak yang aktif mengemudikan bus (mengemudi tinggi dan mengemudi rendah) ketika mereka memiliki sesuatu untuk dikatakan dan mengapungkannya sebaliknya . Memiliki perintah-alamat permintaan yang mengambil alamat dan mask, dan menginstruksikan setiap budak untuk menghasilkan 00 atau tidak melakukan apa-apa (teruskan hasilnya) berdasarkan apakah ia menyukai alamat dan mask. Jika memungkinkan, minta master secara aktif mengemudikan bus beberapa waktu sebelum budak mulai mengendarainya. Bergantung pada kekuatan pull-up dan apakah master mendorong bus tinggi, sebelum slave dibiarkan menariknya rendah, mungkin perlu untuk membatasi kecepatan bus selama fase pengaturan. Di sisi lain, setelah pengaturan selesai,


Jika dua budak aktif mengemudi tinggi dan rendah, apa yang saya harapkan untuk dibaca dari bus?
Shahbaz

Seseorang harus menghindari memiliki satu budak yang mencoba mengemudi tinggi sementara yang lain mengemudi rendah. Seorang budak hanya boleh mengemudikan bus ketika (1) ia tahu itu akan menjadi satu-satunya hal yang melakukannya, atau (2) ia tahu bahwa ia dan semua orang yang mengemudikan bus akan mengendarainya ke kebalikan dari idle pasifnya. negara.
supercat

Apa artinya ini? ... memiliki setiap budak yang dipilih secara aktif menggerakkan level tinggi dan rendah akan memungkinkan bus untuk ...
Shahbaz

@ Shahbaz: Ketika seorang budak memiliki sesuatu untuk dikatakan, ia harus secara aktif mendorong bus tinggi untuk mengirimkan bit "1" dan rendah untuk mengirimkan bit "0". Ketika seorang budak tidak memiliki sesuatu untuk dikatakan, ia seharusnya tidak mengemudikan bus sama sekali. Perhatikan bahwa memiliki budak yang secara aktif mendorong bus tinggi ketika mereka ingin mengirim bit "1" akan memungkinkan bus beroperasi lebih cepat daripada mengandalkan pull-up pasif untuk mendorong bus tinggi.
supercat

@ Shahbaz: Apa supercat coba katakan, adalah bahwa dalam keadaan enumerasi, resistor harus menarik garis, dan budak hanya mengirim "0" atau tidak sama sekali (output drain terbuka), tetapi setelah itu, dalam komunikasi normal, hanya sebuah budak tunggal harus aktif pada satu waktu, dan budak yang aktif harus mengirim "0" atau "1" (output normal). Jadi resistor pull-up dan kapasitansi saluran hanya membatasi laju bit selama enumerasi. Setelah itu, dalam komunikasi normal, laju bit bisa lebih tinggi, karena memungkinkan mengemudi aktif.
Laszlo Valko
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.