kategoriler: Mikrodenetleyici devreleri
Görüntülenme sayısı: 41940
Makaleye yorum: 5

Arduino I / O portlarını okuma ve yönetme yöntemleri

 

Dış dünya ile etkileşime geçmek için mikrodenetleyicinin çıkışlarını bir sinyal alacak veya iletecek şekilde yapılandırmanız gerekir. Sonuç olarak, her pim giriş ve çıkış modunda çalışacaktır. Bunu sevdiğiniz her Arduino tahtasında yapmanın iki yolu vardır, tam olarak bu makaleden nasıl öğrendiğiniz.

Arduino I / O portlarını okuma ve yönetme yöntemleri

Birinci Yöntem - Arduino IDE için Standart Dil

Herkes biliyor Arduino Yeni başlayanlar için bazı uyarlama ve basitleştirmelerle C ++ ile programlanmıştır. Buna Kablolama denir. Başlangıçta, tüm arduino portları giriş olarak tanımlanır ve bunu kodda belirtmeye gerek yoktur.

Bağlantı noktaları genellikle değişken başlatma işlevinde yazılır:

geçersiz kurulum ()
{
// kod
}

Bunu yapmak için pinMode komutunu kullanın, oldukça basit bir sözdizimine sahiptir, önce bağlantı noktası numarasını, ardından rolünü virgülle ayırarak belirtin.

pinMode (nomer_porta, naznachenie)

Bu komutla, mikro denetleyicinin iç devresi belirli bir şekilde yapılandırılır.

Bağlantı noktasının çalışabileceği üç mod vardır: INPUT - giriş, bu modda oluşur sensörlerden veri okuma, düğme durumu, analog ve dijital sinyal. Liman sözde bulunur yüksek empedans durumu, basit bir deyişle - giriş yüksek dirence sahiptir. Bu değer, örneğin, gerekirse kartın 13 pimi aşağıdaki gibi ayarlanır:

pinMode (13, GİRİŞ);

ÇIKIŞ - çıkış, kodda belirtilen komuta bağlı olarak, bağlantı noktası bir veya sıfır değerini alır. Çıkış bir tür kontrollü güç kaynağı haline gelir ve ona bağlı yüke maksimum akım (bizim durumumuzda, tepe noktasında 20 mA ve 40 mA) üretir. Bir bağlantı noktasını Arduino'ya çıkış olarak atamak için şunları girmeniz gerekir:

pinMode (13, ÇIKIŞ);

INPUT_PULLUP - bağlantı noktası bir giriş olarak çalışır, ancak sözde ona bağlanır. 20 kΩ çekme direnci.

Bu durumda portun koşullu dahili devresi aşağıda gösterilmiştir. Bu girişin bir özelliği, giriş sinyalinin ters çevrilmiş olarak algılanmasıdır (girişteki “birim” mikrodenetleyici tarafından “sıfır” olarak algılanması). Bu modda, harici çekme dirençlerini kullanamazsınız düğmelerle çalışırken.

pinMode (13, INPUT_PULLUP);

Giriş çekme direnci

Veri portlardan alınır ve komutlarla iletilir:

  • digitalWrite (pin, değer) - çıkış pimini sırasıyla mantıksal 1 veya 0'a dönüştürür, çıkışta 5V voltaj görünür veya kaybolur, örneğin digitalWrite (13, HIGH) - 5 volt (mantıksal birim) 13 pime ve digitalWrite (13, düşük) sağlar ) - 13 pimi mantıksal sıfır durumuna (0 volt) çevirir;

  • digitalRead (pin) - girişteki değeri okur, örnek digitalRead (10), sinyali 10 pinten okur;

  • analogRead (pin) - analog bir bağlantı noktasından analog bir sinyal okur, 0 ila 1023 (10 bit ADC içinde) aralığında bir değer alırsınız, bir örnek analogRead (3) 'tür.


İkinci yöntem - Portları Atmega kayıtları ile yönetin ve kodu hızlandırın

Böyle bir kontrol elbette basittir, ancak bu durumda iki dezavantaj vardır - bağlantı noktalarıyla çalışırken daha fazla bellek tüketimi ve düşük performans. Ancak seçenek kartından (uno, micro, nano) bağımsız olarak Arduino'nun ne olduğunu hatırlıyor musunuz? Her şeyden önce, bu mikrodenetleyici AVR ailesi ATMEGA, son zamanlarda MK atmega328 kullanıldı.

Arduino IDE'de, bu aileye özgü C AVR dilini, sanki ayrı bir mikrodenetleyici ile çalışıyormuş gibi programlayabilirsiniz. Ama önce ilk şeyler. Arduino portlarını bu şekilde yönetmek için, önce aşağıdaki çizimi dikkatlice düşünmeniz gerekir.

