Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 10835|Svar: 1

Zigbee Journey (10): Omfattande experiment - Temperaturövervakningssystem baserat på CC2430

[Kopiera länk]
Publicerad på 2014-10-30 23:47:44 | | | |
Efter att ha skrivit "Zigbee Journey (9)" den 3 mars planerade författaren ursprungligen att omedelbart börja skriva ett litet experiment om "temperaturövervakningssystem" som en sammanfattning av en serie spridda kunskapspunkter tidigare. Jag insåg dock också att även om varje tidigare småexperiment beskrevs i detalj, kunde den normativa och strukturella karaktären av dess kod sägas vara outhärdlig. Eftersom det är en sammanfattning bör vi göra framsteg på originalet, snarare än att mekaniskt pussla ihop de tidigare små kunskapspunkterna. Därför lade jag min ursprungliga plan på is, tog mig tid att lära mig de allmänna teknikerna för inbäddad utveckling och skrev två essäerInbäddad C51-programmeringsspecifikation" och "Hierarki av inbäddad projektkodstruktur》。 Denna logg är inte bara en sammanfattning av Zigbees första resa, utan inkluderar också författarens lärande erfarenheter de senaste dagarna, i hopp om att vara till hjälp för Zigbee-nybörjare.
Fulltexten är organiserad enligt den grundläggande processen för mjukvaruutveckling: kravanalys, dispositionsdesign, detaljerad design, kodningsimplementering och testning.
1. Efterfrågeanalys
Efter diskussion mellan "kunden" och "utvecklaren" fastställdes följande systemfunktionsbeskrivning:
… Den aktuella rumstemperaturen samlas in av noder baserade på CC2430, och dess temperaturvärden kan övervakas via en dator
… CC2430-noden måste ha en viss grad av stabilitet och kan automatiskt återgå till normalt tillstånd
… Nodens samplingsintervall och strömhantering kan styras av en PC
2. Konturdesign
Enligt ovanstående kravanalys kan vi dela in systemet i två moduler:CC2430-nodochPC
  [CC2430-nod]  
… Externa parametrar kan samlas in regelbundet och skickas till datorn
… Automatisk återställning när maskinen stängs av
… Kommandon från datorn kan tas emot och bearbetas därefter: ändra provintervallet/strömhanteringen
  [PC]  
… C-maskinen tar emot och visar data via det seriella portverktyget
… Instruktioner kan skickas till mikrokontrollern via verktyget för seriella portar för att styra dess samplingshastighet och strömhantering
3. Detaljerad design
(1) Kodstruktur
Lagerindelningen av kodstrukturen i detta system har faktiskt beskrivits i essän "Hierarki av inbäddad projektkodstruktur", och kopian är följande:
(1) Hårdvaruabstraktionslager
      [ioCC2430.h] (System inkluderat)Alla SFR- och avbrottsvektorer för CC2430 är definierade
      [hal.h] Inkluderar gemensamma typdefinitioner, vanliga tilldelningsmakron och gemensam konfiguration av CC2430-on-chip-resurser (I/O, seriell kommunikation, ADC, timer, strömhantering etc.)
  (2) Funktionellt modullager
      [module.h] definierar resurser på chipet (timers, I/O), expansionsmoduler utanför kretsen (LED) och deklarationer av relaterade funktioner
      [module.cImplementera initieringen av varje modul (LED).
  (3) Applikationslagret
      [main.cSe hal.h, ioCC2430.h och module.h för att uppnå specifika applikationskrav såsom temperaturinsamling, kommunikation med PC samt avstängning och återställning
(2) Implementeringsmetoder för varje modul
Enligt modulerna som delas upp enligt dispositionen kan det intrinsiska systemet delas in i två huvudmoduler:CC2430-nodochPC
Eftersom det finns seriella portkommunikationsverktyg på PC:n kan dess funktioner uppfylla kraven, så vi behöver inte göra denna del av PC:n och det finns inget behov av att analysera den. Låt oss prata om sektion CC2430 nedan
Implementeringsmetoden för varje delfunktion av punkten:
… Använd timerns räkningsöverflödesavbrott för att trigga tidssampling
… UART0-läget med seriell port överför temperaturdata till en PC
… CC2430:s inbyggda watchdog-krets används för att genomföra systemets automatiska återställningsfunktion
… Den seriella porten används för att ta emot avbrott för att fånga och svara på kontrollkommandon från datorn
1) Om mottaget@Tecknet är kontrollkommandot för samplingsintervallet, följt av ett nummer som anger samplingsintervallet: 0-0,5 sekunder, 1-1 sekunder, 2-2 sekunder
如:@0,表示每隔0.5秒采样一次。
2) Om mottaget$  Tecknet är sömnkontrollkommandot, följt av en siffra som anger strömläget
Till exempel: 3 dollar, vilket betyder att sätta systemet i strömläge 3.
(3) Programflödesschema
  • Masterprogramflödesschema
  • Timer 1 Överflödesavbrottsprogram flödesschema
  • Flödesschema för seriell portmottagarprocedur för avbrott




