Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 9371|Yanıt: 0

Zigbee Yolculuğu (9): Birkaç önemli temel CC2430 deneyi - sistematik uyku ve kesintili uyanıklık

[Bağlantıyı kopyala]
Yayınlandı 30.10.2014 23:24:30 | | | |
1. Üst ve alt katların birbirine bağlanması

Bu makalede, CC2430'un uyku fonksiyonu ve uyanış yöntemini ele alacağız. Gerçek kullanımda, CC2430 düğümü genellikle pillerle beslenir, bu nedenle güç tüketiminin kontrolü çok önemlidir.

Aşağıda, CC2430'un 4 güç tüketimi modunun tanıtımı için CC2430 Çin kılavuzundan bir alıntı verilmiştir:

Yukarıdaki tablodan da görebileceğiniz gibi, CC2430'un toplamda 4 güç modu vardır:PM0(tamamen uyanık),PM1(biraz uykulu),PM2(yarı uyanık, yarı uykulu),PM3(Çok derin uyuyor). Ne kadar geriye giderseniz, o kadar çok fonksiyon kapalı olur ve güç tüketimi giderek azalır. Aralarındaki dönüşüm ilişkisi şöyledir:

putPM1、PM2UyandırPM0, üç yol vardır: sıfırlama, dış kesinti, uyku zamanlayıcısının kesintisi; AmaPM3UyandırPM0, sadece iki yol vardır: sıfırlama, harici kesinti (çünkü içindePM3Tüm osilatörler çalışmayı durdurdu ve tabii ki uyku zamanlayıcısı kapandı~)

Uyku moduna nasıl geçileceğini ve nasıl uyanacağımızı tanıtmak için küçük bir deney yapalımPM0Eyalet.

2. Sistematik uyku ve kesintili uyanış deneyleri(1) Deneye girişsistem başlatma, içindePM0
→ GirişPM1
→ 1 saniye sonra uyku zamanlayıcısına uyanmakPM0
→ GirişPM2
→ uyku zamanlayıcısıyla 2 saniye sonra uyandıPM0
→ GirişPM3
→ S1 tuşuna basılana kadar bekleyin, bu da harici bir kesintiye tetiklenip uyanmanıza neden olurPM0
(2) Program akış şeması

(Not: Yukarıdaki görseldeki yuvarlak kutu sistemin sağlık durumunu gösterir)

