Dapatkah masing-masing pin porta yang berbeda dari mikrokontroler dipetakan ke register dan nilainya diubah ketika mengubah nilai register?

12

T: Dapatkah masing-masing pin port yang berbeda dari mikrokontroler dipetakan ke register dan nilainya diubah ketika mengubah nilai register?

Skenario: Saya telah menggunakan beberapa pin dari setiap port (8-bit) dari micro-controller. Sekarang saya ingin menghubungkan perangkat yang membutuhkan bus 8-bit (misalkan D0 ke D7 DALAM URUTAN) artinya saya membutuhkan 8 pin dari pengontrol sehingga saya dapat menghubungkannya dalam mode satu-ke-satu

portx0  -> D0 // x is the name of port followed by bit location on that port
portx1  -> D1
...
portx7  -> D7

tetapi saya tidak memiliki seluruh port 8 pin yang dapat saya hubungkan dengan perangkat ini, tetapi saya memiliki beberapa pin dari portx, beberapa dari porty dan beberapa pin dari portz. Skenario koneksi baru adalah as (masing-masing koneksi dari mikrokontroler ke perangkat)

portx0  -> D0
portx1  -> D1
portx2  -> D2
porty4  -> D3
porty5  -> D4
porty6  -> D5
porty7  -> D6
portz1  -> D7

Dalam kondisi ini jika saya ingin mengirim nilai katakanlah

unsigned char dataReg = 0xFA;

ke perangkat saya dari controller saya harus melakukan operasi sedikit bijak pada nilai yang akan dikirim dan mengatur setiap pin sesuai dengan nilai dalam register secara individual. Sebagai contoh

portx0 = ((dataReg & 0x01) >> 0 );  // Masking and shifting as bit position
portx1 = ((dataReg & 0x02) >> 1 );
portx2 = ((dataReg & 0x04) >> 2 );
porty4 = ((dataReg & 0x08) >> 3 );
porty5 = ((dataReg & 0x10) >> 4 );
porty6 = ((dataReg & 0x20) >> 5 );
porty7 = ((dataReg & 0x40) >> 6 );
portz1 = ((dataReg & 0x80) >> 7 );

Sekarang, sampai pada pertanyaan utama, untuk menghindari kalkulasi individual ini pada setiap bit pada port yang berbeda, bisakah pin individual port yang berbeda dari mikrokontroler dipetakan ke register dan nilainya diubah ketika mengubah nilai register?

Osaid
sumber
1
Saya memiliki ide yang sama beberapa waktu lalu. Dengan PIC, ini tidak mungkin: microchip.com/forums/tm.aspx?high=&m=696277 - Saya tidak berpikir itu mungkin dengan mikro apa pun, tetapi mendaftarkan perangkat Anda akan sangat membantu.

Jawaban:

6

Tampaknya pertanyaan Anda bermuara pada memiliki nilai 8 bit di firmware, dan ingin membaca dan menulis itu dari dan ke koleksi pin port yang sewenang-wenang.

Tidak ada cara perangkat keras langsung untuk melakukan ini. Anda harus menulis dua rutinitas, satu untuk membaca nilai 8 bit dan satu lagi untuk menuliskannya. Yang lain menyebutkan menggunakan serikat pekerja, tapi itu ide yang buruk. Dengan serikat pekerja, Anda harus berurusan dengan setiap bit secara terpisah, dan kode menjadi tergantung pada urutan bit mikro. Ini mungkin cara untuk tetap pergi jika semua 8 bit tersebar sepenuhnya secara independen. Jika demikian, ada sedikit yang dapat Anda lakukan selain membuat kode khusus untuk setiap bit.