4. Kodningsimplementering
(1) Hårdvaruabstraktionslager
Hårdvaruabstraktionslagret inkluderar ioCC2430.h och hal.h. Eftersom det tidigare systemet följer med det, kommer det inte att listas.
Följande är en lista över allt innehåll i hal.h (eftersom denna fil är för lång och ser besvärlig ut, kommer jag att visa den i moduler):
  • Huvud
  • I/O-portar
  • Avbrutet
  • Seriellport
  • Ström- och klockhantering
  • Timer
  • Vakthund
  • ADC
[url=] [/url]
/***********************************************************
*Filnamn: hal.h
*Författare: hustlzp
*Datum: 8 mars 2011
*Utgåva: 1.1
*Funktionsbeskrivning: Hårdvaruabstraktionslager
*Modifierade register:
**********************************************************
*/


#ifndef HAL_H
#defineHAL_H


#include


/***********************************************************
                       Vanliga typdefinitioner
**********************************************************
*/
typedef osigneradchar   BYTE;
typedef osigneradint    WORD;
typedef osigneradLång   DWORD;



/***********************************************************
                       Vanligt använda makrodefinitioner
**********************************************************
*/

//8 platser högre
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))


//8 platser lägre
#defineLOW_BYTE(a) ((BYTE) ((WORD)(a)))


//Tilldelning
#defineSET_WORD(regH, regL, ord)  
   göra{                           
      (regH)=HIGH_BYTE(ord);     
      (regL)=LOW_BYTE(ord);      
   }medan(0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       I/O-portar
**********************************************************
*/
/*Konfigurera I/O-portens riktning
-----------------------------------------
*/
#defineIO_DIR_PORT_PIN(port, nål, regi)  
   göra{                                 
      om(dir == IO_OUT)                 
         P##port##DIR |= (0x01<<(nål);  
      annars                              
         P##port##DIR &= ~(0x01<<(nål);
   }medan(0)



//Värdet på parameter-diren är:
#defineIO_IN 0
#defineIO_OUT 1


/*Konfigurera inmatningsläget för I/O-porten
-----------------------------------------
*/
#defineIO_IMODE_PORT_PIN(port, pin, imode)
   göra{                                    
      om(imode == IO_IMODE_TRI)            
         P##port##INP |= (0x01<<(nål);     
      annars                                 
         P##port##INP &= ~(0x01<<(nål);   
   }medan (0)



#define IO_PUD_PORT(babord, pud)        
   gör {                              
      om (pud == IO_PULLDOWN)         
         P2INP |= (0x01 << (port+5));
      annars                           
         P2INP &= ~(0x01 << (port+5));
   } medan (0)


Värdet på parametern PUD är:
#define IO_PULLUP 0 // Dra upp
#define IO_PULLDOWN 1 // Dra ner


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

#define IO_FUNC_PORT_PIN(port, pin, func)  
   gör {                                    
      if((port == 2) && (pin == 3)){      
         om (func) {                       
            P2SEL |= 0x02;                 
         } annars {                          
            P2SEL &= ~0x02;               
         }                                 
      }                                    
      annars if((port == 2) && (pin == 4)){  
         om (func) {                       
            P2SEL |= 0x04;                 
         } annars {                          
            P2SEL &= ~0x04;               
         }                                 
      }                                    
      annars{                                
         om (func) {                       
            P##port##SEL |= (0x01<<(nål));
         } annars {                          
            P##port##SEL &= ~(0x01<<(nål));
        }                                 
      }                                    
   } medan (0)


Värdet på parameterfunken är:
#define IO_FUNC_GIO 0 // Allmän I/O
#define IO_FUNC_PERIPH 1 // Kringutrustning I/O


Konfigurera platsen för den perifera I/O
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } medan (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } medan (0)

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

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

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

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

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

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