Atmega168 Mikrodenetleyici Bağlantı Noktaları

Belki birisi bu formdaki bağlantı noktalarını daha net bir şekilde inceleyecektir (şekilde aynı, ancak farklı bir tasarımda):

Atmega328 Mikrodenetleyici Bağlantı Noktaları

Burada Arduino'nun sonuçlarının yazışmasını ve Atmega limanlarının adlarını görüyorsunuz. Yani, 3 portumuz var:

  • PORTB;

  • PORTC;

  • PORTD.

Gösterilen görüntülere dayanarak, Arduino ve Atmega limanları arasında bir yazışma tablosu hazırladım, gelecekte sizin için yararlı olacaktır.

Arduino ve Atmega limanlarının uyumluluk tablosu

Atmega'nın bağlantı noktalarının durumunu kontrol eden üç 8 bitlik kaydı vardır, örneğin, bağlantı noktası B, bu makalenin başında açıklanan standart kablolama araçlarıyla benzerlikler çizerek amaçlarını anlayacaktır:

  • PORTB - Çıktı durumunu yönetir. Pim "Çıkış" modundaysa, 1 ve 0 çıkışta aynı sinyallerin varlığını belirler. Pim “Giriş” modundaysa, 0 yüksek empedans durumundaysa (INPUT analogu) 1 ise bir yukarı çekme direnci (yukarıda tartışılan INPUT_PULLUP ile aynı) bağlar;

  • PINB bir okuma kaydıdır. Buna göre, port pinlerinin mevcut durumu (mantıksal birim veya sıfır) hakkında bilgi içerir.

  • DDRB - port yönü yazmacı. Bununla birlikte, mikro denetleyiciye bağlantı noktasının bir giriş veya çıkış olup olmadığını, “1” çıkış ve “0” giriş olduğunu belirtirsiniz.

“B” harfi yerine, bağlantı noktalarının adlarına göre başka herhangi biri olabilir, örneğin PORTD veya PORTC gibi diğer komutlar benzer şekilde çalışır.

LED'i yanıp sönüyoruz, standart digitalWrite () işlevini değiştiriyoruz. İlk olarak, Arduino IDE kütüphanesindeki orijinal örneğin neye benzediğini hatırlayalım.

Arduino yanıp sönen LED kodu

Bu, kartın içine yerleştirilmiş LED'in yanıp sönmesini gösteren iyi bilinen “yanıp sönme” kodudur.

Pin yönetimi

Yorumlar kodu açıklar. Bu çalışmanın mantığı aşağıdaki gibidir.

PORTB B00100000 komutu PB5'i mantıksal bir birim durumuna getirir, görünüm ve bu resimler ve aşağıdaki tablo bulunur ve PB5'in 13 pin Arduina'ya karşılık geldiğini görürüz.

Sayıların önündeki "B" harfi, değerleri ikili biçimde yazdığımızı gösterir. İkili olarak numaralandırma sağdan sola gider, yani. burada birim, mikro denetleyiciye bağlantı noktası B kaydının (PB5) altıncı bitinin durumu ile etkileşim hakkında bilgi veren bitin sağ kenarından altıncı bittedir. Aşağıdaki tablo D bağlantı noktasının yapısını göstermektedir, benzerdir ve örnek olarak verilmiştir.

Port D yapısı

Değeri ikili değil, onaltılık biçimde ayarlayabilirsiniz, örneğin bunun için windows hesap makinesini açıyoruz ve “GÖRÜNÜM” modunda “Programcı” seçeneğini seçiyoruz.

Windows hesap makinesi

İstediğiniz numarayı girin:

Programcı Hesaplama Modu

Ve HEX'e tıklayın:

Hesap makinesindeki sayıların çevirisi

Bu durumda, tüm bunları Arduino IDE'ye aktarıyoruz, ancak "B" öneki yerine "0x" olacaktır.

Arduino IDE'de numara transferi

Ancak bu girdi ile bir sorun var. Başka pinlere bağlı bir şey varsa, B00010000 gibi bir komut girerseniz - 13 (PB5) hariç tüm pinleri sıfırlayacaksınız. Her pin için ayrı ayrı veri girebilirsiniz. Şöyle görünecektir:

Her iğneye veri girme

Böyle bir kayıt anlaşılmaz görünebilir, hadi anlayalım.

Bir Kaydı Ayrıştırma

Bu mantıklı bir ekleme işlemidir, | = bağlantı noktasının içeriğine bir şey eklemek anlamına gelir.

Mantıksal toplama işlemi