Cara yang lebih baik untuk melakukan ini, terutama jika Anda dapat mengelompokkan bit dalam beberapa potongan yang berdekatan pada port fisik adalah dengan menggunakan masking, shifting, dan ORing. Sebagai contoh, jika tiga bit rendah dari byte internal berada pada bit <6-4> dari port, geser kanan nilai port sebesar 4 dan DAN dengan 7 untuk mendapatkan bit-bit itu ke posisi akhir. Shift dan mask (atau mask dan shift) bit dari port lain ke tempatnya dan kumpulkan byte 8 bit terakhir dengan ORing hasilnya ke dalamnya.

Jenis twiddling bit level rendah ini lebih mudah dilakukan di assembler daripada C. Saya mungkin akan menempatkan byte membaca dan menulis rutin dalam modul assembler tunggal dan membuat antarmuka dapat dipanggil dari C.

Olin Lathrop
sumber
6
Jawaban saya hampir identik dengan jawaban Anda, kecuali bahwa saya tidak akan menggunakan perakitan sama sekali; manipulasi bit sepele dalam C. Saya pikir itu akan lebih dari sakit kepala (kembali) belajar konvensi pemanggilan C khusus untuk kompiler dan bagaimana menjalankan linker. Benar-benar tergantung pada kompiler dan betapa sulitnya membuat sesuatu. :-)
akohlsmith
@Andrew: Serius? Konvensi pemanggilan dengan jelas dijabarkan dalam manual kompiler yang pernah saya lihat di mana mungkin ada kebutuhan untuk berinteraksi dengan kode assembly. Manipulasi bit mungkin "sepele" untuk ditulis dalam C, tetapi ini adalah area di mana kompiler dapat menghasilkan kode yang menghebohkan. Jika kecepatan atau ruang kode tidak masalah, gunakan apa pun yang Anda sukai. Saya lebih nyaman dengan assembler untuk twiddling bit level rendah, jadi saya akan menggunakannya. Jika ini adalah rutinitas pembatasan kecepatan tingkat rendah, Anda harus melakukannya di assembler. Itu benar-benar harus mudah.
Olin Lathrop
1
Apa yang saya katakan adalah bahwa harus berurusan dengan itu untuk sesuatu yang sepele seperti manipulasi bit bukanlah sesuatu yang akan saya lakukan kecuali ada alasan yang sangat bagus untuk itu. Kita tidak tahu secara spesifik bus paralelnya, tetapi sebagian besar bus memiliki sinyal strobo yang menghilangkan perlunya pembaruan "hampir atomik" dari semua pin bus, jadi turun ke perakitan kemungkinan merupakan optimasi yang tidak perlu dan kompleksitas yang tidak dibutuhkan (bahkan jika itu adalah terus terang).
akohlsmith
@ Andrew: Itu hanya membelit atau rumit jika Anda tidak tahu apa yang Anda lakukan. Saya pikir masalah sebenarnya adalah beberapa orang takut assembler dan tidak mengetahuinya dengan baik. Itu salah. Perlu alat yang siap di kotak peralatan Anda. Jika Anda tidak mengetahuinya dengan baik atau merasa tidak nyaman dengan itu, Anda akan selalu membenarkan bagaimana segala sesuatu harus dilakukan dengan cara lain. Beberapa hal lebih mudah dalam assembler jika Anda tahu dan HLL sama baiknya. Kebanyakan orang tidak, tapi itu masalah dengan mereka, bukan dengan menggunakan assembler.
Olin Lathrop
2
Saya berpengalaman dalam bahasa assembly pada sejumlah mikrokontroler / mikroprosesor. Saya tidak setuju bahwa itu harus menjadi alat yang siap; itu harus digunakan dengan hemat dan hanya jika diperlukan, biasanya untuk inisialisasi tingkat sangat rendah, kode waktu-atau ukuran-kritis atau dalam kasus yang lebih umum, optimasi area yang telah Anda tentukan sebagai hambatan. Saya menemukan bahwa proyek di mana penulis yang melompat ke perakitan karena sering ada menulis kode yang kurang jelas atau tidak mengenali ketika suatu algoritma sedang salah diterapkan. Saya tidak secara khusus mengatakan itu adalah Anda, tetapi dalam kasus yang lebih umum.
akohlsmith
4