//Värdet på parametern imode är:
#defineIO_IMODE_PUD 0   //Dra upp/dra ner
#defineIO_IMODE_TRI 1   //Tre delstater[url=] [/url]

[url=] [/url]
/***********************************************************
                       Avbrutet
**********************************************************
*/
//För av/på-avbrott
#defineINT_ON 1
#defineINT_OFF 0


//Används för att placera/rensa avbrottsflaggor
#defineINT_SET 1
#defineINT_CLR 0


//Globala avbrottsinställningar
#defineINT_GLOBAL_ENABLE(på) EA=(!! på)


//Definiera brottet
#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


/*Tillåtna avbrott
-----------------------------------------
*/
#defineINT_ENABLE(inum, på)                        
   göra{                                             
      om      (inum==INUM_RFERR) { RFERRIE = on; }  
      annars om(inum==INUM_ADC)   { ADCIE = på; }  
      annars om(inum==INUM_URX0)  { URX0IE = on; }  
      annars om(inum==INUM_URX1)  { URX1IE = on; }  
      annars om(inum==INUM_ENC)   { ENCIE = på; }  
      annars om(inum==INUM_ST)    { STIE = på; }  
      annars om(inum==INUM_P2INT) { (på) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
      annars om(inum==INUM_UTX0)  { (på) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
      annars om(inum==INUM_DMA)   { DMAIE = på; }  
      annars om(inum==INUM_T1)    { T1IE = på; }  
      annars om(inum==INUM_T2)    { T2IE = på; }  
      annars om(inum==INUM_T3)    { T3IE = på; }  
      annars om(inum==INUM_T4)    { T4IE = på; }  
      annars om(inum==INUM_P0INT) { P0IE = på; }  
      annars om(inum==INUM_UTX1)  { (på) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
      annars om(inum==INUM_P1INT) { (på) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
      annars om(inum==INUM_RF)    { (på) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
      annars om(inum==INUM_WDT)   { (på) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
   }medan (0)


/*Ställ in avbrottsprioritet
-----------------------------------------
*/
#defineINT_PRIORITY(grupp, pri)                     
   göra{                                               
      om(pri ==0) { IP0 &= ~group; IP1 &= ~grupp; }
      om(pri ==1) { IP0 |= grupp; IP1 &= ~grupp; }
      om(pri ==2) { IP0 &= ~group; IP1 |= grupp; }
      om(pri ==3) { IP0 |= grupp; IP1 |= grupp; }
   }medan (0)

//Värdet på parametern pri är: 0/1/2/3 (högsta prioritet)


//Värdet på parametergruppen är:
#defineRFERR_RF_DMA 0x01//Grupp IP0
#defineADC_P2INT_T1 0x02//Grupp IP1
#defineURX0_UTX0_T2 0x04//Grupp IP2
#defineURX1_UTX1_T3 0x08//Grupp IP3
#defineENC_P1INT_T4 0x10//Grupp IP4
#defineST_WDT_P0INT 0x20//Grupp IP5


/*Hämta avbrottsflaggan
-----------------------------------------
*/
#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                                             
)


/*Sätt avbrottsflaggan
-----------------------------------------
*/
#defineINT_SETFLAG(inum, f)                     
   göra{                                          
      om      (inum==INUM_RFERR) { RFERRIF= f; }
      annars om(inum==INUM_ADC)   { ADCIF = f; }
      annars om(inum==INUM_URX0)  { URX0IF = f; }
      annars om(inum==INUM_URX1)  { URX1IF = f; }
      annars om(inum==INUM_ENC)   { ENCIF_1 = ENCIF_0 = f; }
      annars om(inum==INUM_ST)    { STIF = f;  }
      annars om(inum==INUM_P2INT) { P2IF = f;  }
      annars om(inum==INUM_UTX0)  { UTX0IF= f;  }
      annars om(inum==INUM_DMA)   { DMAIF = f;  }
      annars om(inum==INUM_T1)    { T1IF = f;  }
      annars om(inum==INUM_T2)    { T2IF = f;  }
      annars om(inum==INUM_T3)    { T3IF = f;  }
      annars om(inum==INUM_T4)    { T4IF = f;  }
      annars om(inum==INUM_P0INT) { P0IF = f;  }
      annars om(inum==INUM_UTX1)  { UTX1IF= f;  }
      annars om(inum==INUM_P1INT) { P1IF = f;  }
      annars om(inum==INUM_RF)    { (f) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
      annars om(inum==INUM_WDT)   { WDTIF = f;  }
   }medan (0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Seriellport
**********************************************************
*/
//Värdet på BAUD_E motsvarar olika baudhastigheter
#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  )


//Värdet på BAUD_M motsvarar olika baudhastigheter
#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 portkonfiguration i UART-läge
-----------------------------------------
*/
#defineUART_SETUP(uart, receiveEnable, baudRate, optioner)      
   göra{                                                         
      om((uart) ==0){                                          
         om(PERCFG &0x01){                                    
            P1SEL |=0x30;                                      
         }annars{                                               
            P0SEL |=0x0C;                                      
         }                                                      
      }                                                         
      annars{                                                   
         om(PERCFG &0x02){                                    
            P1SEL |=0xC0;                                      
         }annars{                                               
            P0SEL |=0x30;                                      
         }                                                      
      }                                                         
                                                               
      U##uart##GCR = BAUD_E((baudRate),CLKSPD);                 
      U##uart##BAUD = BAUD_M(baudRate);                        
                                                               
      U##uart##CSR |=0x80;                                    
                                                               
      U##uart##CSR |= mottagaMöjliggöra;                           
                                                               
      U##uart##UCR |= ((alternativ) |0x80);                       
   }medan(0)
     
//Värdet på parametern mottagaMöjliggör:
#defineUART_RECEIVE_ENABLE 0x40   //Att få tillstånd
#defineUART_RECEIVE_DISABLE 0x00   
     
//Värdet av parameteralternativen:
#defineFLOW_CONTROL_ENABLE 0x40   //Flödeskontroll
#defineFLOW_CONTROL_DISABLE 0x00


#defineEVEN_PARITY 0x20   //Tillfällig verifiering
#defineODD_PARITY 0x00   //Underlig verifiering


#defineNINE_BIT_TRANSFER 0x10   //9-bytes överföring
#defineEIGHT_BIT_TRANSFER 0x00   //8-bytes överföring


#definePARITY_ENABLE 0x08   //Paritetskontrollaktivering
#definePARITY_DISABLE 0x00

#defineTWO_STOP_BITS 0x04   //2-positioners stoppläge
#defineONE_STOP_BITS 0x00   //1 stoppläge


#defineHIGH_STOP 0x02   //Stoppnivån är hög
#defineLOW_STOP 0x00   //Stopppositionen är låg
     
#defineHIGH_START 0x01   //Startbitnivån är hög
#defineLOW_START 0x00   //Startbitnivån är låg


//Seriellport skickar tecken
#defineUART_SEND(uart, data)            
   göra{                                 
     medan(U##uart##CSR &0x01);        
       U##uart##DBUF = data;            
   }medan (0)
#defineUART0_SEND(data) UART_SEND(0,data)
#defineUART1_SEND(data) UART_SEND(1,data)


//Seriellporten tar emot tecken
#defineUART_RECEIVE(uart,data)         
   göra{                                 
     medan(! (U##uart##CSR&0x04));      
       data=U##uart##DBUF;              
   }medan(0)
#defineUART0_RECEIVE(data) UART_RECEIVE(0,data)
#defineUART1_RECEIVE(data) UART_RECEIVE(1,data)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Ström- och klockhantering
**********************************************************
*/
//Skaffa klock-crossovern
#defineCLKSPD (CLKCON & 0x07)


//Ställ in strömläget
#defineSET_POWER_MODE(läge)                  
   göra{                                       
      om(läge ==0) { SLEEP &= ~0x03; }
      annars om(läge ==3) { SÖMN |=0x03;  }
      annars{ SOV &= ~0x03; SLEEP |= läge;  }
      PCON |=0x01;                           
      ASM("NOP");                              
   }medan (0)


//Parameterläget sätts till följande värden:
#definePOWER_MODE_0 0x00  
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03


//Används för att upptäcka stabiliteten hos högfrekventa RC-oscillatorer
#defineHIGH_FREQUENCY_RC_OSC_STABLE (SÖMN & 0x20)


//Används för att detektera kristalloscillatorns stabila tillstånd
#defineXOSC_STABLE (SOV & 0x40)


//Få tickfrekvensvärdet för timern
#defineTICKSPD ((CLKCON & 0x38) >> 3)


//Ställ in huvudklockfrekvensen
#defineSET_MAIN_CLOCK_SOURCE(källa)
   göra{                              
      om(källa) {                    
        CLKCON |=0x40;               
        medan(! HIGH_FREQUENCY_RC_OSC_STABLE);
        om(TICKSPD ==0){            
          CLKCON |=0x08;            
        }                             
        SÖMN |=0x04;               
      }                              
      annars{                          
        SOV &= ~0x04;               
        medan(! XOSC_STABLE);         
        ASM("NOP");                  
        CLKCON &= ~0x47;              
        SÖMN |=0x04;               
      }                              
   }medan (0)


//Värdet på parameterkällan är:
#defineKRISTALL 0x00   //Kristalloscillator
#defineRC 0x01   //RC-oscillator
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Timer 1
**********************************************************
*/
//Timer 1 tillåter att räkneöverskottet avbryts
#defineTIMER1_ENABLE_OVERFLOW_INT(Val)
   (TIMIF = (val) ? TIMIF |0x40: TIMIF & ~0x40)


//Ställ in överflödesavbrottsflaggan för timer 1
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))


//Timer 1 startar
#defineTIMER1_RUN(värde) (T1CTL = (värde) ? T1CTL|0x02 : T1CTL&~0x03)


//Ställ in klockdelningen för timern
#defineSET_TIMER_TICK(värde) do{ CLKCON = ((CLKCON & (~0x38)) | värde); } medan(0)


//Värdet av värdet är:
#defineTIMER1_TICK_32M 0x00  //32 MHz
#defineTIMER1_TICK_16M 0x08  //16 MHz, standardvärdet för systemåterställning
#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

//Ställ in TICK-delningsfiltret för timer 1
#defineSET_TIMER1_TICKDIV(värde)  
   göra{                             
     T1CTL &= ~0x0c;               
     T1CTL |= värde;               
   }medan (0)
      
//där värdet är:      
#defineTIMER1_TICKDIV_1 0x00   //1 division
#defineTIMER1_TICKDIV_8 0x04   //8-vägs frekvens
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c


//Ställ in timerns överflödesperiod
#defineSET_TIMER1_PERIOD(värde)
   göra{                           
     T1CC0H = HIGH_BYTE(värde);  
     T1CC0L = LOW_BYTE(värde);   
   }medan (0)
     
//Ställ in driftläget för Timer 1
#defineSET_TIMER1_MODE(läge)  
   göra{                        
     T1CTL = ((T1CTL & (~0x03)) | läge);           
   }medan (0)


//Värdet av mode är:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Vakthund
**********************************************************
*/
//Ställ in överflödesperioden för watchdog-timern
#defineWDT_SET_TIMEOUT_PERIOD(timeout)
   göra{ WDCTL &= ~0x03; WDCTL |= timeout; }medan (0)


//Värdet på parametertimeouten är:
#defineSEC_1 0x00     //Efter 1 sekund
#defineM_SEC_250 0x01     //Efter 250 ms
#defineM_SEC_15 0x02     //Efter 15 ms
#defineM_SEC_2 0x03     //Efter 2 ms


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


//Starta/stoppa vakthundens timer
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]

[url=] [/url]
/***********************************************************
                       ADC
**********************************************************
*/
//Konfigurera en enda ADC
#defineADC_SINGLE_CONVERSION(inställningar)
   göra{ ADCCON3 = inställningar; }medan(0)

//Parameterinställningen består av följande kombinationer:
//Referensspänning
#defineADC_REF_1_25_V 0x00     //Intern referensspänning på 1,25 V
#defineADC_REF_P0_7 0x40     //Extern referensspänning på AIN7-stiftet
#defineADC_REF_AVDD 0x80     //AVDD_SOC Pins
#defineADC_REF_P0_6_P0_7 0xC0     //AIN6-AIN7 Extern referensspänning för differentialingångar


//Samplingsfrekvens
#defineADC_8_BIT 0x00     //8:e plats
#defineADC_10_BIT 0x10     //10:e plats
#defineADC_12_BIT 0x20     //12:e plats
#defineADC_14_BIT 0x30     //14:e plats


//Kanalen kommer in
#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 chipet
#defineADC_VDD_3 0x0F     //VDDD/3




ADC-konverteringen är klar
#define ADC_SAMPLE_READY() (ADCCON1 & 0x80)

#endif
//启动ADC转化
#define ADC_START()
  do { ADCCON1 |= 0x40; } medan (0)//Välj triggerläget på ADC:n som manuellt (dvs. ADC_SAMPLE_READY)
#defineADC_STOP()  
  göra{ ADCCON1 |=0x30; }medan (0)[url=] [/url]


(2) Funktionellt modullager
  • module.h
  • module.c
[url=] [/url]
/***********************************************************
*Filnamn: module.h
*Författare: hustlzp
*Datum: 6 mars 2011
*Version: 1.0
*Funktionsbeskrivning: Funktionsmodulens lagerhuvudfil
*Funktionslista: tomrum led_init()
            tomrum timer1_init()
            tomrum uart0_init(tomrum);
            void Uart0SendString (osignerad karaktär *s);
            float adc_start(tomrum)
            void get_temperature(osignerad char *output, float temp);
            tomrum watchdog_init(tomrum);
*Modifierade register:
**********************************************************
*/

#ifndef MODULE_H
#defineMODULE_H


#include"hal.h"


/***********************************************************
                        LED
**********************************************************
*/
//Definiera LED-stiften
#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   

//LED-ljus och avstängt
#defineLED_OFF 1
#defineLED_ON 0

//LED-initiering
tomrumled_init(tomrum);




/***********************************************************
                        timer1
**********************************************************
*/
//Används för att ställa in värdet på överflödesperioden för timern
#defineTIMER1_OVF_2SEC 0xF424   //2:or
#defineTIMER1_OVF_1SEC 0x7A12   //1:or
#defineTIMER1_OVF_dot5SEC 0x3D09   //0,5 sekunder   

//Timer 1 initierar
tomrum  timer1_init(tomrum);
                  

/***********************************************************
                        UART0
**********************************************************
*/
//UART0-initiering
tomrum  uart0_init(tomrum);                    

//Seriellportsöverföringssträng
tomrum  Uart0SendString (osigneratchar*s);
   

/***********************************************************
                        ADC-14
**********************************************************
*/
//Används för att omvandla data som ADC erhåller till Celsiustemperatur
#defineADC_TO_CELSIUS(temp) (temp * 0,06229 - 311,43)

//Initiera ADC-konvertering
Flottadc_start(tomrum);

//Ombyggnad
tomrum  get_temperature(osigneratchar*output,Flotttillfällig);


/***********************************************************
                        WatchDog
**********************************************************
*/
//Initiering av vakthund
tomrum  watchdog_init(tomrum);                 

#endif
[url=] [/url]

[url=] [/url]
/***********************************************************
*Filnamn: module.c
*Författare: hustlzp
*Datum: 2011/3/11
*Version: 1.0
*Funktionsbeskrivning: Källfilen för funktionellt modullager
*Funktionslista: (utelämnad)
*Modifierade register:
**********************************************************
*/


#include"module.h"


/***********************************************************
*Funktionsnamn: led_init
*Funktionsfunktion: LED-initialisering
*Entréparametrar: Inga
*Exportparametrar: Inga
**********************************************************
*/
tomrumled_init(tomrum)
{
  //Konfigurera P1.0, P1.1, P1.2 och P1.3 som allmänna I/O-portar
  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);
  
  //Konfigurera P1.0, P1.1, P1.2 och P1.3 som utgångar
  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;
}


/***********************************************************
*Funktionsnamn: timer1_init
* Funktionsfunktion: Timer 1 initialisering
*Entréparametrar: Inga
*Exportparametrar: Inga
**********************************************************
*/
tomrumtimer1_init(tomrum)
{
  INT_GLOBAL_ENABLE(INT_ON);                 //Öppna den globala avbrottet
  
  INT_ENABLE(INUM_T1, INT_ON);               //Öppen T1-avbrott

  TIMER1_ENABLE_OVERFLOW_INT(INT_ON);        //Öppen T1-räkningsöverflödesavbrott
  
  SET_TIMER_TICK(TIMER1_TICK_4M);            //Ställ in timern TICK på 4 MHz
  
  SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);        //Sätt räkneperioden för T1 till 2 sekunder
  
  SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128);   //Ställ in klockcrossovern för T1 till 128
  
  SET_TIMER1_MODE(TIMER1_MODE_MODULE);      //Ställ in körläget för T1 till modul
}


/***********************************************************
*Funktionsnamn: uart0_init
*Funktionsfunktion: Seriellport UART0-initialisering
*Entréparametrar: Inga
*Exportparametrar: Inga
**********************************************************
*/
tomrumuart0_init(tomrum)
{
  //Välj UART-platsen
  IO_PER_LOC_UART0_AT_PORT0_PIN2345();
  
  //Konfigurera UART: Mottagning tillåten, 115200 bps, enbitars stoppbit, ingen paritet
  UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);

  //Öppna den totala avbrottet
  INT_GLOBAL_ENABLE(INT_ON);      

  //Öppna serieport 0 för att ta emot avbrott
  INT_ENABLE(INUM_URX0, INT_ON);   
}


/***********************************************************
*Funktionsnamn: Uart0SendString
* Funktionsfunktion: Timer 1 initialisering
*Inmatningsparameter: osignerad char *s
            Strängen du vill skicka
*Exportparametrar: Inga
**********************************************************
*/
tomrumUart0SendString (osigneratchar*s)
{
  medan(*s !=0)         
    UART0_SEND(*s++);
}


/***********************************************************
*Funktionsnamn: adc_start
*Funktionsfunktion: Starta ADC-konvertering
*Entréparametrar: Inga
*Exportparameter: float
            Temperaturvärdet i tabletten
**********************************************************
*/
Flottadc_start(tomrum)
{
  osigneradinttemp;
  
  //Referensspänningen är 1,25 V, samplingsnoggrannheten är 14 bitar och konverteringsmålet är den inbyggda temperatursensorn
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  
  ADC_STOP();                           //Ställ in triggermetoden för ADC-konvertering till manuell
  
  ADC_START();                           //Initiera ADC-konvertering
  
  medan(! ADC_SAMPLE_READY());            //Vänta på att konverteringen ska slutföras
  
  temp = ADCL >>2;                     //Spara konverteringen resulterar i temp
  temp |= (((osigneratint) ADCH) <<6);
  
  ÅterkomstenADC_TO_CELSIUS(tillfällig);           //Returnerar det faktiska temperaturvärdet efter omvandling
}


/***********************************************************
*Funktionsnamn: get_temperature
*Funktionsfunktion: Bearbeta temperaturvärdet och lagra det i teckenmatrisen för seriell utmatning
*Inmatningsparameter: osignerad char *utdata
            Används för att lagra det omvandlade temperaturvärdet
            Flyttemperatur
            Celsiustemperaturvärde
*Exportparametrar: Inga
**********************************************************
*/
tomrumget_temperature(osigneratchar*output,FlottTemp)
{
  Utgång[0] = (osigneratchar(temp) /10 + 48;         //Tio platser
  Utgång[1] = (osigneratchar(temp) %10 + 48;         //ensiffrigt antal
  Utgång[2] ='.';                                      //Decimalpunkt
  Utgång[3] = (osigneratchar(temp*10) %10 + 48;      //Tionde
  Utgång[4] = (osigneratchar(temp*100) %10 + 48;      //Percentil
  Utgång[5] ='';                                    //Strängändare
}


/***********************************************************
*Funktionsnamn: watchdog_init
*Funktionsfunktion: Initiering av vakthund
*Entréparametrar: Inga
*Exportparametrar: Inga
**********************************************************
*/
tomrumwatchdog_init(tomrum)
{
  WDT_SET_TIMEOUT_PERIOD(SEC_1);   //Ställ in timeout-tiden till 1 sekunder
  WDT_ENABLE();                    //Starta vakthunden
}
[url=] [/url]


(3) Applikationslagret
  • main.c
[url=] [/url]
/*******************************************************************
Filnamn: main.c
Författare: hustlzp
Datum: 2011/3/11
Version: 1.0
Funktionsbeskrivning: Masterprogramfil
Funktionslista: (utelämnad)
Modifieringsregister:
******************************************************************
*/


#include




/********************************************************************
                             Avbrottstjänstprocedurer
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektor=T1_VECTOR
__interrupt tomrum T1_ISR(tomrum)
{
  EA=0;                                   Porten är avbruten
  
  led2 = LED_ON;                          
  
  get_temperature(utdata,adc_start());    Konvertera temperaturvärdet till en array av tecken som ska matas ut
   
  Uart0SendString(output);                Utgångstemperaturvärde
  Uart0SendString("°C");  


  led2


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

  receive = U0DBUF;   
  
  if(type==1) // type=1, vilket indikerar att det mottagna tecknet används för att ställa in timeröverflödesperioden
  {
    typ=0;
    Växla (ta emot)
    {
      fall '0': // Timeröverflödsperioden är 0,5 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
        paus;
      }
      fall '1': // Timeröverskottsperioden är 1 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
        paus;
      }
      fall '2': // Timeröverskottsperioden är 2 sekunder
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
        paus;         
      }
    }
  }
  else if(type==2) // type=2, vilket indikerar att de mottagna tecknen används för sömnkontroll
  {
    typ=0;
    led1 = LED_OFF;
    led2 = LED_OFF;
    led3 = LED_OFF;
    Växla (ta emot)
    {
      fodral '1': // Gå in i strömläge PM1
      {
        SET_POWER_MODE(1);  
        paus;
      }
      Fodral '2': // Gå in i strömläge PM2
      {
        SET_POWER_MODE(2);  
        paus;
      }
      fodral '3': //Gå in i strömläge PM3
      {
        SET_POWER_MODE(3);  
        paus;
      }
    }
  }
  else if(type==0) // type=0, vilket indikerar att det mottagna tecknet är typen av kontrollkommando: @ eller $
  {
    if(receive=='@')  
    {
      typ=1;     '@' tas emot för att indikera att nästa tecken används för att sätta överflödesperioden
    }
    annars if(receive=='$')
    {
      typ=2;     '$' tas emot, vilket indikerar att nästa tecken används för systemsömnkontroll
    }
  }
  
  led3 = LED_OFF;
   
  EA=1;
}
=LED_OFF;
  
  TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR);   Rensa avbrottsskylten
  
  EA=1;                                   Öppen avbrott  
}
/* 主函数
-------------------------------------------------------*/
tomt huvudhuvud(tomrum)
{
  SET_MAIN_CLOCK_SOURCE(KRISTALL);  Ställ in systemklockan på 32 MHz kristalloscillator
  
  led_init();                      LED-initiering
  
  uart0_init();                    Seriellport UART0-initialisering
  
  timer1_init();                   Timer 1 initierar
  
  watchdog_init();                 Initiering av vakthund
  
  medan(1)
  {
    WDT_RESET();                   Mata hunden hela tiden
  }
}/********************************************************************
                            Huvudprogram   
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
osignerad char-output[6]={0};       Temperaturdata lagras för enkel seriell utmatning
osignerade char tar emot;             Spara de mottagna karaktärerna
osignerad karaktärstyp=0;              Typflaggan för det mottagna tecknet är satt till 0/1/2"module.h"[url=] [/url]


5. Testning
Åh~ Koden är äntligen inklistrade, det är verkligen utmattande, låt oss testa det här lilla systemet:
(1) Tidsbegränsad provtagning
Öppna den seriella porten, starta IAR-felsökning, och se att led1 är på, och temperaturvärdet på seriella portverktyget genereras ständigt, och samplingsintervallet bestäms till 2 sekunder:
(2) Kontroll av samplingsintervall
Ange "@1" i verktyget för seriell port, testa sedan samplingsintervallet och se att det har blivit 1s; Ange "@0" och samplingsintervallet har ändrats till 0,5 sekunder.
(3) Sömnkontroll
Skriv in "$1" i serieportverktyget och se att alla LED-lampor är släckta och temperaturprovtagningen har upphört:
Efter testning fungerar systemet normalt och stabilt, och uppfyller i princip kraven.
Studenter som behöver källkodKlicka här för att ladda ner
6. Slutsats
Denna artikel tar ett något omfattande experiment som exempel för att visa hur man integrerar CC2430-on-chip-resurser för att skriva ett relativt standardiserat litet system. Om några dagar ska jag ta mig tid att skriva en enkel användarmanual för hal.h så att jag och alla andra enkelt kan använda CC2430.
Nästa steg är att avsluta min research om CC2430 on-chip-resurser och ägna mig åt att lära mig TI Z-Stack-protokollstacken~
Blogginlägget i denna serie är avslutat för tillfället, men Zigbees resa kommer att fortsätta. Utsikten framför oss är okänd, men jag tror att författaren kommer att övervinna hinder med alla och smaka på upp- och nedgångarna, och det kommer att finnas vinster.
Håll utkik: "Gå med i TI Z-Stack"-blogginlägg!















Föregående:Zigbee Journey (9): Flera viktiga grundläggande CC2430-experiment – systematisk sömn och avbruten vakenhet
Nästa:Idag är det Halloween, hur ska du underhålla?
Publicerad på 2014-10-31 08:04:14 |
Förlåt att jag inte förstår någonting
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com