(3) Deneysel kaynak kodu ve analiz (Aşağıdaki kutulara tıklanabilir~Başlık dosyası ve makro tanımı[url=] [/url]
/*
    Deneysel açıklama: Üç uyku modunda uyanıklığı tanıtan kesintili uyanış uykusu deneyi
*/

#include
#define LED_ON 0
#define LED_OFF 1#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   [url=] [/url]

Alt fonksiyonlar[url=] [/url]
/*Sistem saat başlatma
-------------------------------------------------------
*/
Voidxtal_init(Void)
{
  UYKU &= ~0x04;            //Hepsi elektrikli
  while(! (UYKU &0x40));     //Kristal osilatör açık ve sabit.
  CLKCON &= ~0x47;         //32MHz kristal osilatör seçin
  UYKU |=0x04;
}


/*LED başlatma
-------------------------------------------------------
*/
Voidled_init(Void)
{
  P1SEL =0x00;         //P1 normal I/O portudur
  P1DIR |=0x0F;         //P1.0 P1.1 P1.2 P1.3 çıkışı
  
  led1 = LED_OFF;         //Tüm LED'leri kapatın
  led2 = LED_OFF;
  led3 = LED_OFF;
  led4 = LED_OFF;
}


/*Dış kesinti başlatma
-------------------------------------------------------
*/
Voidio_init(Void)
{
    P0INP &= ~0X02;   //P0.1'de hem pull-up hem de pull-down var

    EA =1;           //Toplam kesintiye izin verildi
   
    IEN1 |=  0X20;   //P0IE = 1, P0 kesintileri etkinleştir
   
    PICTL |=  0X09;   //P0.1 kesintiler, kenar tetikleyicileri ve düşürme tetikleyicilerine izin verir
   
    P0IFG &= ~0x02;   //P0.1 Kesme işareti clear0
}


/*Uyku zamanlayıcı kesintisi başlatma
-------------------------------------------------------
*/
VoidsleepTimer_init(Void)
{
  STIF=0;   //Uyku zamanlayıcısı kesme işareti 0 temiz
   
  STIE=1;   //Uyku zamanlayıcısını aç kesinti
   
  EA=1;     //Tam kesintiyi aç
}


/*Uyku zamanlayıcısı için planlanmış aralık ayarla
-------------------------------------------------------
*/
VoidsetSleepTimer(imzasızintsec)
{
  imzasızuzunsleepTimer =0;
  
  sleepTimer |= ST0;                     //Mevcut uyku zamanlayıcısının sayım değerini alın
  sleepTimer |= (imzasızuzun)ST1 <<8;
  sleepTimer |= (imzasızuzun)ST2 <<16;
  
  sleepTimer += ((işaretsizuzun)sec * (imzasızuzun)32768);   //Bir de gerekli zamanlama süresi
  
  ST2 = (işaretsizchar)(sleepTimer >>16);   //Uyku zamanlayıcısının karşılaştırma değerini ayarlayın
  ST1 = (imzasızchar)(sleepTimer >>8);
  ST0 = (imzasızchar)sleepTimer;
}


/*Güç Modu Seç
-------------------------------------------------------
*/
VoidPowerMode(imzasızcharmod)
{
  eğer(mod <4)
  {
    UYKU &=0xfc;      //SLEEP.MODE'u 0'a temizle
    UYKU |= modu;      //Güç Modu Seç
    PCON |=0x01;        //Bu güç modunu etkinleştirin
  }
}


/*Gecikme fonksiyonu
-------------------------------------------------------
*/
VoidGecikme(imzasız)intn)
{
  imzasızinti,j;
  için(i=0; i<n; i++)
    için(j=0; j <1000; j++);
}
[url=] [/url]

Ana işlev[url=] [/url]
/*Ana işlev
-------------------------------------------------------
*/
Voidmain(Void)
{
  xtal_init();         
  led_init();         
  
  //PM0 durumu, ışık açık ve gecikme
  led1 = LED_ON;         //Parlaklık LED1, sistemin PM0 modunda çalıştığını gösterir
  Gecikme(10);


  //PM1 durumu, ışıklar kapalı
  setSleepTimer(1);      //Uyku zamanlayıcısının zaman aralığını 1s olarak ayarlayın
  sleepTimer_init();     //Uyku zamanlayıcısını aç kesinti
  led1 = LED_OFF;
  PowerMode(1);         //Güç modunu PM1'e ayarlayın
  
  
//1 saniyeden sonra PM1 PM0'a giriyor, ışıklar ve gecikmeler
  led1 = LED_ON;
  Gecikme(50);
  
  //PM2, ışıklar kapanıyor
  setSleepTimer(2);      //Uyku zamanlayıcısının zaman aralığını 2 saniyeye ayarlayın
  led1 = LED_OFF;
  PowerMode(2);         //Güç modunu PM2'ye ayarlayın


  
//2 saniye sonra PM2 PM0'a giriyor, ışıklar ve gecikmeler oluyor
  led1=0;
  Gecikme(50);
  
  //PM3, ışıklar kapanıyor  
  io_init();            //Dış kesintileri başlatma
  led1 = LED_OFF;
  PowerMode(3);         //Güç modunu PM3'e ayarlayın
  
  
//Dış bir kesinti olduğunda, PM3 PM0'a girer ve ışık yanır
  led1 = LED_ON;

  while(1);
}
[url=] [/url]

