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

Görünüm: 10835|Yanıt: 1

Zigbee Yolculuğu (10): CC2430 temelli kapsamlı deney - Sıcaklık izleme sistemi

[Bağlantıyı kopyala]
Yayınlandı 30.10.2014 23:47:44 | | | |
3 Mart'ta "Zigbee Journey (9)"u yazdıktan sonra, yazar başlangıçta hemen "sıcaklık izleme sistemi" üzerine küçük bir deney yazmaya başlamayı planlamıştı; bu, daha önce dağınık bilgi noktalarının özeti olarak ortaya çıkmıştır. Ancak, önceki küçük deneylerin her biri ayrıntılı olarak tanımlanmış olsa da, kodlarının normatif ve yapısal doğasının dayanılmaz olarak adlandırılabileceğini de fark ettim. Özet olduğu için, önceki küçük bilgi noktalarını mekanik olarak birleştirmek yerine orijinal temelde ilerleme kaydetmeliyiz. Bu yüzden orijinal planımı erteledim, gömülü geliştirme tekniklerini öğrenmek için zaman ayırdım ve iki deneme yazdımGömülü C51 programlama spesifikasyonu" ve "Gömülü proje kod yapısının hiyerarşisi》。 Bu günlük, sadece Zigbee'nin ilk gezisinin özeti olmakla kalmıyor, aynı zamanda yazarın son günlerdeki öğrenme deneyimini de dahil ediyor ve Zigbee yeni başlayanlara faydalı olmayı umuyordu.
Tam metin, yazılım geliştirmenin temel sürecine göre düzenlenmiştir: gereksinim analizi, taslak tasarımı, ayrıntılı tasarım, kodlama uygulaması ve test.
1. Talep analizi
"Müşteri" ile "geliştirici" arasında yapılan tartışmadan sonra aşağıdaki sistem fonksiyon tanımı belirlendi:
… Mevcut oda sıcaklığı CC2430 tabanlı düğümler tarafından toplanır ve sıcaklık değerleri bir PC aracılığıyla izlenebilir
… CC2430 düğümünün kendisi belirli bir kararlılık derecesine sahip olmalı ve otomatik olarak normal duruma dönebilmelidir
… Düğümün örnekleme aralığı ve güç yönetimi bir PC tarafından kontrol edilebilir
2. Taslak tasarımı
Yukarıdaki gereksinim analizine göre, sistemi iki modüle bölebiliriz:CC2430 düğümüvePC
  [CC2430 Düğüm]  
… Dış parametreler düzenli olarak toplanabilir ve PC'ye gönderilebilir
… Makine kapandığında otomatik sıfırlama
… PC'den gelen komutlar alınabilir ve işlenebilir: örnek aralığını/güç yönetimini değiştirin
  [PC]  
… C makinesi, seri port aracı aracılığıyla veri alır ve gösterir
… Komutlar, mikrodenetleyiciye seri port aracı aracılığıyla gönderilerek örnekleme hızını ve güç yönetimini kontrol edebilir
3. Detaylı tasarım
(1) Kod yapısı
Bu sistemin kod yapısının katmanlanması aslında şu makalede tanımlanmıştır:Gömülü proje kod yapısının hiyerarşisi", ve kopyası şöyledir:
(1) Donanım soyutlama katmanı
      [ioCC2430.h] (sistem dahil)CC2430'un tüm SFR ve kesme vektörleri tanımlanmıştır
      [hal.h] Ortak tip tanımları, ortak atama makroları ve CC2430 çip içi kaynakların (I/O, seri iletişim, ADC, zamanlayıcı, güç yönetimi vb.) ortak yapılandırmasını içerir.
  (2) Fonksiyonel modül katmanı
      [module.h] çip içi kaynakları (zamanlayıcılar, I/O), çip dışı genişletme modüllerini (LED'ler) ve ilgili fonksiyonların beyanlarını tanımlar
      [module.cHer modülün başlatmasını (LED) uygulayın.
  (3) Uygulama katmanı
      [main.cSıcaklık alımı, PC ile iletişim ve kapatma ile sıfırlama gibi özel uygulama gereksinimlerini sağlamak için hal.h, ioCC2430.h ve module.h adreslerine bakın
(2) Her modülün uygulama yöntemleri
Taslak tasarımına göre bölünen modüllere göre, içsel sistem iki ana modüle ayrılabilir:CC2430 düğümüvePC
PC'de seri port iletişim araçları olduğundan, işlevleri gereksinimleri karşılayabilir, bu yüzden PC'nin bu kısmını yapmamıza gerek yok ve analiz etmemize gerek yok. Aşağıdaki CC2430 bölümünden bahsedelim
Noktanın her alt fonksiyonunun uygulama yöntemi:
… Zamanlayıcının sayım taşma kesintisini kullanarak zamanlı örnekleme tetiklenir
… Seri portlu UART0 modu, sıcaklık verilerini bir PC'ye iletir
… CC2430'un yerleşik watchdog devresi, sistemin otomatik sıfırlama fonksiyonunu gerçekleştirmek için kullanılır
… Seri port, PC'den gelen kontrol komutlarını yakalamak ve yanıt vermek için kesintileri almak için kullanılır
1) Alınırsa@Karakter, örnekleme aralığı kontrol komutu ve örnekleme aralığını gösteren bir sayı gelir: 0-0.5s, 1-1s, 2-2s
如:@0,表示每隔0.5秒采样一次。
2) Alınırsa$  Karakter, uyku kontrol komutu komutudur, ardından güç modunu gösteren bir sayı gelir
Örneğin: $3, yani sistemi güç modu 3'e sokmak anlamına gelir.
(3) Program akış şeması
  • Yüksek lisans programı akış şeması
  • Timer 1 Taşma Kesintisi Programı Akış Şeması
  • Seri port alıcı kesinti prosedürünün akış şeması




4. Kodlama uygulaması
(1) Donanım soyutlama katmanı
Donanım soyutlama katmanı ioCC2430.h ve hal.h'yi içerir. Çünkü ilk sistem onunla birlikte geldiği için listelenmeyecek.
Aşağıda hal.h'nin tüm içeriklerinin bir listesi yer almaktadır (bu dosya çok uzun ve rahatsız göründüğü için modüllerde göstereceğim):
  • kafa
  • Giriş/Çıkış portları
  • Kesildi
  • Seri port
  • Güç ve saat yönetimi
  • Zamanlayıcı
  • Nöbetçi köpek
  • ADC
[url=] [/url]
/***********************************************************
*Dosya adı: hal.h
*Yazar: hustlzp
*Tarih: 8 Mart 2011
*Baskı: 1.1
*Fonksiyon tanımı: Donanım soyutlama katmanı
*Değiştirilmiş kayıtlar:
**********************************************************
*/


#ifndef HAL_H
#defineHAL_H


#include


/***********************************************************
                       Yaygın tür tanımları
**********************************************************
*/
typedef imzasızchar   BYTE;
typedef imzasızint    WORD;
typedef imzasızuzun   DWORD;



/***********************************************************
                       Yaygın kullanılan makro tanımlar
**********************************************************
*/

//8 sıra daha yüksek
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))


//8 basamak daha aşağı
#defineLOW_BYTE(a) ((BYTE) ((WORD)(a)))


//Atama
#defineSET_WORD(regH,regL,word)  
   yapmak{                           
      (regH)=HIGH_BYTE(kelime);     
      (regL)=LOW_BYTE(kelime);      
   }while(0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Giriş/Çıkış portları
**********************************************************
*/
/*G/Ç portunun yönünü yapılandırın
-----------------------------------------
*/
#defineIO_DIR_PORT_PIN(port, pin, direksiyon)  
   yapmak{                                 
      eğer(dir == IO_OUT)                 
         P##port##DIR |= (0x01<<(pin));  
      else                              
         P##port##DIR &= ~(0x01<<(pin));
   }while(0)



//Dir'in parametresinin değeri şudur:
#defineIO_IN 0
#defineIO_OUT 1


/*Giriş/Çıkış portunun giriş modunu yapılandırın
-----------------------------------------
*/
#defineIO_IMODE_PORT_PIN(port, pin, imode)
   yapmak{                                    
      eğer(imode == IO_IMODE_TRI)            
         P##port##INP |= (0x01<<(pin));     
      else                                 
         P##port##INP &= ~(0x01<<(pin));   
   }while (0)



#define IO_PUD_PORT(liman, pud)        
   do {                              
      if (pud == IO_PULLDOWN)         
         P2INP |= (0x01 << (port+5));
      else                           
         P2INP &= ~(0x01 << (port+5));
   } while (0)


PUD parametresinin değeri şudur:
#define IO_PULLUP 0 // Çek yukarı
#define IO_PULLDOWN 1 // Aşağı çek


/*配置I/O口的功能
-----------------------------------------*/

#define IO_FUNC_PORT_PIN(port, pin, func)  
   do {                                    
      if((port == 2) && (pin == 3)){      
         if (func) {                       
            P2SEL |= 0x02;                 
         } else {                          
            P2SEL &= ~0x02;               
         }                                 
      }                                    
      else if((port == 2) && (pin == 4)){  
         if (func) {                       
            P2SEL |= 0x04;                 
         } else {                          
            P2SEL &= ~0x04;               
         }                                 
      }                                    
      else{                                
         if (func) {                       
            P##port##SEL |= (0x01<<(pin));
         } else {                          
            P##port##SEL &= ~(0x01<<(pin));
        }                                 
      }                                    
   } while (0)


func parametresinin değeri şudur:
#define IO_FUNC_GIO 0 // Genel I/O
#define IO_FUNC_PERIPH 1 // Çevresel Giriş/Çıkış


Çevresel G/Ç konumunu yapılandırma
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } while (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } while (0)

#define IO_PER_LOC_TIMER3_AT_PORT1_PIN34() do { PERCFG = (PERCFG&~0x20)|0x00; } while (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN67() do { PERCFG = (PERCFG&~0x20)|0x20; } while (0)

#define IO_PER_LOC_TIMER4_AT_PORT1_PIN01() do { PERCFG = (PERCFG&~0x10)|0x00; } while (0)
#define IO_PER_LOC_TIMER4_AT_PORT2_PIN03() do { PERCFG = (PERCFG&~0x10)|0x10; } while (0)

#define IO_PER_LOC_SPI1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x08)|0x00; } while (0)
#define IO_PER_LOC_SPI1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x08)|0x08; } while (0)

#define IO_PER_LOC_SPI0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x00; } while (0)
#define IO_PER_LOC_SPI0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x04; } while (0)

#define IO_PER_LOC_UART1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x02)|0x00; } while (0)
#define IO_PER_LOC_UART1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x02)|0x02; } while (0)

#define IO_PER_LOC_UART0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x00; } while (0)
#define IO_PER_LOC_UART0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x01; } while (0)

//imode parametresinin değeri şudur:
#defineIO_IMODE_PUD 0   //Yukarı/aşağı çek
#defineIO_IMODE_TRI 1   //Üç eyalet[url=] [/url]

[url=] [/url]
/***********************************************************
                       Kesildi
**********************************************************
*/
//Açık/kapalı kesintiler için
#defineINT_ON 1
#defineINT_OFF 0


//Kesme bayraklarını yerleştirmek/temizlemek için kullanılır
#defineINT_SET 1
#defineINT_CLR 0


//Küresel kesinti ayarları
#defineINT_GLOBAL_ENABLE(açık) EA=(!! On)


//Kırılmayı tanımlayın
#defineINUM_RFERR 0
#defineINUM_ADC 1
#defineINUM_URX0 2
#defineINUM_URX1 3
#defineINUM_ENC 4
#defineINUM_ST 5
#defineINUM_P2INT 6
#defineINUM_UTX0 7
#defineINUM_DMA 8
#defineINUM_T1 9
#defineINUM_T2 10
#defineINUM_T3 11
#defineINUM_T4 12
#defineINUM_P0INT 13
#defineINUM_UTX1 14
#defineINUM_P1INT 15
#defineINUM_RF 16
#defineINUM_WDT 17


/*Kesintilere izin verildi
-----------------------------------------
*/
#defineINT_ENABLE(inum, on)                        
   yapmak{                                             
      eğer      (inum==INUM_RFERR) { RFERRIE = açık; }  
      else eğer(inum==INUM_ADC)   { ADCIE = açık; }  
      else eğer(inum==INUM_URX0)  { URX0IE = açık; }  
      else eğer(inum==INUM_URX1)  { URX1IE = açık; }  
      else eğer(inum==INUM_ENC)   { ENCIE = açık; }  
      else eğer(inum==INUM_ST)    { STIE = açık; }  
      else eğer(inum==INUM_P2INT) { (açık) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
      else eğer(inum==INUM_UTX0)  { (açık) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
      else eğer(inum==INUM_DMA)   { DMAIE = açık; }  
      else eğer(inum==INUM_T1)    { T1IE = açık; }  
      else eğer(inum==INUM_T2)    { T2IE = açık; }  
      else eğer(inum==INUM_T3)    { T3IE = açık; }  
      else eğer(inum==INUM_T4)    { T4IE = açık; }  
      else eğer(inum==INUM_P0INT) { P0IE = açık; }  
      else eğer(inum==INUM_UTX1)  { (açık) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
      else eğer(inum==INUM_P1INT) { (açık) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
      else eğer(inum==INUM_RF)    { (açık) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
      else eğer(inum==INUM_WDT)   { (açık) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
   }while (0)


/*Kesinti önceliğini belirleyin
-----------------------------------------
*/
#defineINT_PRIORITY(grup, pri)                     
   yapmak{                                               
      eğer(pri ==0) { IP0 &= ~grup; IP1 &= ~grup; }
      eğer(pri ==1) { IP0 |= grup; IP1 &= ~grup; }
      eğer(pri ==2) { IP0 &= ~grup; IP1 |= grup; }
      eğer(pri ==3) { IP0 |= grup; IP1 |= grup; }
   }while (0)

//Pri parametresinin değeri: 0/1/2/3 (en yüksek öncelik)


//Parametre grubunun değeri şudur:
#defineRFERR_RF_DMA 0x01//Grup IP0
#defineADC_P2INT_T1 0x02//Grup IP1
#defineURX0_UTX0_T2 0x04//IP2 Grubu
#defineURX1_UTX1_T3 0x08//Grup IP3
#defineENC_P1INT_T4 0x10//IP4 Grubu
#defineST_WDT_P0INT 0x20//Grup IP5


/*Kesme bayrağını alın
-----------------------------------------
*/
#defineINT_GETFLAG(inum) (                       
   (inum==INUM_RFERR) ? RFERRIF :
   (inum==INUM_ADC) ? ADCIF :
   (inum==INUM_URX0) ? URX0IF :
   (inum==INUM_URX1) ? URX1IF :
   (inum==INUM_ENC) ? ENCIF_0 :
   (inum==INUM_ST) ? STIF :
   (inum==INUM_P2INT) ? P2IF :
   (inum==INUM_UTX0) ? UTX0IF :
   (inum==INUM_DMA) ? DMAIF :
   (inum==INUM_T1) ? T1IF :
   (inum==INUM_T2) ? T2IF :
   (inum==INUM_T3) ? T3IF :
   (inum==INUM_T4) ? T4IF :
   (inum==INUM_P0INT) ? P0IF :
   (inum==INUM_UTX1) ? UTX1IF :
   (inum==INUM_P1INT) ? P1IF :
   (inum==INUM_RF) ? S1CON &= ~0x03    :
   (inum==INUM_WDT) ? WDTIF :
   0                                             
)


/*Kesme bayrağını ayarlayın
-----------------------------------------
*/
#defineINT_SETFLAG(inum, f)                     
   yapmak{                                          
      eğer      (inum==INUM_RFERR) { RFERRIF= f; }
      else eğer(inum==INUM_ADC)   { ADCIF = f; }
      else eğer(inum==INUM_URX0)  { URX0IF = f; }
      else eğer(inum==INUM_URX1)  { URX1IF = f; }
      else eğer(inum==INUM_ENC)   { ENCIF_1 = ENCIF_0 = f; }
      else eğer(inum==INUM_ST)    { STIF = f;  }
      else eğer(inum==INUM_P2INT) { P2IF = f;  }
      else eğer(inum==INUM_UTX0)  { UTX0IF= f;  }
      else eğer(inum==INUM_DMA)   { DMAIF = f;  }
      else eğer(inum==INUM_T1)    { T1IF = f;  }
      else eğer(inum==INUM_T2)    { T2IF = f;  }
      else eğer(inum==INUM_T3)    { T3IF = f;  }
      else eğer(inum==INUM_T4)    { T4IF = f;  }
      else eğer(inum==INUM_P0INT) { P0IF = f;  }
      else eğer(inum==INUM_UTX1)  { UTX1IF= f;  }
      else eğer(inum==INUM_P1INT) { P1IF = f;  }
      else eğer(inum==INUM_RF)    { (f) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
      else eğer(inum==INUM_WDT)   { WDTIF = f;  }
   }while (0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Seri port
**********************************************************
*/
//Farklı baud hızlarına karşılık gelen BAUD_E değeri
#defineBAUD_E(baud, clkDivPow) (     
    (baud==2400)   ?  6  +clkDivPow :
    (baud==4800)   ?  7  +clkDivPow :
    (baud==9600)   ?  8  +clkDivPow :
    (baud==14400)  ?  8  +clkDivPow :
    (baud==19200)  ?  9  +clkDivPow :
    (baud==28800)  ?  9  +clkDivPow :
    (baud==38400)  ?  10+clkDivPow :
    (baud==57600)  ?  10+clkDivPow :
    (baud==76800)  ?  11+clkDivPow :
    (baud==115200) ?  11+clkDivPow :
    (baud==153600) ?  12+clkDivPow :
    (baud==230400) ?  12+clkDivPow :
    (baud==307200) ?  13+clkDivPow :
    0  )


//Farklı baud hızlarına karşılık gelen BAUD_M değeri
#defineBAUD_M(baud) (      
    (baud==2400)   ?  59  :
    (baud==4800)   ?  59  :
    (baud==9600)   ?  59  :
    (baud==14400)  ?  216 :
    (baud==19200)  ?  59  :
    (baud==28800)  ?  216 :
    (baud==38400)  ?  59  :
    (baud==57600)  ?  216 :
    (baud==76800)  ?  59  :
    (baud==115200) ?  216 :
    (baud==153600) ?  59  :
    (baud==230400) ?  216 :
    (baud==307200) ?  59  :
  0)


/*UART modunda seri port yapılandırması
-----------------------------------------
*/
#defineUART_SETUP(uart, receiveEnable, baudRate, seçenekler)      
   yapmak{                                                         
      eğer((uart) ==0){                                          
         eğer(PERCFG &0x01){                                    
            P1SEL |=0x30;                                      
         }else{                                               
            P0SEL |=0x0C;                                      
         }                                                      
      }                                                         
      else{                                                   
         eğer(PERCFG &0x02){                                    
            P1SEL |=0xC0;                                      
         }else{                                               
            P0SEL |=0x30;                                      
         }                                                      
      }                                                         
                                                               
      U##uart##GCR = BAUD_E((baudRate),CLKSPD);                 
      U##uart##BAUD = BAUD_M(baudRate);                        
                                                               
      U##uart##CSR |=0x80;                                    
                                                               
      U##uart##CSR |= receiveEnable;                           
                                                               
      U##uart##UCR |= ((seçenekler) |0x80);                       
   }while(0)
     
//receive parametresinin değeriEtkinleştir:
#defineUART_RECEIVE_ENABLE 0x40   //İzin alınması
#defineUART_RECEIVE_DISABLE 0x00   
     
//Parametre seçeneklerinin değeri:
#defineFLOW_CONTROL_ENABLE 0x40   //Akış kontrolü
#defineFLOW_CONTROL_DISABLE 0x00


#defineEVEN_PARITY 0x20   //Ara sıra doğrulama
#defineODD_PARITY 0x00   //Garip doğrulama


#defineNINE_BIT_TRANSFER 0x10   //9 baytlık aktarım
#defineEIGHT_BIT_TRANSFER 0x00   //8 baytlık aktarım


#definePARITY_ENABLE 0x08   //Parity check etkinleştirme
#definePARITY_DISABLE 0x00

#defineTWO_STOP_BITS 0x04   //2 pozisyonlu durma pozisyonu
#defineONE_STOP_BITS 0x00   //1 durak pozisyonu


#defineHIGH_STOP 0x02   //Durak seviyesi yüksek
#defineLOW_STOP 0x00   //Durma pozisyonu düşük
     
#defineHIGH_START 0x01   //Başlangıç bit seviyesi yüksek
#defineLOW_START 0x00   //Başlangıç bit seviyesi düşük


//Seri port karakter gönderir
#defineUART_SEND(uart,data)            
   yapmak{                                 
     while(U##uart##CSR &0x01);        
       U##uart##DBUF = veri;            
   }while (0)
#defineUART0_SEND(veri) UART_SEND(0,veri)
#defineUART1_SEND(data) UART_SEND(1,data)


//Seri portu karakterleri alır
#defineUART_RECEIVE(uart,data)         
   yapmak{                                 
     while(! (U##uart##CSR&0x04));      
       data=U##uart##DBUF;              
   }while(0)
#defineUART0_RECEIVE(data) UART_RECEIVE(0,data)
#defineUART1_RECEIVE(veri) UART_RECEIVE(1,veri)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Güç ve saat yönetimi
**********************************************************
*/
//Saat kesişimini yapın
#defineCLKSPD (CLKCON & 0x07)


//Güç modunu ayarlayın
#defineSET_POWER_MODE(mod)                  
   yapmak{                                       
      eğer(mod ==0) { UYKU &= ~0x03; }
      else eğer(mod ==3) { UYKU |=0x03;  }
      else{ UYKU &= ~0x03; UYKU |= modu;  }
      PCON |=0x01;                           
      asm("NOP");                              
   }while (0)


//Parametre modu aşağıdaki değerlere ayarlanmıştır:
#definePOWER_MODE_0 0x00  
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03


//Yüksek frekanslı RC osilatörlerinin kararlılığını tespit etmek için kullanılır
#defineHIGH_FREQUENCY_RC_OSC_STABLE (UYKU &0x20)


//Kristal osilatörün kararlı durumunu tespit etmek için kullanılır
#defineXOSC_STABLE (UYKU &0x40)


//Zamanlayıcının tick frekans değerini alın
#defineTICKSPD ((CLKCON & 0x38) >> 3)


//Ana saat frekansını ayarlayın
#defineSET_MAIN_CLOCK_SOURCE(kaynak)
   yapmak{                              
      eğer(kaynak) {                    
        CLKCON |=0x40;               
        while(! HIGH_FREQUENCY_RC_OSC_STABLE);
        eğer(TICKSPD ==0){            
          CLKCON |=0x08;            
        }                             
        UYKU |=0x04;               
      }                              
      else{                          
        UYKU &= ~0x04;               
        while(! XOSC_STABLE);         
        asm("NOP");                  
        CLKCON &= ~0x47;              
        UYKU |=0x04;               
      }                              
   }while (0)


//Parametre kaynağının değeri şudur:
#defineCRYSTAL 0x00   //Kristal osilatör
#defineRC 0x01   //RC osilatör
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Zamanlayıcı 1
**********************************************************
*/
//Zamanlayıcı 1, sayım taşmasının kesintiye girmesine izin verir
#defineTIMER1_ENABLE_OVERFLOW_INT(val)
   (TIMIF = (val) ? TIMIF |0x40: TIMIF & ~0x40)


//Zamanlayıcı 1 için taşma kesme bayrağını ayarlayın
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))


//Zamanlayıcı 1 başlıyor
#defineTIMER1_RUN(değer) (T1CTL = (değer) ? T1CTL|0x02 : T1CTL&~0x03)


//Zamanlayıcı için saat bölümünü ayarlayın
#defineSET_TIMER_TICK(değer) do{ CLKCON = ((CLKCON & (~0x38)) | değer); } while(0)


//Değer değeri şudur:
#defineTIMER1_TICK_32M 0x00  //32MHz
#defineTIMER1_TICK_16M 0x08  //16MHz, sistem sıfırlanması için varsayılan değer
#defineTIMER1_TICK_8M 0x10  //8MHz
#defineTIMER1_TICK_4M 0x18  //4MHz
#defineTIMER1_TICK_2M 0x20  //2MHz
#defineTIMER1_TICK_1M 0x28  //1MHz
#defineTIMER1_TICK_500k 0x30  //500kHz
#defineTIMER1_TICK_250k 0x38  //250kHz

//TICK crossover'ını zamanlayıcı 1 için ayarlayın
#defineSET_TIMER1_TICKDIV(değer)  
   yapmak{                             
     T1CTL &= ~0x0c;               
     T1CTL |= değer;               
   }while (0)
      
//burada değer şudur:      
#defineTIMER1_TICKDIV_1 0x00   //1 Bölüm
#defineTIMER1_TICKDIV_8 0x04   //8 frekans
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c


//Zamanlayıcı taşma süresini ayarlayın
#defineSET_TIMER1_PERIOD(değer)
   yapmak{                           
     T1CC0H = HIGH_BYTE(değer);  
     T1CC0L = LOW_BYTE(değer);   
   }while (0)
     
//Timer 1'in çalışma modunu ayarlayın
#defineSET_TIMER1_MODE(mod)  
   yapmak{                        
     T1CTL = ((T1CTL & (~0x03)) | mod);           
   }while (0)


//Modun değeri şudur:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Nöbetçi köpek
**********************************************************
*/
//Watchdog zamanlayıcısı için taşma süresini ayarlayın
#defineWDT_SET_TIMEOUT_PERIOD(mola)
   yapmak{ WDCTL &= ~0x03; WDCTL |= mola; }while (0)


//Parametre zaman aşımının değeri şudur:
#defineSEC_1 0x00     //1 saniye sonra
#defineM_SEC_250 0x01     //250 ms sonrası
#defineM_SEC_15 0x02     //15 ms sonrası
#defineM_SEC_2 0x03     //2 ms sonra


//Köpek besleme prosedürleri
#defineWDT_RESET() do {           
   WDCTL = (WDCTL & ~0xF0) |0xA0;
   WDCTL = (WDCTL & ~0xF0) |0x50;
} while (0)


//Watchdog zamanlayıcısını başlat/durdur
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]

[url=] [/url]
/***********************************************************
                       ADC
**********************************************************
*/
//Tek bir ADC yapılandır
#defineADC_SINGLE_CONVERSION(ayarlar)
   yapmak{ ADCCON3 = ayarlar; }while(0)

//Parametre ayarı aşağıdaki kombinasyonlardan oluşur:
//Referans voltajı
#defineADC_REF_1_25_V 0x00     //Dahili 1.25V Referans Voltajı
#defineADC_REF_P0_7 0x40     //AIN7 pininde harici referans voltajı
#defineADC_REF_AVDD 0x80     //AVDD_SOC Pins
#defineADC_REF_P0_6_P0_7 0xC0     //AIN6-AIN7 Diferansiyel girişler için harici referans voltajı


//Örnekleme hızı
#defineADC_8_BIT 0x00     //8. sıra
#defineADC_10_BIT 0x10     //10. sıra
#defineADC_12_BIT 0x20     //12.
#defineADC_14_BIT 0x30     //14. sıra


//Kanala gir
#defineADC_AIN0 0x00     //P0_0
#defineADC_AIN1 0x01     //P0_1
#defineADC_AIN2 0x02     //P0_2
#defineADC_AIN3 0x03     //P0_3
#defineADC_AIN4 0x04     //P0_4
#defineADC_AIN5 0x05     //P0_5
#defineADC_AIN6 0x06     //P0_6
#defineADC_AIN7 0x07     //P0_7
#defineADC_GND 0x0C     //Kara
#defineADC_TEMP_SENS 0x0E     //Çip içi sıcaklık sensörü
#defineADC_VDD_3 0x0F     //vdd/3




ADC dönüşümü tamamlandı
#define ADC_SAMPLE_READY() (ADCCON1 & 0x80)

#endif
//启动ADC转化
#define ADC_START()
  do { ADCCON1 |= 0x40; } while (0)//ADC'nin tetikleme modunu manuel olarak seçin (yani ADC_SAMPLE_READY)
#defineADC_STOP()  
  yapmak{ ADCCON1 |=0x30; }while (0)[url=] [/url]


(2) Fonksiyonel modül katmanı
  • module.h
  • module.c
[url=] [/url]
/***********************************************************
*Dosya adı: module.h
*Yazar: hustlzp
*Tarih: 6 Mart 2011
*Sürüm: 1.0
*Fonksiyon tanımı: Fonksiyonel modül katman başlığı dosyası
*Fonksiyon listesi: boş led_init()
            Void timer1_init()
            void uart0_init(void);
            void Uart0SendString(işaretsiz karakter *s);
            float adc_start(void)
            void get_temperature(işaretsiz karakter *çıktı, float temp);
            void watchdog_init(void);
*Değiştirilmiş kayıtlar:
**********************************************************
*/

#ifndef MODULE_H
#defineMODULE_H


#include"hal.h"


/***********************************************************
                        LED
**********************************************************
*/
//LED pinlerini tanımlayın
#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   

//LED ışığı ve kapanması
#defineLED_OFF 1
#defineLED_ON 0

//LED başlatma
Voidled_init(Void);




/***********************************************************
                        timer1
**********************************************************
*/
//Zamanlayıcının taşma süresi değerini ayarlamak için kullanılır
#defineTIMER1_OVF_2SEC 0xF424   //2s
#defineTIMER1_OVF_1SEC 0x7A12   //1s
#defineTIMER1_OVF_dot5SEC 0x3D09   //0.5s   

//Zamanlayıcı 1 başlatılır
Void  timer1_init(Void);
                  

/***********************************************************
                        UART0
**********************************************************
*/
//UART0 başlatma
Void  uart0_init(Void);                    

//Seri port iletim dizisi
Void  Uart0SendString(imzasızchar*s);
   

/***********************************************************
                        ADC-14
**********************************************************
*/
//ADC tarafından elde edilen verileri Celsius sıcaklığına dönüştürmek için kullanılır
#defineADC_TO_CELSIUS(sıcaklık) (sıcaklık * 0.06229 - 311.43)

//ADC dönüşümünü başlatın
Floatadc_start(Void);

//Dönüşüm
Void  get_temperature(imzasızchar*çıktı,Floattemp);


/***********************************************************
                        WatchDog
**********************************************************
*/
//Gözetleme köpeği başlatma
Void  watchdog_init(Void);                 

#endif
[url=] [/url]

[url=] [/url]
/***********************************************************
*Dosya adı: module.c
*Yazar: hustlzp
*Tarih: 2011/3/11
*Sürüm: 1.0
*Fonksiyon Tanımı: Fonksiyonel modül katmanı kaynak dosyası
*Fonksiyon listesi: (çıkarıldı)
*Değiştirilmiş kayıtlar:
**********************************************************
*/


#include"module.h"


/***********************************************************
*Fonksiyon Adı: led_init
*Fonksiyon fonksiyonu: LED başlatma
*Giriş parametreleri: Yok
*İxracat parametreleri: Yok
**********************************************************
*/
Voidled_init(Void)
{
  //P1.0, P1.1, P1.2 ve P1.3'ü genel G/O portları olarak yapılandırın
  IO_FUNC_PORT_PIN(1, 0, IO_FUNC_GIO);
  IO_FUNC_PORT_PIN(1, 1, IO_FUNC_GIO);
  IO_FUNC_PORT_PIN(1, 2, IO_FUNC_GIO);
  IO_FUNC_PORT_PIN(1, 3, IO_FUNC_GIO);
  
  //P1.0, P1.1, P1.2 ve P1.3'ü çıkış olarak yapılandırın
  IO_DIR_PORT_PIN(1, 0, IO_OUT);
  IO_DIR_PORT_PIN(1, 1, IO_OUT);
  IO_DIR_PORT_PIN(1, 2, IO_OUT);
  IO_DIR_PORT_PIN(1, 3, IO_OUT);
  
  led1 = LED_ON;
  led2 = LED_OFF;
  led3 = LED_OFF;
  led4 = LED_OFF;
}


/***********************************************************
*Fonksiyon Adı: timer1_init
* Fonksiyon fonksiyonu: Zamanlayıcı 1 başlatma
*Giriş parametreleri: Yok
*İxracat parametreleri: Yok
**********************************************************
*/
Voidtimer1_init(Void)
{
  INT_GLOBAL_ENABLE(INT_ON);                 //Küresel kesintiyi aç
  
  INT_ENABLE(INUM_T1, INT_ON);               //Open T1 kesmesi

  TIMER1_ENABLE_OVERFLOW_INT(INT_ON);        //Open T1 sayım taşma kesintisi
  
  SET_TIMER_TICK(TIMER1_TICK_4M);            //Zamanlayıcı TICK'i 4MHz'e ayarlayın
  
  SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);        //T1 için sayım süresini 2 saniyeye ayarlayın
  
  SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128);   //T1 için saat geçişini 128'e ayarlayın
  
  SET_TIMER1_MODE(TIMER1_MODE_MODULE);      //T1'in çalışma modunu modül olarak ayarlayın
}


/***********************************************************
*Fonksiyon Adı: uart0_init
*Fonksiyon fonksiyonu: Seri port UART0 başlatma
*Giriş parametreleri: Yok
*İxracat parametreleri: Yok
**********************************************************
*/
Voiduart0_init(Void)
{
  //UART konumunu seçin
  IO_PER_LOC_UART0_AT_PORT0_PIN2345();
  
  //UART'ı yapılandırma: Kabul izni, 115200bps, tek bitlik durdurma biti, eşitlik yok
  UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);

  //Tam kesintiyi aç
  INT_GLOBAL_ENABLE(INT_ON);      

  //Kesintileri almak için seri port 0'ı açın
  INT_ENABLE(INUM_URX0, INT_ON);   
}


/***********************************************************
*Fonksiyon adı: Uart0SendString
* Fonksiyon fonksiyonu: Zamanlayıcı 1 başlatma
*Giriş parametresi: işaretsiz karakter *s
            Göndermek istediğiniz ip
*İxracat parametreleri: Yok
**********************************************************
*/
VoidUart0SendString(imzasızchar*s)
{
  while(*s !=0)         
    UART0_SEND(*s++);
}


/***********************************************************
*Fonksiyon Adı: adc_start
*Fonksiyon fonksiyonu: ADC dönüşümünü başlat
*Giriş parametreleri: Yok
*İhracat parametresi: float
            Tabletteki sıcaklık değeri
**********************************************************
*/
Floatadc_start(Void)
{
  imzasızintTemp;
  
  //Referans voltajı 1.25V, örnekleme doğruluğu 14 bittir ve dönüşüm hedefi çip içi sıcaklık sensörüdür
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  
  ADC_STOP();                           //ADC dönüşümü için tetikleme yöntemini manuel olarak ayarlayın
  
  ADC_START();                           //ADC dönüşümünü başlatın
  
  while(! ADC_SAMPLE_READY());            //Dönüşümün tamamlanmasını bekleyin
  
  temp = ADCL >>2;                     //Dönüşümü sıcaklıkta kaydet
  temp |= (((imzasızint) ADCH) <<6);
  
  DönüşADC_TO_CELSIUS(müdemlik);           //Dönüşümden sonra gerçek sıcaklık değerini döndürür
}


/***********************************************************
*Fonksiyon adı: get_temperature
*Fonksiyon fonksiyonu: Sıcaklık değerini işleyip seri çıktı için karakter dizisinde depolayın
*Giriş parametresi: işaretsiz karakter *çıktı
            Dönüştürülmüş sıcaklık değerini depolamak için kullanılır
            Float sıcaklığı
            Celsius sıcaklık değeri
*İxracat parametreleri: Yok
**********************************************************
*/
Voidget_temperature(imzasızchar*çıktı,Floattemp)
{
  çıktı[0] = (imzasızchar)(Temp) /10 + 48;         //On yer
  çıktı[1] = (imzasızchar)(sıcaklık) %10 + 48;         //tek haneli
  çıktı[2] ='.';                                      //Ondalık nokta
  çıktı[3] = (imzasızchar)(temp*10) %10 + 48;      //Onuncu
  çıktı[4] = (imzasızchar)(temp*100) %10 + 48;      //Yüzde Çizgisi
  çıktı[5] ='';                                    //String endifiers
}


/***********************************************************
*Fonksiyon Adı: watchdog_init
*Fonksiyon fonksiyonu: Watchdog başlatma
*Giriş parametreleri: Yok
*İxracat parametreleri: Yok
**********************************************************
*/
Voidwatchdog_init(Void)
{
  WDT_SET_TIMEOUT_PERIOD(SEC_1);   //Zaman aşımı süresini 1s olarak ayarlayın
  WDT_ENABLE();                    //Gözetçi Köpeği başlat
}
[url=] [/url]


(3) Uygulama katmanı
  • main.c
[url=] [/url]
/*******************************************************************
Dosya adı: main.c
Yazar: hustlzp
Tarih: 2011/3/11
Sürüm: 1.0
Fonksiyon tanımı: Ana program dosyası
Fonksiyon Listesi: (çıkarıldı)
Değişiklik Kaydı:
******************************************************************
*/


#include




/********************************************************************
                             Kesinti hizmeti prosedürleri
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektör=T1_VECTOR
__interrupt boşluk T1_ISR(boşluk)
{
  EA=0;                                   Kapı kesintiye girdi
  
  led2 = LED_ON;                          
  
  get_temperature(çıktı,adc_start());    Sıcaklık değerini çıkarılacak karakter dizisine dönüştürün
   
  Uart0SendString(output);                Çıkış sıcaklık değeri
  Uart0SendString("°C");  


  led2


/* 串口接收中断子程序
-------------------------------------------------------*/
#pragma vektör=URX0_VECTOR
__interrupt void RE_ISR(void)
{
  EA=0;
  
  led3 = LED_ON;

  receive = U0DBUF;   
  
  if(type==1) // type=1, bu da alınan karakterin zamanlayıcı taşma süresini ayarlamak için kullanıldığını gösterir
  {
    type=0;
    Anahtar (al)
    {
      vaka '0': // Zamanlayıcı taşma süresi 0.5s
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
        mola;
      }
      vaka '1': // Zamanlayıcı taşma süresi 1s'tir.
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
        mola;
      }
      case '2': // Zamanlayıcı taşma süresi 2s'tir.
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
        mola;         
      }
    }
  }
  else if(type==2) // type=2, alınan karakterlerin uyku kontrolü için kullanıldığını gösterir
  {
    type=0;
    led1 = LED_OFF;
    led2 = LED_OFF;
    led3 = LED_OFF;
    Anahtar (al)
    {
      case '1': // Güç moduna gir PM1
      {
        SET_POWER_MODE(1);  
        mola;
      }
      case '2': // Güç moduna gir PM2
      {
        SET_POWER_MODE(2);  
        mola;
      }
      vaka '3': //Güç moduna gir PM3
      {
        SET_POWER_MODE(3);  
        mola;
      }
    }
  }
  else if(type==0) // type=0, bu da alınan karakterin kontrol komutu türü olduğunu gösterir: @ veya $
  {
    if(receive=='@')  
    {
      type=1;     '@' harfi bir sonraki karakterin taşma süresini ayarlamak için kullanıldığını belirtmek için alınır
    }
    else if(receive=='$')
    {
      type=2;     '$' alınır, bu da sistem uyku kontrolü için bir sonraki karakterin kullanıldığını gösterir
    }
  }
  
  led3 = LED_OFF;
   
  EA=1;
}
=LED_OFF;
  
  TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR);   Kesinti işaretini temizleyin
  
  EA=1;                                   Açık kesinti  
}
/* 主函数
-------------------------------------------------------*/
void main(void)
{
  SET_MAIN_CLOCK_SOURCE(CRYSTAL);  Sistem saat saatini 32MHz kristal osilatör olarak ayarlayın
  
  led_init();                      LED başlatma
  
  uart0_init();                    Seri port UART0 başlatma
  
  timer1_init();                   Zamanlayıcı 1 başlatılır
  
  watchdog_init();                 Gözetleme köpeği başlatma
  
  while(1)
  {
    WDT_RESET();                   Köpeği sürekli besle
  }
}/********************************************************************
                            Ana program   
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
işaretsiz karakter çıktısı[6]={0};       Sıcaklık verileri, kolay seri çıkış için saklanır
imzasız Char Receive;             Alınan karakterleri depolayın
işaretsiz karakter tipi=0;              Alınan karakterin tip bayrağı 0/1/2 olarak ayarlanmıştır"module.h"[url=] [/url]


5. Test
Ah~ Kod nihayet yapıştırıldı, gerçekten çok yorucu, şu küçük sistemi test edelim:
(1) Zamanlanmış örnekleme
Seri portu açın, IAR hata ayıklamasına başlayın ve led1'in açık olduğunu, seri port aracının sıcaklık değerinin sürekli üretildiğini ve örnekleme aralığının 2s olarak belirlendiğini görürün:
(2) Örnekleme aralığı kontrolü
Seri port aracına "@1" girin ve örnekleme aralığını test edin, bunun 1s olduğunu görün; "@0" girin, örnekleme aralığı 0.5 saniyeye değişir.
(3) Uyku kontrolü
Seri port aracına "$1" girin ve tüm LED'lerin kapalı olduğunu, sıcaklık örneklemenin durduğunu görün:
Test sonrası sistem normal ve istikrarlı çalışıyor ve temel olarak gereksinimleri karşılıyor.
Kaynak koduna ihtiyacı olan öğrencilerİndirmek için buraya tıklayın
6. Sonuç
Bu makale, CC2430 çip üzerindeki kaynakların nasıl entegre edileceğini göstermek için biraz kapsamlı bir deneyi örnek olarak ele alarak nispeten standartlaştırılmış küçük bir sistem yazmayı amaçlamaktadır. Birkaç gün sonra, hal.h için basit bir kullanım kılavuzu yazacağım ki ben ve herkes CC2430'u kolayca kullanabilsin.
Sonra, CC2430 çip üzerindeki kaynaklar üzerine araştırmamı tamamlayıp kendimi TI Z-Stack protokol yığınını öğrenmeye adacağım~
Bu serideki blog yazısı şimdilik sona erdi, ancak Zigbee'nin yolculuğu devam edecek. Önlerindeki manzara bilinmiyor, ama yazarın herkesle engelleri aşacağına, iniş çıkışları tadacağına ve kazanımlar olacağına inanıyorum.
Takipte kalın: "TI Z-Stack'e Katılın" blog yazıları!















Önceki:Zigbee Yolculuğu (9): Birkaç önemli temel CC2430 deneyi - sistematik uyku ve kesintili uyanıklık
Önümüzdeki:Bugün Cadılar Bayramı, nasıl ağırlayacaksınız?
Yayınlandı 31.10.2014 08:04:14 |
Hiçbir şeyi anlamadığım için affedin
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