Menggunakan beberapa interupsi eksternal dalam PIC

9

Saya telah menggunakan PIC16F877( lembar data ) untuk beberapa proyek. Untuk interupsi penggantian pin eksternal tunggal, Anda dapat menggunakan PORTB0interupsi. Tapi sekarang saya perlu mendukung 8 interupsi penggantian pin eksternal independen, dalam satu sirkuit.

Dalam datasheet dikatakan ada 15 interupsi PIC16F877, tetapi saya kira itu dihitung termasuk timer overflow interupsi dll ... yang tidak berguna dalam kasus ini.

Inilah yang dikatakan lembar data tentang INTCONdaftar.

masukkan deskripsi gambar di sini

Bisakah saya memiliki 4 interupsi independen menggunakan bit0 RBIF,? Ini mewakili perubahan PB7:PB4. Bagaimana saya bisa mengidentifikasi pin mana yang berubah, apakah dengan membaca nilai port dalam rutin interupsi?

Bahkan saya mendapat jawaban positif di atas, saya butuh 8 interupsi? tentu saja saya masih bisa menggunakan INTE, untuk PORTB0perubahan. Lalu 4 + 1 = 5, tapi bagaimana dengan 3 lainnya? (Namun karena semua 8 peristiwa interupsi memiliki tipe yang sama, 4 + 1 + 3 = 8masalahnya tampak jelek, bukan?)

Tidak ada tugas berat lain yang diharapkan dari mikrokontroler lain yang memantau 8 pin. (Berbicara tentang tugas-tugas lain, itu harus mempertahankan satu set variabel penghitung yang terpisah dan sering mengirimkan sekitar 4 byte ke PC secara seri)

Setiap saran dipersilahkan. Bahkan jika itu tentang mengubah mikro-controller untuk yang lebih cocok (tapi uh .. jangan bilang pergi dari PICs).

Nama kode SC
sumber
2
Tanpa menggunakan interupsi, mungkin Anda bisa memonitor pin di program utama. Tapi itu tidak sempurna. Sebagai alternatif, Anda bisa menggunakan Arduino. Meskipun bukan PIC, ini cukup sederhana, Anda akan dengan mudah mengerti karena Anda sudah terbiasa dengan PIC.
Anubis
1
Jika Anda menggunakan interupsi RBIE, Anda bisa buffer nilai sebelumnya setiap kali dan XOR untuk menemukan apa yang berubah. Seharusnya cukup cepat untuk dieksekusi.
PeterJ
@ PeterJ saya tidak begitu mengerti itu. Buffer nilai mana?
Codenamed SC
@ Peter bagus! menunggu ...
kode SC
1
Salah satu caranya adalah dengan menggunakan gerbang input 8 eksternal (seperti 74LS30 di masa lalu) untuk menggabungkan sinyal eksternal menjadi satu pin interupsi. Karena 74 (HC) 30 adalah gerbang NAND, Anda akan membutuhkan semua input tinggi dalam keadaan diam - mereka juga harus terhubung ke pin port sehingga Anda dapat mengidentifikasi gangguan mana yang aktif dengan membaca port.
Brian Drummond

Jawaban:

3

Ini adalah kode pseudo-C untuk menjelaskan satu ide. Menggunakan dan eksklusif ATAU untuk mengetahui pin mana yang telah berubah dan akan memanggil penangan Anda yang berbeda dalam satu interupsi RBIE. Bergantung pada seberapa kritisnya aplikasi ini, Anda mungkin ingin memeriksa bagaimana PIC menangani situasi seperti perubahan port saat interupsi dijalankan untuk memastikan Anda tidak akan melewatkan acara apa pun.

int old_port_b;

void isr_handler()
{
    int new_port_b, changed_pins;
    new_port_b = read_port_b();
    changed_pins = new_port_b ^ old_port_b;
    if (changed_pins | 1)
        rb0_hander();
    if (changed_pins | 2)
        rb1_hander();
        // ... etc
    old_port_b = new_port_b;
}

int main()
{
    old_port_b = read_port_b();
    enable_interrupt();
}
PeterJ
sumber
Saya mengerti, terima kasih! tapi itu bukan jawaban yang tepat yang saya cari. Dengan begitu, Anda bisa memantau RB7:RB44 pin saja. Tapi saya meminta cara untuk memonitor 8 pin. ada saran?
Kode nama SC
Saya kira ada alasan Anda tidak dapat menggunakan RB0 - RB7 di atas seharusnya bekerja? Kalau tidak, saya tidak bisa memikirkan cara, jika melakukan triger pada kode dengan cepat tidak penting, Anda bisa menggunakan gaya kode di atas dalam penghentian waktu (atau hanya loop utama).
PeterJ
Untuk PIC itu, jika Anda perlu menggunakan interupsi untuk melakukan ini, trik XOR pada RB4: RB7, dan empat interupsi untuk RB0: RB3 adalah cara yang harus dilakukan. Jika Anda tidak memerlukan interupsi, cukup polling seluruh port dalam kode Anda, atau gunakan timer interrupt untuk menangani polling jika Anda membutuhkan sample rate yang keras
Scott Seidman
and four interrupts for the RB0:RB3? PIC16F877 tidak mendukung gangguan apa pun RB1:RB3, eh?
Codenamed SC
Saya melewatkannya di lembar data, saya berasumsi itu menutupi seluruh port. Tapi saya melihat komentar Anda yang lain tentang sekali per detik jadi saya pikir Anda akan lebih baik menjalankan ini di loop utama Anda. Dengan interupsi, Anda harus menangani pemutakhiran variabel kapan saja selama eksekusi dan bagaimana menangani perubahan pin saat interupsi berjalan. Itu benar-benar terdengar seperti itu hanya akan mempersulit tanpa keuntungan nyata. Satu-satunya pengecualian yang bisa saya pikirkan adalah jika Anda ingin menggunakan wake from sleep pada interrupt, dalam hal ini Anda perlu MUX hardware mereka.
PeterJ
1

Bagian itu hanya memiliki 4 interupsi perubahan pin dan beberapa lainnya yang dapat Anda atur di tepi yang dipilih. Salah satu strategi adalah mendeteksi perubahan dalam nilai 8 bit secara eksternal, kemudian menyela ketidakcocokan. Itu menjadi berantakan di perangkat keras, tetapi akan jadi apa yang Anda inginkan.

Parameter penting yang belum Anda nyatakan adalah seberapa cepat Anda perlu merespons perubahan pin, dan berapa waktu minimum perubahan pin akan tetap berlaku. Tergantung pada jawabannya, Anda dapat memilih berdasarkan interupsi reguler dalam firmware. 16F877 dapat berjalan pada kecepatan instruksi 5 MHz, dan memeriksa perubahan hanya akan membutuhkan beberapa instruksi. Katakanlah Anda mengatur interupsi setiap 50 instruksi. Itu akan menyisakan sebagian besar waktu prosesor untuk kode latar depan. Tingkat interupsi akan menjadi 100 kHz dan periode 10 μs. Tentu saja kode latar depan masih perlu melihat bendera perubahan dan melakukan sesuatu tentang hal itu, sehingga waktu respons akan lebih dari 10 μs, tetapi Anda belum mengatakan apa-apa tentang apa yang perlu Anda lakukan ketika perubahan terdeteksi. Jika ini hanya perlu merespons dalam waktu manusia,

Olin Lathrop
sumber
Maaf tentang detail yang hilang. Karena tingkat respons yang diharapkan once per secondakan cukup. Ketika perubahan pin (hanya satu sisi, katakan naik) terdeteksi, penghitung (variabel) harus ditambahkan. Pada loop utama, ia harus memonitor nilai penghitung dan ketika seseorang mendapatkan lebih tinggi dari nilai tertentu, empat byte harus ditransmisikan melalui USARTPC. Kemudian atur ulang nilai penghitung yang relevan ke nol. Sederhana seperti itu. Saya kira opsi pemungutan suara akan berjalan dengan baik bukan?
Codenamed SC
2
Sekali per detik ! Jadi untuk apa semua susah selama interupsi? Ini mudah dilakukan dengan pemungutan suara secara berkala. Lalu apa masalahnya?
Olin Lathrop
um ... saya pikir itu akan menjadi yang terbaik karena ada 8 dari mereka dan juga, respon tidak dapat diprediksi (tetapi nilai itu dapat dianggap sebagai minimum). Hei! orang bisa melakukan kesalahan, benar .. :(
Kode nama SC
1

Anda dapat menggunakan gerbang input 8-NAND seperti yang disebutkan oleh @Brian Drummond untuk meningkatkan interupsi atas pin INT dan juga menghubungkan sumber interupsi Anda ke 8-Bit Parallel-In / Serial-Out Shift Register seperti "74HC165N", jadi Anda perlu hanya membaca data dari Shift Register itu setelah interupsi naik dan yang akan memberi Anda informasi tentang sumber interupsi Anda yang sebenarnya ... ini mungkin bukan cara tercepat, tetapi mudah diperluas dan akan menggunakan tidak lebih dari 5 pin, dan jika Anda menambahkan sistem pengontrol alamat (MUX, LATCH, ...), maka Anda hanya perlu satu pinus untuk pemberitahuan interupsi dan pin lainnya dapat digunakan kembali pada waktu yang berbeda untuk sumber daya yang berbeda;)

Eli Oulman
sumber