Secara umum ini tidak mungkin. Sejauh yang saya tahu, itu tidak mungkin dengan PICs.

Hanya ada satu mikrokontroler yang saya tahu yang bisa melakukan ini, Cypress PSoC . Ini adalah sistem yang sangat dapat dikonfigurasi pada chip. Dari banyak hal yang dapat Anda lakukan adalah mendefinisikan register Anda sendiri (1-8 bit) dan menghubungkannya ke pin yang Anda suka, atau bahkan ke sirkuit internal.

Pengkabelan PSoC

Sebagai contoh, di sini saya telah membuat register kontrol 6-bit. 5 bit langsung ke pin, sedangkan bit ke-6 saya gunakan untuk XOR dengan input dari pin ke-7.

Pin PSoC

Pada chip, saya dapat memilih untuk mengalokasikan pin ini ke salah satu pin GPIO yang tersedia. (Ini yang abu-abu satu gambar)

Roket
sumber
1
LPC800 juga harus dapat melakukannya, karena fungsi dapat ditugaskan secara bebas ke pin.
starblue
-1

Anda dapat mencoba yang berikut ini. Tulis struktur Anda sendiri yang memetakan ke pin masing-masing dari 2 port (yang akan digunakan) Sekarang memperbarui nilai dalam register ini akan mengatur / mengatur ulang pin dari 2port tersebut. Coba dan beri tahu kami jika itu berhasil !!

Saya yakin ini harus berhasil.

Rahul Ranjan
sumber
2
Di C Anda dapat memetakan struktur ke lokasi memori, dan Anda dapat memetakan bit struktur Anda (bidang bit) ke bit offset, tetapi tidak ada cara untuk mencegah kompiler dari mengacaukan bit 'inbetween', dan sekarang ada cara untuk melihat struktur 'keseluruhan' nilai integer tunggal. Ini tidak akan berhasil.
Wouter van Ooijen
-1

Jika saya memahami pertanyaan dengan benar, cukup mudah di C:

Deklarasi tipe umum, dapat digunakan kembali untuk register apa pun:

typedef union    // Generic 8-bit register Type
{
  uint8 reg; // Whole register
  struct
  {
    unsigned  bit7     : 1;  // Bit 7 
    unsigned  bit6     : 1;  // Bit 6 
    unsigned  bit5     : 1;  // Bit 5 
    unsigned  bit4     : 1;  // Bit 4 
    unsigned  bit3     : 1;  // Bit 3 
    unsigned  bit2     : 1;  // Bit 2 
    unsigned  bit1     : 1;  // Bit 1 
    unsigned  bit0     : 1;  // Bit 0 
  } bit;
} typ_GENERIC_REG8;

Jadi, untuk menentukan port yang ingin kita atasi:

#define MCU_GPO_PORTx   (*(volatile typ_GENERIC_REG8 *)(0x12345678)) // Number is address

Dan untuk secara langsung memutar pin di port itu:

#define MCU_PORTx_PINn  (MCU_GPO_PORTx.bit.bit0)

Dalam kode:

MCU_PORTx_PINn = 1; // Set pin high

Seluruh daftar:

MCU_GPO_PORTx.reg = 0xF; // All pins high

Layak dibaca pada struct, serikat pekerja, typedefs dan enum - semua ini membuat hidup jadi lebih baik dalam embedded & secara umum!

John U
sumber
OP ingin menggabungkan beberapa bit dari port yang berbeda menjadi 'satu byte'. Saya tidak melihat bagaimana ini akan melakukan itu? Olin Lathrop menjelaskan mengapa itu tidak mungkin.
Ini sebenarnya tidak mengatasi masalah ini, dan tergantung pada bagaimana "smrt" kompiler Anda, dapat menghasilkan set masalah baru untuk debug.
akohlsmith