SAM3X8E (Arduino Due) Pin IO kayıtları


9

Arduino Due'ın IO kayıtları nasıl çalışır? Arduino Uno sadece set üzerinde DDRx, daha sonra PINx, okumak için PORTxben bir Arduino Due ile aynı şeyi yapmak istiyorum, yazmak için, ama gibi daha birçok kayıtlarını sahiptir PIO_OWER, PIO_OSER, PIO_CODR, PIO_SODRArduino Uno ve arasında hiçbir yazışmaları bulmak vb ben Arduino Due kayıtları.

Gibi bazı yararlı işlevler de vardır pio_clear, pio_set, pio_getve diğerleri, hepsi burada açıklanmıştır:

http://asf.atmel.com/docs/3.19.0/sam3x/html/group__sam__drivers__pio__group.html

Şimdi, bahsedilen üç fonksiyonun ne yaptığını anladığımı düşünüyorum, ancak diğerleri değil, örneğin:

pio_configure (Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)

Ne olduğunu ul_attributeve ne olduğunu anlayamıyorum ul_type.


AVR ve SAM için uygulanan bir GPIO sınıfı. Kayıtların
Mikael Patel

Yanıtlar:


7

Veri Sayfasının 31. bölümünü okuyorsanız, buradan ulaşabilirsiniz , işler sizin için biraz daha açık olabilir.

İşte bildiklerimin bir özeti:

PIO, Paralel Giriş / Çıkış anlamına gelir ve aynı anda birden çok kayıt portunu okuma ve yazma işlevi sunar. Veri sayfasında bir kayıttan bahsedildiği yerde, örneğin PIO_OWER, Arduino kütüphanesinde bunlara erişmek için makrolar vardır REG_PIO? _OWER nerede? mevcut farklı portlar için A, B, C veya D'dir.

Hala REG_PIOC_OWER = 0xdeadbeef gibi kısaltma tabanlı kayıt aramalarından daha okunabilir hale getirdiği için pinlerde giriş / çıkış ayarlamak için yavaş Arduino pinMode () işlevini kullanma eğilimindeyim, ancak daha sonra pinleri ayarlamak için doğrudan kayıtları kullanın performans / senkronizasyonu. Henüz girdi ile hiçbir şey yapmadım, bu yüzden örneklerimin tümü çıktı tabanlıdır.

