Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 10835|Svare: 1

Zigbee Journey (10): Omfattende eksperiment - Temperaturovervåkingssystem basert på CC2430

[Kopier lenke]
Publisert på 30.10.2014 23:47:44 | | | |
Etter å ha skrevet «Zigbee Journey (9)» 3. mars, planla forfatteren opprinnelig å umiddelbart begynne å skrive et lite eksperiment om «temperaturovervåkingssystem» som en oppsummering av en rekke spredte kunnskapspunkter tidligere. Men jeg innså også at selv om hvert av de tidligere små eksperimentene var beskrevet i detalj, kunne den normative og strukturelle naturen til koden sies å være uutholdelig. Siden det er et sammendrag, bør vi gjøre fremgang på det opprinnelige grunnlaget, i stedet for å mekanisk sette sammen de tidligere små kunnskapspunktene. Derfor satte jeg den opprinnelige planen min på vent, tok meg tid til å lære de generelle teknikkene for innebygd utvikling, og skrev to essaysInnebygd C51-programmeringsspesifikasjon" og "Hierarki for innebygd prosjektkodestruktur》。 Denne loggen er ikke bare et sammendrag av Zigbees første tur, men inkluderer også forfatterens læringserfaringer de siste dagene, i håp om å være til hjelp for nybegynnere i Zigbee.
Fullteksten er organisert etter den grunnleggende prosessen for programvareutvikling: kravanalyse, disposisjonsdesign, detaljert design, kodeimplementering og testing.
1. Etterspørselsanalyse
Etter diskusjon mellom "kunden" og "utvikleren" ble følgende systemfunksjonsbeskrivelse fastsatt:
… Den nåværende romtemperaturen samles inn av CC2430-baserte noder, og temperaturverdiene kan overvåkes via en PC
… Selve CC2430-noden må ha en viss grad av stabilitet og kan automatisk gå tilbake til normal tilstand
… Samplingsintervallet og strømstyringen til noden kan styres av en PC
2. Utforming av disposisjoner
I henhold til kravanalysen ovenfor kan vi dele systemet inn i to moduler:CC2430-nodeogPC
  [CC2430-node]  
… Eksterne parametere kan samles inn regelmessig og sendes til PC-en
… Automatisk tilbakestilling når maskinen slås av
… Kommandoer fra PC-en kan mottas og behandles deretter: endre prøveintervallet/strømstyring
  [PC]  
… C-maskinen mottar og viser data gjennom det serielle portverktøyet
… Instruksjoner kan sendes til mikrokontrolleren via det serielle portverktøyet for å kontrollere prøvetakingshastighet og strømstyring
3. Detaljert design
(1) Kodestruktur
Lagdelingen av kodestrukturen i dette systemet er faktisk beskrevet i essayet "Hierarki for innebygd prosjektkodestruktur", og kopien er som følger:
(1) Maskinvareabstraksjonslag
      [ioCC2430.h] (System inkludert)Alle SFR- og avbruddsvektorer til CC2430 er definert
      [hal.h] Inkluderer felles typedefinisjoner, vanlige tilordningsmakroer og felles konfigurasjon av CC2430 on-chip-ressurser (I/O, seriell kommunikasjon, ADC, timer, strømstyring, osv.)
  (2) Funksjonelt modullag
      [module.h] definerer on-chip ressurser (timere, I/O), off-chip ekspansjonsmoduler (LED-er) og deklarasjoner av relaterte funksjoner
      [module.cImplementer initialiseringen av hver modul (LED).
  (3) Applikasjonslag
      [main.cSe hal.h, ioCC2430.h og module.h for å oppnå spesifikke applikasjonskrav som temperaturinnsamling, kommunikasjon med PC, samt nedstengning og tilbakestilling
(2) Implementeringsmetoder for hver modul
I henhold til modulene delt inn etter disposisjonsdesignet, kan det intrinsiske systemet deles inn i to hovedmoduler:CC2430-nodeogPC
Siden det finnes serielle portkommunikasjonsverktøy på PC-en, kan funksjonene oppfylle kravene, så vi trenger ikke å gjøre denne delen av PC-en, og det er ikke nødvendig å analysere den. La oss snakke om seksjon CC2430 nedenfor
Implementeringsmetoden for hver delfunksjon av punktet:
… Bruk timerens telleoverløpsavbrudd for å utløse tidsbestemt sampling
… UART0-modusen med seriell port sender temperaturdata til en PC
… CC2430s innebygde watchdog-krets brukes til å realisere systemets automatiske tilbakestillingsfunksjon
… Den serielle porten brukes til å motta avbrudd for å fange opp og svare på kontrollkommandoer fra PC-en
1) Hvis mottatt@Tegnet er kontrollkommandoen for prøvetakingsintervallet, etterfulgt av et tall som indikerer prøvetakingsintervallet: 0-0,5 sekunder, 1-1 sekunder, 2-2 sekunder
如:@0,表示每隔0.5秒采样一次。
2) Hvis mottatt$  Tegnet er søvnkontrollkommandoen, etterfulgt av et tall som indikerer strømmodus
For eksempel: 3 dollar, som betyr å sette systemet i strømmodus 3.
(3) Programflytskjema
  • Flytskjema for masterprogrammet
  • Timer 1 Overflow Interrupt Program flytskjema
  • Flytskjema for prosedyre for seriell port mottakende avbrudd