Bu, kayıt defterine 8 bitlik bir kelime eklemeniz gerektiği anlamına gelir, ünite 5 bit kaydırılır - sonuç olarak, 11000010 110,110,010 olarak ortaya çıkarsa, bu örnekte, yalnızca PB5'in değiştiği, bu kaydın kalan bitlerinin değişmeden kaldığı görülebilir. Mikrodenetleyici pimlerinin durumu değişmeden kaldı.

Ancak mantıksal ekleme ile bir sorun ortaya çıkar - birimi sıfıra çeviremezsiniz, çünkü:

0+0=1

1+0=1

0+1=1

Mantıksal çarpma ve ters çevirme yardımımıza gelecek:

Mantıksal Çarpma ve Ters Çevirme

& =, bağlantı noktasının içeriğini belirli bir sayıyla çarpmak anlamına gelir.

 

Bağlantı noktası içeriklerini bir sayı ile çarpma

Ve bu, çarptığımız sayıdır. “~” İşareti ters çevrimi gösterir. Bizim durumumuzda, ters çevrilmiş birim sıfırdır. Yani, portun içeriğini sıfıra çarparız, 5 bit kaydırırız. Örneğin, 10110001 idi, 10100001 oldu. Geri kalan bitler değişmedi.

Bağlantı noktasının içeriğini 5 bit kaydırılarak sıfıra çarpın

Aynı işlem ters çevirme işlemi (^) kullanılarak da yapılabilir:

Bağlantı noktalarından okuma, digitalRead () analogu PIN kaydı kullanılarak gerçekleştirilir, pratikte şöyle görünür:

Bağlantı noktalarından okuma

Burada parantez içindeki ifadenin bağlantı noktalarının gerçek durumuna eşit olup olmadığını kontrol ediyoruz, yani. benzer şekilde if (digitalRead (12) == 1) yazarsak.


Sonuç

Standart uygun fonksiyonları kullanabiliyorsanız neden liman yönetiminde bu kadar zorluklar var? Her şey hız ve kod boyutu ile ilgilidir. Makalede tartışılan ikinci yöntemi kullanırken, kod boyutu önemli ölçüde azalır ve hız birkaç büyüklükte artar. Standart digitalWrite (), 1800 μs'de yürütüldü ve doğrudan bağlantı noktasına 0.2 μs'de ve digitalRead () 1900 μs'de kaydedildi ve ayrıca 0.2 μs'de oldu. Bu kontrol yöntemi ağın açık alanlarında bulunur ve genellikle kodda bulunur. bitmiş projeler.

Ayrıca bkz. electro-tr.tomathouse.com:

  • Yeni başlayanlar için Arduino'yu bağlama ve programlama
  • Arduino'ya artımlı kodlayıcı nasıl bağlanır
  • Yeni başlayanlar için PIC mikrodenetleyiciler
  • Mikrodenetleyici Uzaktan Kumanda: IR Uzaktan Kumanda, Arduino, ESP8266, 433 ...
  • Arduino'da sıcaklık ve nemin ölçülmesi - çeşitli yöntemler

  •  
     
    Yorumlar:

    # 1 şunu yazdı: Kipovets | [Cite]

     
     

    "Ancak mantıklı bir ekleme ile bir sorun ortaya çıkar - birimi sıfıra çeviremezsiniz, çünkü:

    0 + 0 = 1 "(c)

    Küçük gözetim: 0 + 0 = 0.

     
    Yorumlar:

    # 2 şunu yazdı: chugou | [Cite]

     
     

    Kipovets, muhtemelen şunları söylemek istiyordu:

    1 + 1 = 1

     
    Yorumlar:

    # 3 şunu yazdı: | [Cite]

     
     

    Kipovets,
    Banal yazım hatası! Portalımızda uzmanların oturmasının ne kadar iyi olduğunu görüyorsunuz! Sadece uygun içerikler yapmak zorundasınız!

     
    Yorumlar:

    # 4 şunu yazdı: Serg | [Cite]

     
     

    Son bölümde ise (digitalRead (12) == 1) ise PORTB | = 1 << 5 ... yazıyor. Ama B portunun 5 pimi, 13 pin arduino. Yoksa yanılıyor muyum?!

     
    Yorumlar:

    # 5 şunu yazdı: p-a-h-a | [Cite]

     
     

    (PINB == B00010000) {} değilseif (digitalRead (12) == 1) yazdığımızdakine benzer
    oldukça analog
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... ve böylece 8 port pin

    Burada şunlardan birine ihtiyacınız var:
    eğer (
    ! (~ PORTB & (1 << PB4))) {} //döner0 veya 1
    ya böyle:
    eğer (PORTB & (1 << PB4)) {} // kaydırılan birimi döndürür = 16, DEC
    ya böyle:
    eğer (
    bit_is_set (PORTB, 4)) {}// kaydırılan birimi döndürür = 16, DEC