Temel kullanım için çıkış hatlarını yüksek ayarlamak için REG_PIO? _SODR, düşük ayarlamak için REG_PIO? _CODR kullanırsınız. Örneğin REG_PIOC_SODR = 0x00000002, PORTC'de bit 1'i (sıfırdan sayılı) ayarlayacaktır (bu, Due dijital pim 33'tür). PORTC üzerindeki diğer tüm pimler değişmeden kalır. REG_POIC_CODR = 0x00000002, PORTC düşük bit 1'i ayarlayacaktır. Yine diğer tüm pimler değişmeden kalır.

Bu hala optimal olmadığından veya paralel verilerle senkronize edildiğinizden, bir portun 32 bitinin tümünü tek bir çağrı ile yazmanıza izin veren bir kayıt vardır. Bunlar REG_PIO? _ODSR'dir, bu nedenle REG_PIOC_ODSR = 0x00000002 artık PORTC yüksekte bit 1'i ayarlayacak ve PORTC'deki diğer tüm bitler tek bir CPU komutunda anında düşük olacaktı.

Aynı anda bir portun 32 bitini de ayarlamanız gereken bir durumda olmanız pek olası olmadığından, pinlerin mevcut değerini saklamanız, bunları gizlemek için bir AND işlemi yapmanız gerekir. değiştirmek istiyorsanız, yüksek ayarlamak istediğiniz olanları ayarlamak için bir OR işlemi gerçekleştirin, ardından yazmanızı ve tekrarlayın ve bu uygun değildir. Bunun üstesinden gelmek için, CPU'nun kendisi sizin için maskeleme yapacak. OWSR'de ayarlanan bitlerle eşleşmeyen ODSR'lere yazdığınız bitleri maskeleyecek OWSR (çıktı yazma durum kaydı) adı verilen bir kayıt vardır.

Yani, şimdi REG_PIOC_OWER = 0x00000002 (bu OWSR'nin bit 1'ini ayarlar) ve REG_PIOC_OWDR = 0xfffffffd (bu OWSR'nin bit 1 dışındaki tüm bitleri temizler) çağırır ve daha sonra REG_PIOC_ODSR = 0x00000002'yi tekrar çağırırsak, bu sefer sadece biraz değişecektir 1 PORTC ve diğer tüm bitler değişmeden kalır. Gerçeğine dikkat OWER sağlayan herhangi bit 1 olarak ayarlanır yazdığınız değer ve OWDR devre dışı bırakır herhangi bit 1 olarak ayarlanır yazdığınız değer. Bunu okuduğumda bunu anladı rağmen, hala OWDR engelli bit benim ilk test kod düşünme yazarken bir kod hata yapmak başardı değildi değer 1 olarak ayarlanmış yazdım.

Umarım bu en azından Due CPU'nun PIO'sunu anlamanız için biraz başlangıç ​​yapmıştır. Bir okuma ve bir oyun var ve başka sorularınız varsa, onlara cevap vermeye çalışacağım.

Düzenleme: Bir şey daha ...

PORT'ların hangi bitlerinin Due'ın hangi dijital hatlarına karşılık geldiğini nasıl bilebilirsiniz? Şuna bir göz at: Due Pinout


3

Temel doğrudan pim erişimi için oldukça basit bir denklik vardır. Aşağıda, bir dijital pimin yüksek ve sonra düşük ayarlanacağını gösteren bazı örnek kodlar bulunmaktadır. Birincisi Arduino Due için, ikincisi Arduino Uno / Mega / etc içindir.

const unsigned int imThePin = 10; //e.g. digital Pin 10

#ifdef _LIB_SAM_

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    Pio* imThePort = g_APinDescription[imThePin].pPort; 
    unsigned int imTheMask = g_APinDescription[imThePin].ulPin; 

    //Lets set the pin high
    imThePort->PIO_SODR = imTheMask;
    //And then low
    imThePort->PIO_CODR = imTheMask;

#else

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    volatile unsigned char* imThePort = portOutputRegister(digitalPinToPort(imThePin)); 
    unsigned char imTheMask = digitalPinToBitMask(imThePin);

    //Lets set the pin high
    *imThePort |= imTheMask;
    //Now low
    *imThePort &= ~imTheMask;

#endif

Bunu yapmak için gereken her şey varsayılan olarak dahil edilmelidir - ve eğer değilse #include <Arduino.h>oraya ulaşmak için yeterli olmalıdır.

PioAyar / temizleme / çekme dirençleri / vb. Yapmak için işaretçiye sahip olduğunuzda çağrılabilen fonksiyonlar vardır . biraz daha temiz görünümlü fonksiyon çağrıları kullanarak. Tam liste şurada bulunabilir: başlık dosyası.


0

Bu, 33 numaralı pimde bir LED'i yanıp sönen bir kod örneğidir. Kod yukarıdan ödünç alındı ​​- çok yararlı açıklamalar için çok teşekkürler :) Bu, ihtiyaç duyulan 16bit renkli piksel verilerinin dökümü ile bir TFT dokunmatik ekranla konuşmak için bir projenin başlangıcıdır. limanlara hızlı erişim. Ben kod doğru olduğunu düşünüyorum - özellikle pin düşük ayarlar hattı. Led mutlu bir şekilde yanıp sönüyor.

void setup() 
{
  pinMode(33, OUTPUT); 
  REG_PIOC_OWER = 0x00000002; 
  REG_PIOC_OWDR = 0xfffffffd; 
}

void loop() 
{
  REG_PIOC_ODSR = 0x00000002; 
  delay(1000);             
  REG_PIOC_ODSR = 0x00000000;    
  delay(1000);   
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.