4. Kodingsimplementering
(1) Maskinvareabstraksjonslag
Maskinvareabstraksjonslaget inkluderer ioCC2430.h og hal.h. Siden det første systemet følger med, vil det ikke være oppført.
Følgende er en liste over alt innholdet i hal.h (fordi denne filen er for lang og ser upraktisk ut, vil jeg vise den i moduler):
  • Hode
  • I/O-porter
  • Avbrutt
  • Seriellport
  • Strøm- og klokkestyring
  • Timer
  • Vakthund
  • ADC
[url=] [/url]
/***********************************************************
*Filnavn: hal.h
*Forfatter: hustlzp
*Dato: 8. mars 2011
*Utgave: 1.1
*Funksjonsbeskrivelse: Maskinvareabstraksjonslag
*Modifiserte opptegnelser:
**********************************************************
*/


#ifndef HAL_H
#defineHAL_H


#include


/***********************************************************
                       Vanlige typedefinisjoner
**********************************************************
*/
typedef usignertChar   BYTE;
typedef usignertInt    WORD;
typedef usignertlang   DWORD;



/***********************************************************
                       Ofte brukte makrodefinisjoner
**********************************************************
*/

//8 plasser høyere
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))


//8 plasser lavere
#defineLOW_BYTE(a) ((BYTE) ((WORD)(a)))


//Tildeling
#defineSET_WORD(regH, regL, ord)  
   gjøre{                           
      (regH)=HIGH_BYTE(ord);     
      (regL)=LOW_BYTE(ord);      
   }mens(0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       I/O-porter
**********************************************************
*/
/*Konfigurer I/O-portretningen
-----------------------------------------
*/
#defineIO_DIR_PORT_PIN(babord, pin, regi)  
   gjøre{                                 
      hvis(dir == IO_OUT)                 
         P##port##DIR |= (0x01<<(nål);  
      ellers                              
         P##port##DIR &= ~(0x01<<(nål);
   }mens(0)



//Verdien til parameter-diren er:
#defineIO_IN 0
#defineIO_OUT 1


/*Konfigurer inngangsmodusen til I/O-porten
-----------------------------------------
*/
#defineIO_IMODE_PORT_PIN(port, pin, imode)
   gjøre{                                    
      hvis(imode == IO_IMODE_TRI)            
         P##port##INP |= (0x01<<(nål);     
      ellers                                 
         P##port##INP &= ~(0x01<<(nål);   
   }mens (0)



#define IO_PUD_PORT(babord, pud)        
   do {                              
      hvis (pud == IO_PULLDOWN)         
         P2INP |= (0x01 << (port+5));
      ellers                           
         P2INP &= ~(0x01 << (port+5));
   } mens (0)


Verdien av parameteren PUD er:
#define IO_PULLUP 0 // Trekk opp
#define IO_PULLDOWN 1 // Dra ned


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

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


Verdien til parameterfunkcen er:
#define IO_FUNC_GIO 0 // Generell I/O
#define IO_FUNC_PERIPH 1 // Perifer I/O


Konfigurer plasseringen av den perifere I/O
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } mens (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } mens (0)

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

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

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

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

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

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

//Verdien av parameteren imode er:
#defineIO_IMODE_PUD 0   //Dra opp/dra ned
#defineIO_IMODE_TRI 1   //Tre stater[url=] [/url]

[url=] [/url]
/***********************************************************
                       Avbrutt
**********************************************************
*/
//For av/på-avbrudd
#defineINT_ON 1
#defineINT_OFF 0


//Brukes til å plassere/fjerne avbruddsflagg
#defineINT_SET 1
#defineINT_CLR 0


//Globale avbruddsinnstillinger
#defineINT_GLOBAL_ENABLE(på) EA=(!! på)


//Definer bruddet
#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


/*Avbrudd tillatt
-----------------------------------------
*/
#defineINT_ENABLE(inum, på)                        
   gjøre{                                             
      hvis      (inum==INUM_RFERR) { RFERRIE = on; }  
      ellers hvis(inum==INUM_ADC)   { ADCIE = på; }  
      ellers hvis(inum==INUM_URX0)  { URX0IE = on; }  
      ellers hvis(inum==INUM_URX1)  { URX1IE = on; }  
      ellers hvis(inum==INUM_ENC)   { ENCIE = på; }  
      ellers hvis(inum==INUM_ST)    { STIE = på; }  
      ellers hvis(inum==INUM_P2INT) { (på) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
      ellers hvis(inum==INUM_UTX0)  { (på) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
      ellers hvis(inum==INUM_DMA)   { DMAIE = på; }  
      ellers hvis(inum==INUM_T1)    { T1IE = på; }  
      ellers hvis(inum==INUM_T2)    { T2IE = på; }  
      ellers hvis(inum==INUM_T3)    { T3IE = på; }  
      ellers hvis(inum==INUM_T4)    { T4IE = på; }  
      ellers hvis(inum==INUM_P0INT) { P0IE = på; }  
      ellers hvis(inum==INUM_UTX1)  { (på) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
      ellers hvis(inum==INUM_P1INT) { (på) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
      ellers hvis(inum==INUM_RF)    { (på) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
      ellers hvis(inum==INUM_WDT)   { (på) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
   }mens (0)


/*Sett utfallsprioritet
-----------------------------------------
*/
#defineINT_PRIORITY(gruppe, pri)                     
   gjøre{                                               
      hvis(pri ==0) { IP0 &= ~gruppe; IP1 &= ~gruppe; }
      hvis(pri ==1) { IP0 |= gruppe; IP1 &= ~gruppe; }
      hvis(pri ==2) { IP0 &= ~gruppe; IP1 |= gruppe; }
      hvis(pri ==3) { IP0 |= gruppe; IP1 |= gruppe; }
   }mens (0)

//Verdien av parameteren pri er: 0/1/2/3 (høyeste prioritet)


//Verdien til parametergruppen er:
#defineRFERR_RF_DMA 0x01//Gruppe IP0
#defineADC_P2INT_T1 0x02//Gruppe IP1
#defineURX0_UTX0_T2 0x04//Gruppe IP2
#defineURX1_UTX1_T3 0x08//Gruppe IP3
#defineENC_P1INT_T4 0x10//Gruppe IP4
#defineST_WDT_P0INT 0x20//Gruppe IP5


/*Få avbruddsflagget
-----------------------------------------
*/
#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                                             
)


/*Sett avbruddsflagget
-----------------------------------------
*/
#defineINT_SETFLAG(inum, f)                     
   gjøre{                                          
      hvis      (inum==INUM_RFERR) { RFERRIF= f; }
      ellers hvis(inum==INUM_ADC)   { ADCIF = f; }
      ellers hvis(inum==INUM_URX0)  { URX0IF = f; }
      ellers hvis(inum==INUM_URX1)  { URX1IF = f; }
      ellers hvis(inum==INUM_ENC)   { ENCIF_1 = ENCIF_0 = f; }
      ellers hvis(inum==INUM_ST)    { STIF = f;  }
      ellers hvis(inum==INUM_P2INT) { P2IF = f;  }
      ellers hvis(inum==INUM_UTX0)  { UTX0IF= f;  }
      ellers hvis(inum==INUM_DMA)   { DMAIF = f;  }
      ellers hvis(inum==INUM_T1)    { T1IF = f;  }
      ellers hvis(inum==INUM_T2)    { T2IF = f;  }
      ellers hvis(inum==INUM_T3)    { T3IF = f;  }
      ellers hvis(inum==INUM_T4)    { T4IF = f;  }
      ellers hvis(inum==INUM_P0INT) { P0IF = f;  }
      ellers hvis(inum==INUM_UTX1)  { UTX1IF= f;  }
      ellers hvis(inum==INUM_P1INT) { P1IF = f;  }
      ellers hvis(inum==INUM_RF)    { (f) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
      ellers hvis(inum==INUM_WDT)   { WDTIF = f;  }
   }mens (0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Seriellport
**********************************************************
*/
//Verdien av BAUD_E tilsvarer ulike baudrater
#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  )


//Verdien av BAUD_M tilsvarer ulike baudrater
#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)


/*Seriell portkonfigurasjon i UART-modus
-----------------------------------------
*/
#defineUART_SETUP(uart, receiveEnable, baudRate, alternativer)      
   gjøre{                                                         
      hvis((uart) ==0){                                          
         hvis(PERCFG &0x01){                                    
            P1SEL |=0x30;                                      
         }ellers{                                               
            P0SEL |=0x0C;                                      
         }                                                      
      }                                                         
      ellers{                                                   
         hvis(PERCFG &0x02){                                    
            P1SEL |=0xC0;                                      
         }ellers{                                               
            P0SEL |=0x30;                                      
         }                                                      
      }                                                         
                                                               
      U##uart##GCR = BAUD_E((baudRate),CLKSPD);                 
      U##uart##BAUD = BAUD_M(baudRate);                        
                                                               
      U##uart##CSR |=0x80;                                    
                                                               
      U##uart##CSR |= mottaMuliggjør;                           
                                                               
      U##uart##UCR |= ((alternativer) |0x80);                       
   }mens(0)
     
//Verdien av parameteren receiveEnable:
#defineUART_RECEIVE_ENABLE 0x40   //Mottak av tillatelse
#defineUART_RECEIVE_DISABLE 0x00   
     
//Verdien av parameteralternativene:
#defineFLOW_CONTROL_ENABLE 0x40   //Flytkontroll
#defineFLOW_CONTROL_DISABLE 0x00


#defineEVEN_PARITY 0x20   //Sporadisk verifisering
#defineODD_PARITY 0x00   //Merkelig verifisering


#defineNINE_BIT_TRANSFER 0x10   //9-byte overføring
#defineEIGHT_BIT_TRANSFER 0x00   //8-bytes overføring


#definePARITY_ENABLE 0x08   //Paritetssjekk-aktivering
#definePARITY_DISABLE 0x00

#defineTWO_STOP_BITS 0x04   //2-posisjons stoppposisjon
#defineONE_STOP_BITS 0x00   //1 stoppposisjon


#defineHIGH_STOP 0x02   //Stoppnivået er høyt
#defineLOW_STOP 0x00   //Stoppposisjonen er lav
     
#defineHIGH_START 0x01   //Startbitnivået er høyt
#defineLOW_START 0x00   //Startbitnivået er lavt


//Seriellport sender tegn
#defineUART_SEND(uart,data)            
   gjøre{                                 
     mens(U##uart##CSR &0x01);        
       U##uart##DBUF = data;            
   }mens (0)
#defineUART0_SEND(data) UART_SEND(0,data)
#defineUART1_SEND(data) UART_SEND(1,data)


//Seriellport mottar tegn
#defineUART_RECEIVE(uart,data)         
   gjøre{                                 
     mens(! (U##uart##CSR&0x04));      
       data=U##uart##DBUF;              
   }mens(0)
#defineUART0_RECEIVE(data) UART_RECEIVE(0,data)
#defineUART1_RECEIVE(data) UART_RECEIVE(1,data)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Strøm- og klokkestyring
**********************************************************
*/
//Få tak i klokkekrysset
#defineCLKSPD (CLKCON & 0x07)


//Sett strømmodusen
#defineSET_POWER_MODE(modus)                  
   gjøre{                                       
      hvis(modus ==0) { SØVN &= ~0x03; }
      ellers hvis(modus ==3) { SØVN |=0x03;  }
      ellers{ SLEEP &= ~0x03; SLEEP |= modus;  }
      PCON |=0x01;                           
      ASM("NOP");                              
   }mens (0)


//Parametermodusen settes til følgende verdier:
#definePOWER_MODE_0 0x00  
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03


//Brukes til å oppdage stabiliteten til høyfrekvente RC-oscillatorer
#defineHIGH_FREQUENCY_RC_OSC_STABLE (SØVN & 0x20)


//Brukes til å detektere den stabile tilstanden til krystalloscillatoren
#defineXOSC_STABLE (SØVN & 0x40)


//Få tikkfrekvensverdien til timeren
#defineTICKSPD ((CLKCON & 0x38) >> 3)


//Still inn hovedklokkefrekvensen
#defineSET_MAIN_CLOCK_SOURCE(kilde)
   gjøre{                              
      hvis(kilde) {                    
        CLKCON |=0x40;               
        mens(! HIGH_FREQUENCY_RC_OSC_STABLE);
        hvis(TICKSPD ==0){            
          CLKCON |=0x08;            
        }                             
        SØVN |=0x04;               
      }                              
      ellers{                          
        SOV &= ~0x04;               
        mens(! XOSC_STABLE);         
        ASM("NOP");                  
        CLKCON &= ~0x47;              
        SØVN |=0x04;               
      }                              
   }mens (0)


//Verdien til parameterkilden er:
#defineCRYSTAL 0x00   //Krystalloscillator
#defineRC 0x01   //RC-oscillator
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Timer 1
**********************************************************
*/
//Timer 1 lar telleoverløpet avbryte
#defineTIMER1_ENABLE_OVERFLOW_INT(Val)
   (TIMIF = (val) ? TIMIF |0x40: TIMIF & ~0x40)


//Sett overflow-avbruddsflagget for timer 1
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))


//Timer 1 starter
#defineTIMER1_RUN(verdi) (T1CTL = (verdi) ? T1CTL|0x02 : T1CTL&~0x03)


//Sett klokkedelingen for timeren
#defineSET_TIMER_TICK(verdi) do{ CLKCON = ((CLKCON & (~0x38)) | verdi); } mens(0)


//Verdien av verdien er:
#defineTIMER1_TICK_32M 0x00  //32 MHz
#defineTIMER1_TICK_16M 0x08  //16 MHz, standardverdien for systemtilbakestilling
#defineTIMER1_TICK_8M 0x10  //8 MHz
#defineTIMER1_TICK_4M 0x18  //4 MHz
#defineTIMER1_TICK_2M 0x20  //2 MHz
#defineTIMER1_TICK_1M 0x28  //1 MHz
#defineTIMER1_TICK_500k 0x30  //500kHz
#defineTIMER1_TICK_250k 0x38  //250kHz

//Sett TICK-delefilteret for timer 1
#defineSET_TIMER1_TICKDIV(verdi)  
   gjøre{                             
     T1CTL &= ~0x0c;               
     T1CTL |= verdi;               
   }mens (0)
      
//hvor verdien er:      
#defineTIMER1_TICKDIV_1 0x00   //1. divisjon
#defineTIMER1_TICKDIV_8 0x04   //8-veis frekvens
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c


//Sett timerens overløpsperiode
#defineSET_TIMER1_PERIOD(verdi)
   gjøre{                           
     T1CC0H = HIGH_BYTE(verdi);  
     T1CC0L = LOW_BYTE(verdi);   
   }mens (0)
     
//Sett driftsmodusen til Timer 1
#defineSET_TIMER1_MODE(modus)  
   gjøre{                        
     T1CTL = ((T1CTL & (~0x03)) | modus);           
   }mens (0)


//Verdien av modus er:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Vakthund
**********************************************************
*/
//Sett overløpsperioden for watchdog-timeren
#defineWDT_SET_TIMEOUT_PERIOD(timeout)
   gjøre{ WDCTL &= ~0x03; WDCTL |= timeout; }mens (0)


//Verdien av parameter-timeouten er:
#defineSEC_1 0x00     //etter 1 sekund
#defineM_SEC_250 0x01     //etter 250 ms
#defineM_SEC_15 0x02     //Etter 15 ms
#defineM_SEC_2 0x03     //Etter 2 MS


//Hundematingsprosedyrer
#defineWDT_RESET() do {           
   WDCTL = (WDCTL & ~0xF0) |0xA0;
   WDCTL = (WDCTL & ~0xF0) |0x50;
} mens (0)


//Start/stopp vaktbikkje-timeren
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]

[url=] [/url]
/***********************************************************
                       ADC
**********************************************************
*/
//Konfigurer en enkelt ADC
#defineADC_SINGLE_CONVERSION(innstillinger)
   gjøre{ ADCCON3 = innstillinger; }mens(0)

//Parameterinnstillingen består av følgende kombinasjoner:
//Referansespenning
#defineADC_REF_1_25_V 0x00     //Intern 1,25V referansespenning
#defineADC_REF_P0_7 0x40     //Ekstern referansespenning på AIN7-pinnen
#defineADC_REF_AVDD 0x80     //AVDD_SOC Nåler
#defineADC_REF_P0_6_P0_7 0xC0     //AIN6-AIN7 Ekstern referansespenning for differensialinnganger


//Samplingsfrekvens
#defineADC_8_BIT 0x00     //8. plass
#defineADC_10_BIT 0x10     //10. plass
#defineADC_12_BIT 0x20     //12. plass
#defineADC_14_BIT 0x30     //14. plass


//Kom inn i kanalen
#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     //Land
#defineADC_TEMP_SENS 0x0E     //Temperatursensor i chipen
#defineADC_VDD_3 0x0F     //VDD/3




ADC-konverteringen er fullført
#define ADC_SAMPLE_READY() (ADCCON1 & 0x80)

#endif
//启动ADC转化
#define ADC_START()
  do { ADCCON1 |= 0x40; } mens (0)//Velg trigger-modusen til ADC-en som manuell (dvs. ADC_SAMPLE_READY)
#defineADC_STOP()  
  gjøre{ ADCCON1 |=0x30; }mens (0)[url=] [/url]


(2) Funksjonelt modullag
  • module.h
  • module.c
[url=] [/url]
/***********************************************************
*Filnavn: module.h
*Forfatter: hustlzp
*Dato: 6. mars 2011
*Versjon: 1.0
*Funksjonsbeskrivelse: Funksjonelt modullag-headerfil
*Funksjonsliste: void led_init()
            tomrom timer1_init()
            tomrom uart0_init(tomrom);
            void Uart0SendString (usignert tegn *s);
            flyt adc_start(tomrom)
            void get_temperature(usignert char *output, flytetemperatur);
            tomrom watchdog_init(tomrom);
*Modifiserte opptegnelser:
**********************************************************
*/

#ifndef MODULE_H
#defineMODULE_H


#include"hal.h"


/***********************************************************
                        LED
**********************************************************
*/
//Definer LED-pinnene
#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   

//LED-lys og av
#defineLED_OFF 1
#defineLED_ON 0

//LED-initialisering
Tomromled_init(Tomrom);




/***********************************************************
                        timer1
**********************************************************
*/
//Brukes til å sette overløpsperioden for timeren
#defineTIMER1_OVF_2SEC 0xF424   //2-ere
#defineTIMER1_OVF_1SEC 0x7A12   //1-ere
#defineTIMER1_OVF_dot5SEC 0x3D09   //0,5 sekunder   

//Timer 1 initialiserer
Tomrom  timer1_init(Tomrom);
                  

/***********************************************************
                        UART0
**********************************************************
*/
//UART0-initialisering
Tomrom  uart0_init(Tomrom);                    

//Seriellport overføringsstreng
Tomrom  Uart0SendString(usignert)Char*s);
   

/***********************************************************
                        ADC-14
**********************************************************
*/
//Brukes til å konvertere dataene oppnådd av ADC-en til Celsius-temperatur
#defineADC_TO_CELSIUS(temp) (temp * 0,06229 - 311,43)

//Start ADC-konvertering
Floatadc_start(Tomrom);

//Ombygging
Tomrom  get_temperature (usignertChar*output,Floatmidlertidig);


/***********************************************************
                        WatchDog
**********************************************************
*/
//Initialisering av vakthund
Tomrom  watchdog_init(Tomrom);                 

#endif
[url=] [/url]

[url=] [/url]
/***********************************************************
*Filnavn: module.c
*Forfatter: hustlzp
*Dato: 2011.03.11
*Versjon: 1.0
*Funksjonsbeskrivelse: Kildefil for funksjonelt modullag
*Funksjonsliste: (utelatt)
*Modifiserte opptegnelser:
**********************************************************
*/


#include"module.h"


/***********************************************************
*Funksjonsnavn: led_init
*Funksjonsfunksjon: LED-initialisering
*Inngangsparametere: Ingen
*Eksportparametere: Ingen
**********************************************************
*/
Tomromled_init(Tomrom)
{
  //Konfigurer P1.0, P1.1, P1.2 og P1.3 som generelle I/O-porter
  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);
  
  //Konfigurer P1.0, P1.1, P1.2 og P1.3 som utganger
  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;
}


/***********************************************************
*Funksjonsnavn: timer1_init
* Funksjonsfunksjon: Timer 1 initialisering
*Inngangsparametere: Ingen
*Eksportparametere: Ingen
**********************************************************
*/
Tomromtimer1_init(Tomrom)
{
  INT_GLOBAL_ENABLE(INT_ON);                 //Åpne den globale avbrytelsen
  
  INT_ENABLE(INUM_T1, INT_ON);               //Åpen T1-avbrudd

  TIMER1_ENABLE_OVERFLOW_INT(INT_ON);        //Åpen T1-telling overløpsavbrudd
  
  SET_TIMER_TICK(TIMER1_TICK_4M);            //Sett timeren TICK til 4 MHz
  
  SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);        //Sett telleperioden for T1 til 2
  
  SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128);   //Sett klokkekrysset for T1 til 128
  
  SET_TIMER1_MODE(TIMER1_MODE_MODULE);      //Sett kjøremodusen til T1 til modul
}


/***********************************************************
*Funksjonsnavn: uart0_init
*Funksjonsfunksjon: Seriellport UART0-initialisering
*Inngangsparametere: Ingen
*Eksportparametere: Ingen
**********************************************************
*/
Tomromuart0_init(Tomrom)
{
  //Velg UART-lokasjonen
  IO_PER_LOC_UART0_AT_PORT0_PIN2345();
  
  //Konfigurer UART: Mottak tillatt, 115200 bps, en-bits stoppbit, ingen paritet
  UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);

  //Åpne den totale avbrytelsen
  INT_GLOBAL_ENABLE(INT_ON);      

  //Åpne serieport 0 for å motta avbrudd
  INT_ENABLE(INUM_URX0, INT_ON);   
}


/***********************************************************
*Funksjonsnavn: Uart0SendString
* Funksjonsfunksjon: Timer 1 initialisering
*Inngangsparameter: usignert karakter *s
            Strengen du vil sende
*Eksportparametere: Ingen
**********************************************************
*/
TomromUart0SendString(usignert)Char*s)
{
  mens(*s !=0)         
    UART0_SEND(*s++);
}


