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.

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);

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.
Belki birisi bu formdaki bağlantı noktalarını daha net bir şekilde inceleyecektir (şekilde aynı, ancak farklı bir tasarımda):

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.

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.

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

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.

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.

İstediğiniz numarayı girin:

Ve HEX'e tıklayın:

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

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:

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

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

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:

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

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.

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:

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
: