Kategori: Litar mikropengawal
Bilangan pandangan: 41940
Komen pada artikel: 5

Kaedah untuk membaca dan mengurus port Arduino I / O

 

Untuk berinteraksi dengan dunia luar, anda perlu mengkonfigurasi output mikropengawal untuk menerima atau menghantar isyarat. Akibatnya, setiap pin akan berfungsi dalam mod input dan output. Terdapat dua cara untuk melakukan ini pada setiap papan Arduino yang anda suka, tepat bagaimana anda belajar dari artikel ini.

Kaedah untuk membaca dan mengurus port Arduino I / O

Kaedah Satu - Bahasa Standard untuk Arduino IDE

Semua orang tahu itu Arduino Ia diprogramkan dalam C ++ dengan beberapa penyesuaian dan penyederhanaan untuk pemula. Ia dipanggil Pendawaian. Pada mulanya, semua pelabuhan arduino ditakrifkan sebagai input, dan tidak perlu menentukan ini dalam kod.

Pelabuhan biasanya ditulis dalam fungsi penyesuaian ubahsuaian:

batal persediaan ()
{
// kod
}

Perintah pinMode digunakan untuk ini, ia mempunyai sintaks yang agak mudah, terlebih dahulu nombor port ditunjukkan, maka peranannya dipisahkan oleh koma.

pinMode (nombor_porta, naznachenie)

Dengan arahan ini, litar dalaman mikrokontroler dikonfigurasi dengan cara tertentu.

Terdapat tiga mod di mana pelabuhan boleh berfungsi: INPUT - input, dalam mod ini berlaku membaca data dari sensor, status butang, isyarat analog dan digital. Pelabuhan itu terletak dalam apa yang dipanggil tinggi impedans keadaan, dengan kata-kata mudah - input mempunyai rintangan yang tinggi. Nilai ini ditetapkan, sebagai contoh, 13 pin lembaga, jika perlu, seperti berikut:

pinMode (13, INPUT);

OUTPUT - output, bergantung pada arahan yang ditetapkan dalam kod, port mengambil nilai satu atau sifar. Output menjadi sejenis sumber kuasa terkawal dan menghasilkan arus maksimum (dalam kes kita, 20 mA dan 40 mA pada puncak) kepada beban yang disambungkan kepadanya. Untuk menetapkan pelabuhan sebagai output kepada Arduino, anda perlu memasukkan:

pinMode (13, OUTPUT);

INPUT_PULLUP - port berfungsi sebagai input, tetapi apa yang dipanggil menghubungkannya. 20 kΩ pull-up resistor.

Litar dalaman bersyarat pelabuhan di negeri ini ditunjukkan di bawah. Satu ciri input ini adalah bahawa isyarat input dianggap sebagai terbalik ("unit" pada input dilihat oleh mikrokontroler sebagai "sifar"). Dalam mod ini, anda tidak boleh menggunakan perintang tarik luaran semasa bekerja dengan butang.

pinMode (13, INPUT_PULLUP);

Perintang penarik input

Data diterima dari pelabuhan dan dihantar kepada mereka oleh perintah:

  • digitalWrite (pin, nilai) - menukarkan pin output kepada logik 1 atau 0, masing-masing, voltan 5V muncul atau hilang pada output, misalnya digitalWrite (13, HIGH) - membekalkan 5 volt (unit logik) kepada 13 pin dan digitalWrite ) - menterjemahkan 13 pin ke dalam keadaan sifar logik (0 volt);

  • digitalRead (pin) - membaca nilai dari input, contoh digitalRead (10), membaca isyarat daripada 10 pin;

  • analogRead (pin) - membaca isyarat analog dari port analog, anda mendapat nilai dalam julat dari 0 hingga 1023 (dalam ADC 10-bit), contoh adalah analogRead (3).


Kaedah dua - mengurus pelabuhan melalui daftar Atmega dan mempercepatkan kod

Kawalan itu sememangnya mudah, tetapi dalam kes ini terdapat dua kekurangan - penggunaan memori yang lebih besar dan prestasi yang lemah apabila bekerja dengan pelabuhan. Tetapi ingat apa yang Arduino, tanpa mengira papan pilihan (uno, mikro, nano)? Pertama sekali, ini mikropengawal keluarga AVR ATMEGA, baru-baru ini digunakan MK atmega328.