Kesinti hizmeti prosedürleri[url=] [/url]
/*Harici kesinti servis programı
-------------------------------------------------------
*/
#pragmavektör = P0INT_VECTOR
__interruptVoidP0_ISR(Void)
{
  EA =0;                        //Kapı kesintiye girdi
  
  Gecikme(50);

  eğer((P0IFG &0x02) >0)         //Tuşlar kesiliyor
  {
    P0IFG &= ~0x02;               //P0.1 Kesme işareti clear0
  }
  P0IF =0;                       //P0 kesme işareti clear0


  EA =1;                        //Açık kesinti
}


/*Uyku zamanlayıcısı servis programlarını kesintiye uğratıyor
-------------------------------------------------------
*/
#pragmavektör= ST_VECTOR
__interruptVoidsleepTimer_IRQ(Void)
{
  EA=0;     //Kapı kesintiye girdi
   
  STIF=0;   //Uyku zamanlayıcısı kesme işareti 0 temiz
  
  EA=1;     //Açık kesinti
}
[url=] [/url]

Sistemi uyandırmak için uyku zamanlayıcısının nasıl kullanılacağı şu şekilde özetlenebilir:Uyku zamanlayıcısı kesintisini açın → uyku zamanlayıcısının zaman aralığını ayarlayın → güç modunu ayarlayın

(Not: "Uyku Zamanlayıcı Aralığını Ayarlayın" adımı "Güç Modu Ayarlan"dan önce olmalıdır, çünkü sistem uyku rejimine girdikten sonra programı çalıştırmaya devam etmez)

Sonra, uyku zamanlayıcı aralığını ayarlayan alt fonksiyona odaklanalım:setSleepTimer

Öncelikle, uyku zamanlayıcısına kısa bir giriş: çalışarak devam ediyor32.768kHzof24. sıraZamanlayıcı, sistem çalışırkenPM3'e ek olarakTüm güç modlarında, uyku zamanlayıcısıKesintisiz çalışma

Uyku zamanlayıcıları tarafından kullanılan kayıtlar şunlardır:ST0ST1ST2。 Aşağıda, CC2430 Çin el kitabından işlevlerine dair ayrıntılı bir giriş verilmiştir:

Fonksiyonlarının iki yönü içerdiği görülebilir:Okuyaz

  Oku: Mevcut zamanlayıcının sayım değerini okumak için kullanılır, okumaların takip edilmesi gereken sıra:ST0 Oku → ST1'i Oku → ST2'yi Oku

  yaz: Zamanlayıcının karşılaştırma değerini ayarlamak için kullanılır (zamanlayıcının sayı değeri = karşılaştırma değeri olduğunda bir kesme oluşur), yazı sırası şöyle olmalıdır:ST2 yaz → ST1 yaz → ST0 yaz

Tamam, bunu kaynak koduyla birlikte açıklayalım:

(1) Öncelikle, uyku zamanlayıcısının mevcut sayım değerini almak için işaretsiz uzun değişken (32-bit) bir sleepTimer tanımlayın:

  imzasızuzunsleepTimer =0;
  
  sleepTimer |= ST0;                     //Mevcut uyku zamanlayıcısının sayım değerini alın
  sleepTimer |= (imzasızuzun)ST1 <<8;
  sleepTimer |= (imzasızuzun)ST2 <<16;

(2) Sonra gerekli zaman aralığını ekleyin:

  sleepTimer += ((işaretsizuzun)sec * (imzasızuzun)32768);   //Bir de gerekli zamanlama süresi

İşte küçük bir açıklama:

1'ler neden 32768'i temsil ediyor? Zamanlayıcı 32.768kHz'in altında çalıştığı için, zamanlayıcıya eklenen her 1 saniye için 1/32768 saniye alır; 32768 ekleyin, 1'lere ihtiyacınız olacak;