/***********************************************************
*Funksjonsnavn: adc_start
*Funksjonsfunksjon: Start ADC-konvertering
*Inngangsparametere: Ingen
*Eksportparameter: flyt
            Temperaturverdien i nettbrettet
**********************************************************
*/
Floatadc_start(Tomrom)
{
  UsignertInttemp;
  
  //Referansespenningen er 1,25V, prøvetakingsnøyaktigheten er 14 biter, og konverteringsmålet er den innebygde temperatursensoren
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  
  ADC_STOP();                           //Sett trigger-metoden for ADC-konvertering til manuell
  
  ADC_START();                           //Start ADC-konvertering
  
  mens(! ADC_SAMPLE_READY());            //Vent til konverteringen er ferdig
  
  temp = ADCL >>2;                     //Lagre konverteringen resulterer i midlertidig
  temp |= (((usignertInt) ADCH) <<6);
  
  TilbakeADC_TO_CELSIUS(midlertidig);           //Returnerer den faktiske temperaturverdien etter konvertering
}


/***********************************************************
*Funksjonsnavn: get_temperature
*Funksjonsfunksjon: Behandle temperaturverdien og lagre den i tegnarrayet for seriell utdata
*Inngangsparameter: usignert karakter *utdata
            Brukes til å lagre den konverterte temperaturverdien
            Flytetemperatur
            Celsius-temperaturverdi
*Eksportparametere: Ingen
**********************************************************
*/
Tomromget_temperature (usignertChar*output,Floatmidlertidig)
{
  Output[0] = (usignertChar(midlertidig) /10 + 48;         //Ti steder
  Output[1] = (usignertChar(midlertidig) %10 + 48;         //ensifret antall
  Output[2] ='.';                                      //Desimalpunkt
  Output[3] = (usignertChar(midlertidig)10) %10 + 48;      //Tiende
  Output[4] = (usignertChar(midlertidig)100) %10 + 48;      //Prosentil
  Output[5] ='';                                    //Strengendifiere
}


/***********************************************************
*Funksjonsnavn: watchdog_init
*Funksjonsfunksjon: Vakthund-initialisering
*Inngangsparametere: Ingen
*Eksportparametere: Ingen
**********************************************************
*/
Tomromwatchdog_init(Tomrom)
{
  WDT_SET_TIMEOUT_PERIOD(SEC_1);   //Sett timeout-tiden til 1 sekunder
  WDT_ENABLE();                    //Start vakthunden
}
[url=] [/url]


(3) Applikasjonslag
  • main.c
[url=] [/url]
/*******************************************************************
Filnavn: main.c
Forfatter: hustlzp
Dato: 2011.03.11
Versjon: 1.0
Funksjonsbeskrivelse: Masterprogramfil
Funksjonsliste: (utelatt)
Modifikasjonsregister:
******************************************************************
*/


#include




/********************************************************************
                             Avbruddstjenesteprosedyrer
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektor=T1_VECTOR
__interrupt void T1_ISR(void)
{
  EA=0;                                   Porten er avbrutt
  
  led2 = LED_ON;                          
  
  get_temperature(utdata,adc_start());    Konverter temperaturverdien til et array av tegn som skal utdatas
   
  Uart0SendString (output);                Utgangstemperaturverdi
  Uart0SendString("°C");  


  led2


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

  motta = U0DBUF;   
  
  if(type==1) // type=1, noe som indikerer at det mottatte tegnet brukes til å sette timeroverløpsperioden
  {
    type=0;
    Bytte (motta)
    {
      tilfelle '0': // Timeroverløpsperioden er 0,5 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
        pause;
      }
      tilfelle '1': // Timer overflow-periode er 1 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
        pause;
      }
      tilfelle '2': // Timer-overløpsperioden er 2 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
        pause;         
      }
    }
  }
  else if(type==2) // type=2, noe som indikerer at de mottatte tegnene brukes til søvnkontroll
  {
    type=0;
    led1 = LED_OFF;
    led2 = LED_OFF;
    led3 = LED_OFF;
    Bytte (motta)
    {
      Case '1': // Gå inn strømmodus PM1
      {
        SET_POWER_MODE(1);  
        pause;
      }
      Case '2': // Gå inn i strømmodus PM2
      {
        SET_POWER_MODE(2);  
        pause;
      }
      Kabinett '3': //Gå inn i strømmodus PM3
      {
        SET_POWER_MODE(3);  
        pause;
      }
    }
  }
  else if(type==0) // type=0, som indikerer at det mottatte tegnet er typen kontrollkommando: @ eller $
  {
    if(receive=='@')  
    {
      type=1;     '@' mottas for å indikere at neste tegn brukes til å sette overløpsperioden
    }
    else if(receive=='$')
    {
      type=2;     '$' mottas, noe som indikerer at neste tegn brukes til systemsøvnkontroll
    }
  }
  
  led3 = LED_OFF;
   
  EA=1;
}
=LED_OFF;
  
  TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR);   Fjern avbruddsskiltet
  
  EA=1;                                   Åpen avbrytelse  
}
/* 主函数
-------------------------------------------------------*/
Void main(void)
{
  SET_MAIN_CLOCK_SOURCE(KRYSTALL);  Sett systemklokken til 32 MHz krystalloscillator
  
  led_init();                      LED-initialisering
  
  uart0_init();                    Seriellport UART0-initialisering
  
  timer1_init();                   Timer 1 initialiserer
  
  watchdog_init();                 Initialisering av vakthund
  
  mens(1)
  {
    WDT_RESET();                   Mat hunden hele tiden
  }
}/********************************************************************
                            Hovedprogram   
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
usignert char-output[6]={0};       Temperaturdata lagres for enkel seriell utgang
usignert char mottar;             Lagre de mottatte tegnene
usignert tegn type=0;              Typeflagget til det mottatte tegnet settes til 0/1/2"module.h"[url=] [/url]


5. Testing
Åh~ Koden er endelig limt inn, det er virkelig utmattende, la oss teste dette lille systemet:
(1) Tidsbegrenset prøvetaking
Åpne den serielle porten, start IAR-feilsøking, og finn at LED1 er på, og temperaturverdien på serielportverktøyet genereres kontinuerlig, og prøvetakingsintervallet er bestemt til å være 2 sekunder:
(2) Kontroll av prøvetakingsintervaller
Skriv inn "@1" i serieportverktøyet, og test deretter prøvetakingsintervallet, og finn at det har blitt 1-ere; Skriv inn "@0" og prøvetakingsintervallet har endret seg til 0,5 sekunder.
(3) Søvnkontroll
Skriv inn «$1» i serieportverktøyet og se at alle LED-lysene er av og temperaturprøvingen har stoppet:
Etter testing fungerer systemet normalt og stabilt, og oppfyller i hovedsak kravene.
Elever som trenger kildekodeKlikk her for å laste ned
6. Konklusjon
Denne artikkelen tar et noe omfattende eksperiment som eksempel for å vise hvordan man kan integrere CC2430 on-chip-ressurser for å skrive et relativt standardisert småsystem. Om noen dager skal jeg ta meg tid til å skrive en enkel brukermanual for hal.h slik at jeg og alle andre enkelt kan bruke CC2430.
Neste steg er å fullføre forskningen min på CC2430 sine on-chip-ressurser og vie meg til å lære TI Z-Stack protokollstakken~
Blogginnlegget i denne serien er nå avsluttet, men Zigbees reise vil fortsette. Utsikten foran oss er ukjent, men jeg tror forfatteren vil overvinne hindringer med alle og smake på opp- og nedturene, og det vil bli gevinster.
Følg med: «Bli med i TI Z-Stack»-blogginnlegg!















Foregående:Zigbee Journey (9): Flere viktige grunnleggende CC2430-eksperimenter – systematisk søvn og avbrutt våkenhet
Neste:I dag er det Halloween, hvordan skal du underholde?
Publisert på 31.10.2014 08:04:14 |
Tilgi meg for at jeg ikke forstår noe
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com