Dalam Arduino IDE, anda boleh program dalam bahasa ibunda untuk keluarga C AVR ini, seolah-olah anda bekerja dengan mikrokontroler berasingan. Tetapi perkara pertama yang pertama. Untuk menguruskan pelabuhan Arduino dengan cara ini, anda perlu terlebih dahulu mempertimbangkan ilustrasi berikut.

Pelabuhan Mikrokontroler Atmega168

Mungkin seseorang akan lebih jelas meneliti pelabuhan dalam bentuk ini (sama dalam angka itu, tetapi dalam reka bentuk yang berbeza):

Pelabuhan Mikrokontroler Atmega328

Di sini anda melihat surat-menyurat kesimpulan Arduino dan nama-nama pelabuhan atmega. Oleh itu, kami mempunyai 3 port:

  • PORTB;

  • PORTC;

  • PORTD.

Berdasarkan imej yang ditunjukkan, saya menyusun jadual surat-menyurat antara pelabuhan Arduino dan Atmega, ia akan berguna untuk anda pada masa akan datang.

Jadual kesepakatan pelabuhan Arduino dan Atmega

Atmega mempunyai tiga daftar 8-bit yang mengawal keadaan pelabuhan, contohnya, port B akan memikirkan tujuan mereka dengan melukis analogi dengan alat pendawaian standard yang diterangkan pada awal artikel ini:

  • PORTB - Menguruskan status output. Jika pin berada dalam mod "Output", maka 1 dan 0 menentukan kehadiran isyarat yang sama pada output. Jika pin berada dalam mod "Input", maka 1 menghubungkan perintang tarik (sama dengan INPUT_PULLUP dibincangkan di atas), jika 0 adalah keadaan impedans tinggi (analog INPUT);

  • PINB adalah daftar baca. Oleh itu, ia mengandungi maklumat mengenai keadaan semasa pin pelabuhan (unit logik atau sifar).

  • DDRB - arahan arah port. Dengan itu, anda menunjukkan kepada mikrokontroler apa port sebagai input atau output, dengan "1" output dan "0" input.

Daripada huruf "B", mungkin ada yang lain mengikut nama-nama pelabuhan, contohnya, PORTD atau PORTC perintah lain bekerja sama.

Kami mengedipkan LED, menggantikan fungsi digitalWrite () standard. Pertama, mari kita ingatkan semula contoh asal dari pustaka Arduino IDE.

Kod LED berkelip Arduino

Ini adalah kod "berkedip" yang terkenal, yang menunjukkan berkelip LED dibina ke dalam papan.

Pengurusan pin

Komen tersebut menerangkan kod. Logik kerja ini adalah seperti berikut.

Perintah PORTB B00100000 meletakkan PB5 dalam keadaan unit logik, lihat, dan gambar-gambar dan jadual di bawah ini terletak dan kita melihat bahawa PB5 sepadan dengan 13 pin Arduina.

Huruf "B" di depan angka menunjukkan bahawa kita sedang menulis nilai dalam bentuk binari. Penomboran dalam binari pergi dari kanan ke kiri, iaitu di sini unit berada di bit keenam dari tepi kanan bit, yang memberitahu mikrokontroler tentang interaksi dengan keadaan bit keenam pelabuhan B mendaftar (PB5). Jadual di bawah menunjukkan struktur port D, ia sama dan diberikan sebagai contoh.

Struktur D D

Anda boleh menetapkan nilai bukan dalam binari, tetapi dalam bentuk heksadesimal, sebagai contoh, untuk ini kita membuka kalkulator tingkap dan dalam mod "VIEW", pilih pilihan "Programmer".

Kalkulator Windows

Masukkan nombor yang dikehendaki:

Mod Kalkulator Programmer

Dan klik pada HEX:

Terjemahan nombor pada kalkulator

Dalam kes ini, kami memindahkan semua ini ke IDE Arduino, tetapi bukan awalan "B" ia akan menjadi "0x".

Nombor pemindahan dalam Arduino IDE

Tetapi dengan input ini ada masalah. Jika anda mempunyai apa-apa yang berkaitan dengan pin lain, kemudian masukkan arahan seperti B00010000 - anda akan menetapkan semula semua pin kecuali 13 (PB5). Anda boleh memasukkan data untuk setiap pin secara individu. Ia akan kelihatan seperti ini:

Memasukkan data ke dalam setiap pin

Rekod sedemikian rupa mungkin tidak dapat difahami, katakanlah.

Parsing a Record

Ini adalah operasi penambahan logik, | = bermakna menambahkan sesuatu kepada kandungan port.

Operasi penambahan logik