(3) Son olarak, zamanlayıcının karşılaştırma değeri olarak sleepTimer değeri kullanılır:

  ST2 = (işaretsizchar)(sleepTimer >>16);   //Uyku zamanlayıcısının karşılaştırma değerini ayarlayın
  ST1 = (imzasızchar)(sleepTimer >>8);
  ST0 = (imzasızchar)sleepTimer;

Bu şekilde, zamanlayıcının zamanlama süresini başarıyla ayarlayabilirsiniz~

(Not: Kaynak kodun diğer bölümlerine gelince, ayrıntılı açıklamalarla birlikte kolayca anlaşılabileceğinize inanıyorum ve burada tekrar etmeyeceğim)

(4) Deneysel sonuçlar
Programı çalıştırırken, LED1'i gözlemlerken, fenomen şöyledir:LED1 yanıp sönüyor (yani, 1 kez açık > kapalı), 1 saniye sonra tekrar yanıp sönüyor, 2 saniye sonra tekrar yanıp söner, sonra kapalı kalır ve S1 tuşuna basılır, LED1 yanır.
Deneysel olgu, Over~ beklentisiyle tamamen tutarlıdır

3. Sonuç

Ah~ İki gün boş vakit ayırdıktan sonra sonunda bu günlüğü aldım. Bir blog yazmanın, özellikle "okuyucu dostu" bir blog yazısının gerçekten fiziksel bir iş olduğunu fark ettim: titizlik, estetik, mantık... Her şey düşünceyle ilgili.

Her kodu paylaştığımda çok uzun olduğunu düşünüyorum ama blog bahçesiyle birlikte gelen katlama aracını kullanmaya isteksizim. Bu nedenle, bu blog yazısında yazar kodun düzgün katlanması için bazı JQuery öğeleri ekledi ve hâlâ küçük bir başarı hissi var, hehe (JQuery acemi, ustaya gülme~). Ama bunun makalenin okunabilirliğini gerçekten artırıp artırmadığını bilmiyorum ve okuyucular ile arkadaşlar yorum yapabilir :)

Bu ay, yazar gerçekten blog bahçesinde kök salmaya karar verdi, bu yüzden bolca boş zamanımı blog yazıları yazmaya harcadım. İlk kez blog yazdığımda, yorum çok az olmasına rağmen, çoğu logun tıklama oranı 500'ün üzerindeydi, bu da benim için küçük bir cesaret kaynağıydı! Blog bahçesinde mikrodenetleyicilerle ilgili içerik yayınlamak cesaret gerektiriyor ama ben buna sadık kalacağım~

Başından günümüze kadar dokuz blog yazısı, CC2430 çipinde temel donanım modüllerinin kullanımına odaklanmaktadır. Şu ana kadar CC2430'daki çoğu çevre birimini inceledik, ancak Flash erişimi, rastgele sayı üreteci, AES yardımcı işlemcisi, RF iletişimi gibi konulara hâlâ değinilmemiş konular var. Ancak, Zigbee yolculuğu henüz bitmedi ve yazar, bu eksiklikleri bir sonraki konuda (Z-Stack protokolünün uygulanması) seçici olarak doldurmayı planlıyor.

Bir sonraki blog yazısında, Zigbee'nin ilk gezisini biraz daha kapsamlı ve genişletilmiş bir deneyle - "sıcaklık izleme sistemi" - bitirmeyi ve daha önce öğrendiğim bilgiyi kapsamlı şekilde nasıl uygulayabileceğimizi açıklamayı planlıyorum.

Aslında, "AçıklamaYeni başlayan biri olarak, yazar sadece birbirlerini teşvik etmeyi ve doktora yazma sürecinde birlikte ilerleme kaydetmeyi umuyordu!


</n; i++)




Önceki:Zigbee Yolculuğu (8): Birkaç önemli CC2430 temel deneyi - gözcüler
Önümüzdeki:Zigbee Yolculuğu (10): CC2430 temelli kapsamlı deney - Sıcaklık izleme sistemi
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com