Ini bermakna anda perlu menambah perkataan 8 bit dalam daftar dengan satu unit yang ditukar dengan 5 bit - sebagai hasilnya, jika 11000010 ternyata menjadi 110,110,010. Dalam contoh ini, dapat dilihat bahawa hanya PB5 telah berubah, baki bit dari daftar ini tetap tidak berubah, serta Keadaan pin mikropengawal kekal tidak berubah.

Tetapi dengan penambahan logik, masalah timbul - anda tidak boleh mengubah unit menjadi sifar, kerana:

0+0=1

1+0=1

0+1=1

Pendaraban logik dan penyongsangan akan datang kepada kami:

Logik Pendaraban dan Inverting

& = bermaksud melipatgandakan kandungan pelabuhan dengan nombor tertentu.

 

Mengalikan kandungan port dengan nombor

Dan ini adalah bilangan yang kita banyakkan. Tanda "~" menunjukkan penyongsangan. Dalam kes kami, unit terbalik adalah sifar. Iaitu, kami melipatgandakan kandungan pelabuhan dengan sifar, beralih sebanyak 5 bit. Sebagai contoh, ia adalah 10110001, ia menjadi 10100001. Bit yang tinggal kekal tidak berubah.

Maju kandungan port dengan nol yang dialihkan oleh 5 bit

Perkara yang sama boleh dilakukan dengan menggunakan operasi terbalik (^):

Membaca dari port, analog digitalRead () dilakukan menggunakan register PIN, dalam praktiknya kelihatan seperti ini:

Baca dari pelabuhan

Di sini kita periksa sama ada ungkapan dalam kurungan sama dengan keadaan sebenar pelabuhan, iaitu. sama seperti jika kita menulis jika (digitalRead (12) == 1).


Kesimpulannya

Mengapa terdapat kesulitan seperti pengurusan pelabuhan jika anda boleh menggunakan fungsi standard yang sesuai? Ini semua tentang kelajuan dan saiz kod. Apabila menggunakan kaedah kedua, dibincangkan dalam artikel itu, saiz kod dikurangkan dengan ketara, dan kelajuannya meningkat dengan beberapa pesanan magnitud. DigitalWrite standard () telah dilaksanakan pada 1800 μs, dan merakam terus ke port dalam 0.2 μs, dan digitalRead () pada 1900 μs, dan juga menjadi 0.2 μs. Kaedah kawalan ini didapati pada ruang terbuka rangkaian dan sering dijumpai dalam kod. projek siap.

Lihat juga di i.electricianexp.com:

  • Menyambung dan pengaturcaraan Arduino untuk pemula
  • Bagaimana untuk menyambung pengekod tambahan kepada Arduino
  • PIC microcontrollers untuk pemula
  • Kawalan Jauh Mikrocontroller: IR Remote, Arduino, ESP8266, 433 ...
  • Mengukur suhu dan kelembapan pada Arduino - pilihan cara

  •  
     
    Komen:

    # 1 menulis: Kipovets | [quote]

     
     

    "Tetapi dengan penambahan logik, timbul masalah - anda tidak dapat mengubah unit menjadi sifar, karena:

    0 + 0 = 1 "(c)

    Pengawasan kecil: 0 + 0 = 0.

     
    Komen:

    # 2 menulis: chugou | [quote]

     
     

    Kipovets, dia mungkin mahu berkata:

    1 + 1 = 1

     
    Komen:

    # 3 menulis: | | [quote]

     
     

    Kipovets,
    Kesalahan palsu! Anda melihat betapa baiknya pakar yang duduk di portal kami! Anda hanya perlu membuat kandungan yang sesuai!

     
    Komen:

    # 4 menulis: Serg | [quote]

     
     

    Di bahagian akhir ia mengatakan PORTB | = 1 << 5 ... jika (digitalRead (12) == 1). Tetapi 5 pin port B, ia adalah 13 pin arduino. Atau saya salah?

     
    Komen:

    # 5 menulis: p-a-h-a | [quote]

     
     

    Jika (PINB == B00010000) {} tidaksama seperti jika kita menulis jika (digitalRead (12) == 1)
    agak analog
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... dan sebagainya 8 port pins

    Di sini anda perlu sama ada ini:
    jika (
    ! (~ PORTB & (1 << PB4))) {} //pulangan0 atau 1
    sama seperti ini:
    jika (PORTB & (1 << PB4)) {} // mengembalikan unit beralih = 16, DEC
    sama seperti ini:
    jika (
    bit_is_set (PORTB, 4)) {}// mengembalikan unit beralih = 16, DEC