Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 10835|Antwoord: 1

Zigbee Journey (10): Uitgebreid experiment - Temperatuurmonitoringsysteem gebaseerd op CC2430

[Link kopiëren]
Geplaatst op 30-10-2014 23:47:44 | | | |
Na het schrijven van "Zigbee Journey (9)" op 3 maart, was de auteur oorspronkelijk van plan direct te beginnen met het schrijven van een klein experiment over het "temperatuurmonitoringsysteem" als samenvatting van een reeks verspreide kennispunten van eerder. Toch realiseerde ik me ook dat, hoewel elk van de voorgaande kleine experimenten in detail was beschreven, de normatieve en structurele aard van de code ondraaglijk kon worden genoemd. Omdat het een samenvatting is, zouden we voortgang moeten boeken op basis van het origineel, in plaats van de eerdere kleine kennispunten mechanisch aan elkaar te knopen. Daarom heb ik mijn oorspronkelijke plan opgeschort, de tijd genomen om de algemene technieken van embedded development te leren en twee essays geschrevenIngebedde C51-programmeerspecificatie" en "Hiërarchie van embedded projectcodestructuur》。 Dit logboek is niet alleen een samenvatting van Zigbee's eerste reis, maar bevat ook de leerervaringen van de auteur van de afgelopen dagen, in de hoop nuttig te zijn voor Zigbee-beginners.
De volledige tekst is georganiseerd volgens het basisproces van softwareontwikkeling: eisenanalyse, outline-ontwerp, gedetailleerd ontwerp, codeerimplementatie en testen.
1. Vraaganalyse
Na overleg tussen de "klant" en de "ontwikkelaar" werd de volgende functiebeschrijving van het systeem vastgesteld:
… De huidige kamertemperatuur wordt verzameld door CC2430-gebaseerde nodes, en de temperatuurwaarden kunnen worden gemonitord via een pc
… De CC2430-node zelf moet een bepaalde mate van stabiliteit hebben en kan automatisch terugkeren naar de normale toestand
… Het bemonsteringsinterval en het energiebeheer van de node kunnen door een pc worden geregeld
2. Ontwerp van de omtrek
Volgens de bovenstaande vereistenanalyse kunnen we het systeem opdelen in twee modules:CC2430-knooppuntenPC
  [CC2430 Node]  
… Externe parameters kunnen regelmatig worden verzameld en naar de pc worden gestuurd
… Automatische reset wanneer de machine wordt uitgeschakeld
… Commando's van de pc kunnen worden ontvangen en dienovereenkomstig worden verwerkt: verander het sampleinterval/energiebeheer
  [PC]  
… De C-machine ontvangt en toont gegevens via het seriële poortgereedschap
… Instructies kunnen via het seriële poortgereedschap naar de microcontroller worden gestuurd om de bemonsteringssnelheid en het energiebeheer te regelen
3. Detailontwerp
(1) Codestructuur
De gelaagdheid van de codestructuur van dit systeem is beschreven in het essay "Hiërarchie van embedded projectcodestructuur", en de kopie is als volgt:
(1) Hardware-abstractielaag
      [ioCC2430.h] (Systeem inbegrepen)Alle SFR- en interruptvectoren van de CC2430 zijn gedefinieerd
      [hal.h] Bevat gemeenschappelijke typedefinities, veelvoorkomende toewijzingsmacro's en gemeenschappelijke configuratie van CC2430 on-chip resources (I/O, seriële communicatie, ADC, timer, energiebeheer, enz.)
  (2) Functionele modulelaag
      [module.h] definieert on-chip resources (timers, I/O), off-chip uitbreidingsmodules (LED's) en declaraties van gerelateerde functies
      [module.cVoer de initialisatie van elke module (LED) uit.
  (3) Applicatielaag
      [main.cRaadpleeg hal.h, ioCC2430.h en module.h om specifieke toepassingsvereisten te bereiken zoals temperatuurvergelijking, intercommunicatie met pc, en uitschakelen en resetten
(2) Implementatiemethoden van elke module
Volgens de modules die zijn verdeeld volgens het ontwerp van de omschrijving, kan het intrinsieke systeem worden onderverdeeld in twee hoofdmodules:CC2430-knooppuntenPC
Omdat er seriële poortcommunicatietools op de pc zitten, kunnen de functies voldoen aan de eisen, dus we hoeven dit deel van de pc niet te doen en hoeven we het niet te analyseren. Laten we het hieronder hebben over sectie CC2430
De implementatiemethode van elke subfunctie van het punt:
… Gebruik de tellingoverlooponderbreking van de timer om getimede sampling te activeren
… De UART0-modus met seriële poort zendt temperatuurgegevens naar een pc
… Het ingebouwde watchdogcircuit van de CC2430 wordt gebruikt om de automatische resetfunctie van het systeem te realiseren
… De seriële poort wordt gebruikt om interrupts te ontvangen om bedieningscommando's van de pc vast te leggen en te beantwoorden
1) Indien ontvangen@Het teken is het besturingscommando voor het bemonsteringsinterval, gevolgd door een getal dat het bemonsteringsinterval aangeeft: 0-0,5 s, 1-1 s, 2-2 s.
如:@0,表示每隔0.5秒采样一次。
2) Als ontvangen$  Het teken is het slaapcommando, gevolgd door een cijfer dat de energiemodus aangeeft
Bijvoorbeeld: $3, wat betekent dat je het systeem in energiemodus 3 zet.
(3) Programmastroomdiagram
  • Masterprogramma stroomdiagram
  • Timer 1 Overflow Interrupt Program Stroomdiagram
  • Stroomdiagram van procedure voor seriële poortontvangst van interrupts




4. Codeerimplementatie
(1) Hardware-abstractielaag
De hardware-abstractielaag omvat ioCC2430.h en hal.h. Omdat het eerste systeem erbij hoort, wordt het niet vermeld.
Hieronder volgt een lijst van alle inhoud van hal.h (omdat dit bestand te lang is en onhandig lijkt, zal ik het in modules tonen):
  • hoofd
  • I/O-poorten
  • Onderbroken
  • Seriële poort
  • Stroom- en klokbeheer
  • Timer
  • Waakhond
  • ADC
[url=] [/url]
/***********************************************************
*Bestandsnaam: hal.h
*Auteur: hustlzp
*Datum: 8 maart 2011
*Editie: 1.1
*Functiebeschrijving: Hardware-abstractielaag
*Aangepaste records:
**********************************************************
*/


#ifndef HAL_H
#defineHAL_H


#include


/***********************************************************
                       Veelvoorkomende typedefinities
**********************************************************
*/
typedef unsignedchar   BYTE;
typedef unsignedint    WORD;
typedef unsignedlang   DWORD;



/***********************************************************
                       Veelgebruikte macrodefinities
**********************************************************
*/

//8 plaatsen hoger
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))


//8 plaatsen lager
#defineLOW_BYTE(a) ((BYTE) ((WORD)(a)))


//Toewijzing
#defineSET_WORD(regH,regL,woord)  
   doen{                           
      (regH)=HIGH_BYTE(woord);     
      (regL)=LOW_BYTE(woord);      
   }terwijl(0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       I/O-poorten
**********************************************************
*/
/*Configureer de richting van de I/O-poort
-----------------------------------------
*/
#defineIO_DIR_PORT_PIN(bakboord, pin, dir)  
   doen{                                 
      als(dir == IO_OUT)                 
         P##port##DIR |= (0x01<<(speld));  
      anders                              
         P##port##DIR &= ~(0x01<<(speld));
   }terwijl(0)



//De waarde van de parameter-gids is:
#defineIO_IN 0
#defineIO_OUT 1


/*Configureer de invoermodus van de I/O-poort
-----------------------------------------
*/
#defineIO_IMODE_PORT_PIN(poort, pin, imode)
   doen{                                    
      als(imode == IO_IMODE_TRI)            
         P##port##INP |= (0x01<<(speld));     
      anders                                 
         P##port##INP &= ~(0x01<<(speld));   
   }terwijl (0)



#define IO_PUD_PORT(bakboord, pud)        
   doe {                              
      als (pud == IO_PULLDOWN)         
         P2INP |= (0x01 << (poort+5));
      anders                           
         P2INP &= ~(0x01 << (poort+5));
   } terwijl (0)


De waarde van de parameter PUD is:
#define IO_PULLUP 0 // Trek omhoog
#define IO_PULLDOWN 1 // Trek naar beneden


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

#define IO_FUNC_PORT_PIN(poort, pin, func)  
   doe {                                    
      als((poort == 2) && (pin == 3)){      
         als (func) {                       
            P2SEL |= 0x02;                 
         } anders {                          
            P2SEL &= ~0x02;               
         }                                 
      }                                    
      anders als((poort == 2) && (pin == 4)){  
         als (func) {                       
            P2SEL |= 0x04;                 
         } anders {                          
            P2SEL &= ~0x04;               
         }                                 
      }                                    
      anders{                                
         als (func) {                       
            P##port##SEL |= (0x01<<(pin));
         } anders {                          
            P##port##SEL &= ~(0x01<<(pin));
        }                                 
      }                                    
   } terwijl (0)


De waarde van de parameterfunc is:
#define IO_FUNC_GIO 0 // Algemene I/O
#define IO_FUNC_PERIPH 1 // Perifere I/O


Configureer de locatie van de perifere I/O
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } terwijl (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } terwijl (0)

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

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

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

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

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

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

//De waarde van de parameter imode is:
#defineIO_IMODE_PUD 0   //Trek omhoog/trek omlaag
#defineIO_IMODE_TRI 1   //Drie staten[url=] [/url]

[url=] [/url]
/***********************************************************
                       Onderbroken
**********************************************************
*/
//Voor aan/uit-interrupts
#defineINT_ON 1
#defineINT_OFF 0


//Gebruikt om interrupt-vlaggen te plaatsen/wissen
#defineINT_SET 1
#defineINT_CLR 0


//Globale interruptinstellingen
#defineINT_GLOBAL_ENABLE(op) EA=(!! op)


//Definieer de breuk
#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


/*Onderbrekingen toegestaan
-----------------------------------------
*/
#defineINT_ENABLE(inum, aan)                        
   doen{                                             
      als      (inum==INUM_RFERR) { RFERRIE = on; }  
      anders als(inum==INUM_ADC)   { ADCIE = aan; }  
      anders als(inum==INUM_URX0)  { URX0IE = on; }  
      anders als(inum==INUM_URX1)  { URX1IE = on; }  
      anders als(inum==INUM_ENC)   { ENCIE = aan; }  
      anders als(inum==INUM_ST)    { STIE = aan; }  
      anders als(inum==INUM_P2INT) { (aan) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
      anders als(inum==INUM_UTX0)  { (aan) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
      anders als(inum==INUM_DMA)   { DMAIE = aan; }  
      anders als(inum==INUM_T1)    { T1IE = on; }  
      anders als(inum==INUM_T2)    { T2IE = on; }  
      anders als(inum==INUM_T3)    { T3IE = on; }  
      anders als(inum==INUM_T4)    { T4IE = on; }  
      anders als(inum==INUM_P0INT) { P0IE = on; }  
      anders als(inum==INUM_UTX1)  { (aan) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
      anders als(inum==INUM_P1INT) { (aan) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
      anders als(inum==INUM_RF)    { (aan) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
      anders als(inum==INUM_WDT)   { (aan) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
   }terwijl (0)


/*Stel de prioriteit voor de storing in
-----------------------------------------
*/
#defineINT_PRIORITY(groep, pri)                     
   doen{                                               
      als(pri ==0) { IP0 &= ~groep; IP1 &= ~groep; }
      als(pri ==1) { IP0 |= groep; IP1 &= ~groep; }
      als(pri ==2) { IP0 &= ~groep; IP1 |= groep; }
      als(pri ==3) { IP0 |= groep; IP1 |= groep; }
   }terwijl (0)

//De waarde van de parameter pri is: 0/1/2/3 (hoogste prioriteit)


//De waarde van de parametergroep is:
#defineRFERR_RF_DMA 0x01//Groep IP0
#defineADC_P2INT_T1 0x02//Groep IP1
#defineURX0_UTX0_T2 0x04//Groep IP2
#defineURX1_UTX1_T3 0x08//Groep IP3
#defineENC_P1INT_T4 0x10//Groep IP4
#defineST_WDT_P0INT 0x20//Groep IP5


/*Haal de interrupt-vlag
-----------------------------------------
*/
#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                                             
)


/*Stel de interruptvlag in
-----------------------------------------
*/
#defineINT_SETFLAG(inum, f)                     
   doen{                                          
      als      (inum==INUM_RFERR) { RFERRIF= f; }
      anders als(inum==INUM_ADC)   { ADCIF = f; }
      anders als(inum==INUM_URX0)  { URX0IF = f; }
      anders als(inum==INUM_URX1)  { URX1IF = f; }
      anders als(inum==INUM_ENC)   { ENCIF_1 = ENCIF_0 = f; }
      anders als(inum==INUM_ST)    { STIF = f;  }
      anders als(inum==INUM_P2INT) { P2IF = f;  }
      anders als(inum==INUM_UTX0)  { UTX0IF= f;  }
      anders als(inum==INUM_DMA)   { DMAIF = f;  }
      anders als(inum==INUM_T1)    { T1IF = f;  }
      anders als(inum==INUM_T2)    { T2IF = f;  }
      anders als(inum==INUM_T3)    { T3IF = f;  }
      anders als(inum==INUM_T4)    { T4IF = f;  }
      anders als(inum==INUM_P0INT) { P0IF = f;  }
      anders als(inum==INUM_UTX1)  { UTX1IF= f;  }
      anders als(inum==INUM_P1INT) { P1IF = f;  }
      anders als(inum==INUM_RF)    { (f) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
      anders als(inum==INUM_WDT)   { WDTIF = f;  }
   }terwijl (0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Seriële poort
**********************************************************
*/
//De waarde van de BAUD_E overeenkomt met verschillende baudrates
#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  )


//De waarde van de BAUD_M overeenkomt met verschillende baudsnelheden
#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)


/*Seriële poortconfiguratie in UART-modus
-----------------------------------------
*/
#defineUART_SETUP(uart, receiveEnable, baudRate, opties)      
   doen{                                                         
      als((uart) ==0){                                          
         als(PERCFG &0x01){                                    
            P1SEL |=0x30;                                      
         }anders{                                               
            P0SEL |=0x0C;                                      
         }                                                      
      }                                                         
      anders{                                                   
         als(PERCFG &0x02){                                    
            P1SEL |=0xC0;                                      
         }anders{                                               
            P0SEL |=0x30;                                      
         }                                                      
      }                                                         
                                                               
      U##uart##GCR = BAUD_E((baudRate),CLKSPD);                 
      U##uart##BAUD = BAUD_M(baudRate);                        
                                                               
      U##uart##CSR |=0x80;                                    
                                                               
      U##uart##CSR |= ontvangstEnable;                           
                                                               
      U##uart##UCR |= ((opties) |0x80);                       
   }terwijl(0)
     
//De waarde van de parameter receiveEnable:
#defineUART_RECEIVE_ENABLE 0x40   //Toestemming ontvangen
#defineUART_RECEIVE_DISABLE 0x00   
     
//De waarde van de parameteropties:
#defineFLOW_CONTROL_ENABLE 0x40   //Stroomregeling
#defineFLOW_CONTROL_DISABLE 0x00


#defineEVEN_PARITY 0x20   //Occasionele verificatie
#defineODD_PARITY 0x00   //Vreemde verificatie


#defineNINE_BIT_TRANSFER 0x10   //9-byte overdracht
#defineEIGHT_BIT_TRANSFER 0x00   //8-byte overdracht


#definePARITY_ENABLE 0x08   //Pariteitscontrole-enablement
#definePARITY_DISABLE 0x00

#defineTWO_STOP_BITS 0x04   //2-positie stoppositie
#defineONE_STOP_BITS 0x00   //1 stoppositie


#defineHIGH_STOP 0x02   //Het stopniveau is hoog
#defineLOW_STOP 0x00   //De stoppositie is laag
     
#defineHIGH_START 0x01   //Het startbitniveau is hoog
#defineLOW_START 0x00   //Het startbitniveau is laag


//Seriële poort stuurt karakters
#defineUART_SEND(uart,data)            
   doen{                                 
     terwijl(U##uart##CSR &0x01);        
       U##uart##DBUF = data;            
   }terwijl (0)
#defineUART0_SEND(data) UART_SEND(0,data)
#defineUART1_SEND(data) UART_SEND(1,data)


//Seriële poort ontvangt tekens
#defineUART_RECEIVE(uart,data)         
   doen{                                 
     terwijl(! (U##uart##CSR&0x04));      
       data=U##uart##DBUF;              
   }terwijl(0)
#defineUART0_RECEIVE(data) UART_RECEIVE(0,data)
#defineUART1_RECEIVE(data) UART_RECEIVE(1,data)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Stroom- en klokbeheer
**********************************************************
*/
//Haal de klok-crossover
#defineCLKSPD (CLKCON & 0x07)


//Stel de stroommodus in
#defineSET_POWER_MODE(modus)                  
   doen{                                       
      als(modus ==0) { SLAAP &= ~0x03; }
      anders als(modus ==3) { SLAAP |=0x03;  }
      anders{ SLAAP &= ~0x03; SLAAP |= modus;  }
      PCON |=0x01;                           
      ASM("NOP");                              
   }terwijl (0)


//De parametermodus is ingesteld op de volgende waarden:
#definePOWER_MODE_0 0x00  
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03


//Gebruikt om de stabiliteit van hoogfrequente RC-oscillatoren te detecteren
#defineHIGH_FREQUENCY_RC_OSC_STABLE (SLAAP & 0x20)


//Gebruikt om de stabiele toestand van de kristaloscillator te detecteren
#defineXOSC_STABLE (SLAAP & 0x40)


//Krijg de tikfrequentiewaarde van de timer
#defineTICKSPD ((CLKCON & 0x38) >> 3)


//Stel de hoofdklokfrequentie in
#defineSET_MAIN_CLOCK_SOURCE(bron)
   doen{                              
      als(bron) {                    
        CLKCON |=0x40;               
        terwijl(! HIGH_FREQUENCY_RC_OSC_STABLE);
        als(TICKSPD ==0){            
          CLKCON |=0x08;            
        }                             
        SLAAP |=0x04;               
      }                              
      anders{                          
        SLAAP &= ~0x04;               
        terwijl(! XOSC_STABLE);         
        ASM("NOP");                  
        CLKCON &= ~0x47;              
        SLAAP |=0x04;               
      }                              
   }terwijl (0)


//De waarde van de parameterbron is:
#defineCRYSTAL 0x00   //Kristaloscillator
#defineRC 0x01   //RC-oscillator
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Timer 1
**********************************************************
*/
//Timer 1 laat de teloverloop onderbreken
#defineTIMER1_ENABLE_OVERFLOW_INT(Val)
   (TIMIF = (val) ? TIMIF |0x40: TIMIF & ~0x40)


//Stel de overflow-interruptvlag in voor timer 1
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))


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


//Stel de klokdivisie in voor de timer
#defineSET_TIMER_TICK(waarde) do{ CLKCON = ((CLKCON & (~0x38)) | waarde); } terwijl(0)


//De waarde van de waarde is:
#defineTIMER1_TICK_32M 0x00  //32MHz
#defineTIMER1_TICK_16M 0x08  //16MHz, de standaardwaarde voor systeemreset
#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

//Stel de TICK-crossover in op timer 1
#defineSET_TIMER1_TICKDIV(waarde)  
   doen{                             
     T1CTL &= ~0x0c;               
     T1CTL |= waarde;               
   }terwijl (0)
      
//waarbij de waarde is:      
#defineTIMER1_TICKDIV_1 0x00   //1 Divisie
#defineTIMER1_TICKDIV_8 0x04   //8-weg frequentie
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c


//Stel de timer overloopperiode in
#defineSET_TIMER1_PERIOD(waarde)
   doen{                           
     T1CC0H = HIGH_BYTE(waarde);  
     T1CC0L = LOW_BYTE(waarde);   
   }terwijl (0)
     
//Stel de bedrijfsmodus in van Timer 1
#defineSET_TIMER1_MODE(modus)  
   doen{                        
     T1CTL = ((T1CTL & (~0x03)) | modus);           
   }terwijl (0)


//De waarde van modus is:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Waakhond
**********************************************************
*/
//Stel de overloopperiode in voor de watchdog-timer
#defineWDT_SET_TIMEOUT_PERIOD(time-out)
   doen{ WDCTL &= ~0x03; WDCTL |= time-out; }terwijl (0)


//De waarde van de parametertimeout is:
#defineSEC_1 0x00     //na 1 seconde
#defineM_SEC_250 0x01     //na 250 ms
#defineM_SEC_15 0x02     //na 15 ms
#defineM_SEC_2 0x03     //na 2 ms


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


//Start/stop de watchdog-timer
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]

[url=] [/url]
/***********************************************************
                       ADC
**********************************************************
*/
//Configureer een enkele ADC
#defineADC_SINGLE_CONVERSION(instellingen)
   doen{ ADCCON3 = instellingen; }terwijl(0)

//De parameterinstelling bestaat uit de volgende combinaties:
//Referentiespanning
#defineADC_REF_1_25_V 0x00     //Interne referentiespanning van 1,25V
#defineADC_REF_P0_7 0x40     //Externe referentiespanning op de AIN7-pin
#defineADC_REF_AVDD 0x80     //AVDD_SOC Pinnen
#defineADC_REF_P0_6_P0_7 0xC0     //AIN6-AIN7 Externe referentiespanning voor differentiële ingangen


//Bemonsteringsfrequentie
#defineADC_8_BIT 0x00     //8e plaats
#defineADC_10_BIT 0x10     //10e plaats
#defineADC_12_BIT 0x20     //12e plaats
#defineADC_14_BIT 0x30     //14e plaats


//Enter het kanaal
#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     //In-chip temperatuursensor
#defineADC_VDD_3 0x0F     //VDDD/3




ADC-conversie is voltooid
#define ADC_SAMPLE_READY() (ADCCON1 & 0x80)

#endif
//启动ADC转化
#define ADC_START()
  do { ADCCON1 |= 0x40; } terwijl (0)//Selecteer de triggermodus van de ADC als handmatig (d.w.z. ADC_SAMPLE_READY)
#defineADC_STOP()  
  doen{ ADCCON1 |=0x30; }terwijl (0)[url=] [/url]


(2) Functionele modulelaag
  • module.h
  • module.c
[url=] [/url]
/***********************************************************
*Bestandsnaam: module.h
*Auteur: hustlzp
*Datum: 6 maart 2011
*Versie: 1.0
*Functiebeschrijving: Functioneel modulelaag-headerbestand
*Functielijst: leeg led_init()
            Void timer1_init()
            leegte uart0_init(leegte);
            void Uart0SendString (ongetekende karakter *s);
            float adc_start(leegte)
            void get_temperature(niet-ondertekende char *output, float temp);
            leegte watchdog_init(leegte);
*Aangepaste records:
**********************************************************
*/

#ifndef MODULE_H
#defineMODULE_H


#include"hal.h"


/***********************************************************
                        LED
**********************************************************
*/
//Definieer de LED-pinnen
#defineled1 P1_0         
#defineled2 P1_1         
#defineled3 P1_2         
#defineled4 P1_3   

//LED-licht en uit
#defineLED_OFF 1
#defineLED_ON 0

//LED-initialisatie
leegteled_init(leegte);




/***********************************************************
                        timer1
**********************************************************
*/
//Gebruikt om de overloopperiode van de timer in te stellen
#defineTIMER1_OVF_2SEC 0xF424   //2s
#defineTIMER1_OVF_1SEC 0x7A12   //1s
#defineTIMER1_OVF_dot5SEC 0x3D09   //0,5s   

//Timer 1 initialiseert
leegte  timer1_init(leegte);
                  

/***********************************************************
                        UART0
**********************************************************
*/
//UART0-initialisatie
leegte  uart0_init(leegte);                    

//Seriële poort transmissiestring
leegte  Uart0SendString (ongetekendchar*s);
   

/***********************************************************
                        ADC-14
**********************************************************
*/
//Gebruikt om de door de ADC verkregen gegevens om te zetten naar Celsiustemperatuur
#defineADC_TO_CELSIUS(Temperatuur) (Temperatuur * 0,06229 - 311,43)

//Start ADC-conversie
Floatadc_start(leegte);

//Ombouw
leegte  get_temperature(niet ondertekend)char*output,Floattijdelijk);


/***********************************************************
                        WatchDog
**********************************************************
*/
//Initialisatie van de waakhond
leegte  watchdog_init(leegte);                 

#endif
[url=] [/url]

[url=] [/url]
/***********************************************************
*Bestandsnaam: module.c
*Auteur: hustlzp
*Datum: 2011/3/11
*Versie: 1.0
*Functiebeschrijving: Functioneel modulelaag-bronbestand
*Functielijst: (weggelaten)
*Aangepaste records:
**********************************************************
*/


#include"module.h"


/***********************************************************
*Functienaam: led_init
*Functiefunctie: LED-initialisatie
*Toegangsparameters: Geen
*Exportparameters: Geen
**********************************************************
*/
leegteled_init(leegte)
{
  //Configureer P1.0, P1.1, P1.2 en P1.3 als algemene I/O-poorten
  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);
  
  //Configureer P1.0, P1.1, P1.2 en P1.3 als uitgangen
  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;
}


/***********************************************************
*Functienaam: timer1_init
* Functiefunctie: Timer 1 initialisatie
*Toegangsparameters: Geen
*Exportparameters: Geen
**********************************************************
*/
leegtetimer1_init(leegte)
{
  INT_GLOBAL_ENABLE(INT_ON);                 //Open de globale onderbreking
  
  INT_ENABLE(INUM_T1, INT_ON);               //Open T1-interrupt

  TIMER1_ENABLE_OVERFLOW_INT(INT_ON);        //Open T1 telling overloopinterrupt
  
  SET_TIMER_TICK(TIMER1_TICK_4M);            //Stel de timer TICK in op 4MHz
  
  SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);        //Stel de telperiode voor T1 in op 2's
  
  SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128);   //Stel de klokcrossover voor T1 in op 128
  
  SET_TIMER1_MODE(TIMER1_MODE_MODULE);      //Stel de loopmodus van T1 in op module
}


/***********************************************************
*Functienaam: uart0_init
*Functiefunctie: Seriële poort UART0 initialisatie
*Toegangsparameters: Geen
*Exportparameters: Geen
**********************************************************
*/
leegteuart0_init(leegte)
{
  //Selecteer de UART-locatie
  IO_PER_LOC_UART0_AT_PORT0_PIN2345();
  
  //UART configureren: Ontvangst toegestaan, 115200 bps, één-bit stopbit, geen pariteit
  UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);

  //Open de totale onderbreking
  INT_GLOBAL_ENABLE(INT_ON);      

  //Open seriële poort 0 om interrupts te ontvangen
  INT_ENABLE(INUM_URX0, INT_ON);   
}


/***********************************************************
*Functienaam: Uart0SendString
* Functiefunctie: Timer 1 initialisatie
*Invoerparameter: onondertekende char *s
            De string die je wilt sturen
*Exportparameters: Geen
**********************************************************
*/
leegteUart0SendString (ongetekendchar*s)
{
  terwijl(*s !=0)         
    UART0_SEND(*s++);
}


/***********************************************************
*Functienaam: adc_start
*Functiefunctie: Start ADC-conversie
*Toegangsparameters: Geen
*Exportparameter: float
            De temperatuurwaarde in de tablet
**********************************************************
*/
Floatadc_start(leegte)
{
  OnondertekendintTemp;
  
  //De referentiespanning is 1,25V, de bemonsteringsnauwkeurigheid is 14 bits, en het conversiedoel is de on-chip temperatuursensor
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  
  ADC_STOP();                           //Stel de triggermethode voor ADC-conversie handmatig in
  
  ADC_START();                           //Start ADC-conversie
  
  terwijl(! ADC_SAMPLE_READY());            //Wacht tot de conversie voltooid is
  
  temp = ADCL >>2;                     //Sla de conversieresultaten op in tijdelijke
  temp |= (((onondertekendint) ADCH) <<6);
  
  TerugkeerADC_TO_CELSIUS(tijdelijk);           //Geeft de werkelijke temperatuurwaarde terug na conversie
}


/***********************************************************
*Functienaam: get_temperature
*Functiefunctie: Verwerk de temperatuurwaarde en sla deze op in de tekenarray voor seriële uitvoer
*Invoerparameter: onondertekende char *output
            Gebruikt om de omgezette temperatuurwaarde op te slaan
            Drijvende temperatuur
            Celsiustemperatuurwaarde
*Exportparameters: Geen
**********************************************************
*/
leegteget_temperature(niet ondertekend)char*output,Floattijdelijk)
{
  output[0] = (niet ondertekendchar(tijdelijk) /10 + 48;         //Tien plaatsen
  output[1] = (niet ondertekendchar(temp) %10 + 48;         //Enkelcijferig aantal
  output[2] ='.';                                      //Decimale punt
  output[3] = (niet ondertekendchar(temp*10) %10 + 48;      //Tiende
  output[4] = (niet ondertekendchar(temp*100) %10 + 48;      //Percentiel
  output[5] ='';                                    //String-endifiers
}


/***********************************************************
*Functienaam: watchdog_init
*Functiefunctie: Initialisatie van de waakhond
*Toegangsparameters: Geen
*Exportparameters: Geen
**********************************************************
*/
leegtewatchdog_init(leegte)
{
  WDT_SET_TIMEOUT_PERIOD(SEC_1);   //Stel de time-out tijd in op 1 seconden
  WDT_ENABLE();                    //Start de waakhond
}
[url=] [/url]


(3) Applicatielaag
  • main.c
[url=] [/url]
/*******************************************************************
Bestandsnaam: main.c
Auteur: hustlzp
Datum: 2011/3/11
Versie: 1.0
Functiebeschrijving: Masterprogrammabestand
Functielijst: (weggelaten)
Wijzigingsverslag:
******************************************************************
*/


#include




/********************************************************************
                             Interruptserviceprocedures
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vector=T1_VECTOR
__interrupt leegte T1_ISR(leegte)
{
  EA=0;                                   De poort wordt onderbroken
  
  led2 = LED_ON;                          
  
  get_temperature(output,adc_start());    Zet de temperatuurwaarde om in een array van karakters die wordt uitgevoerd
   
  Uart0SendString(output);                Uitgangstemperatuurwaarde
  Uart0SendString("°C");  


  led2


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

  ontvangen = U0DBUF;   
  
  if(type==1) // type=1, wat aangeeft dat het ontvangen teken wordt gebruikt om de timer overloopperiode in te stellen
  {
    type=0;
    wissel (ontvangst)
    {
      geval '0': // Timer overloopperiode is 0,5 seconden
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
        pauze;
      }
      geval '1': // Timer overloopperiode is 1s
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
        pauze;
      }
      geval '2': // Timer overloopperiode is 2 seconden
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
        pauze;         
      }
    }
  }
  anders als(type==2) // type=2, wat aangeeft dat de ontvangen tekens worden gebruikt voor slaapcontrole
  {
    type=0;
    led1 = LED_OFF;
    led2 = LED_OFF;
    led3 = LED_OFF;
    wissel (ontvangst)
    {
      kast '1': // Schakel in energiemodus PM1
      {
        SET_POWER_MODE(1);  
        pauze;
      }
      kast '2': // Schakel in energiemodus PM2
      {
        SET_POWER_MODE(2);  
        pauze;
      }
      kast '3': //Voer de energiemodus PM3 in
      {
        SET_POWER_MODE(3);  
        pauze;
      }
    }
  }
  else if(type==0) // type=0, wat aangeeft dat het ontvangen teken het type besturingscommando is: @ of $
  {
    als(ontvangt=='@')  
    {
      type=1;     '@' wordt ontvangen om aan te geven dat het volgende teken wordt gebruikt om de overloopperiode in te stellen
    }
    else if(ontvangt=='$')
    {
      type=2;     '$' wordt ontvangen, wat aangeeft dat het volgende teken wordt gebruikt voor systeemslaapbesturing
    }
  }
  
  led3 = LED_OFF;
   
  EA=1;
}
=LED_OFF;
  
  TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR);   Maak het onderbrekingsbord weg
  
  EA=1;                                   Open onderbreking  
}
/* 主函数
-------------------------------------------------------*/
Void main(void)
{
  SET_MAIN_CLOCK_SOURCE(KRISTAL);  Stel de systeemklok in op 32MHz kristaloscillator.
  
  led_init();                      LED-initialisatie
  
  uart0_init();                    Seriële poort UART0 initialisatie
  
  timer1_init();                   Timer 1 initialiseert
  
  watchdog_init();                 Initialisatie van de waakhond
  
  terwijl(1)
  {
    WDT_RESET();                   Voer de hond constant
  }
}/********************************************************************
                            Hoofdprogramma   
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
onondertekende char output[6]={0};       Temperatuurgegevens worden opgeslagen voor een gemakkelijke seriële uitvoer
onondertekende char ontvangt;             Sla de ontvangen karakters op
onondertekend karaktertype=0;              De typevlag van het ontvangen karakter is ingesteld op 0/1/2"module.h"[url=] [/url]


5. Testen
Oh~ De code is eindelijk geplakt, het is echt vermoeiend, laten we dit kleine systeem testen:
(1) Tijdbemonstering
Open de seriële poort, start met IAR-debugging, en ontdek dat led1 aan staat, de temperatuurwaarde op het seriële poortgereedschap wordt constant gegenereerd, en het bemonsteringsinterval wordt bepaald als 2s:
(2) Controle van bemonsteringsintervallen
Voer "@1" in in het seriële poortgereedschap, test vervolgens het bemonsteringsinterval, en zie dat het 1s is geworden; Voer "@0" in en het steekproefinterval is veranderd naar 0,5 seconden.
(3) Slaapcontrole
Voer "$1" in in het seriële poortgereedschap en zie dat alle LED's uit zijn en de temperatuurbemonstering is gestopt:
Na testen werkt het systeem normaal en stabiel, en voldoet het in principe aan de vereisten.
Studenten die broncode nodig hebbenKlik hier om te downloaden
6. Conclusie
Dit artikel neemt een enigszins uitgebreid experiment als voorbeeld om te laten zien hoe CC2430 on-chip resources geïntegreerd kan worden om een relatief gestandaardiseerd klein systeem te schrijven. Over een paar dagen neem ik de tijd om een eenvoudige gebruikershandleiding voor hal.h te schrijven, zodat ik en iedereen de CC2430 gemakkelijk kunnen bedienen.
Vervolgens zal ik mijn onderzoek naar CC2430 on-chip bronnen afronden en me wijden aan het leren van de TI Z-Stack protocolstack~
Het schrijven van blogposts in deze serie is voorlopig afgelopen, maar Zigbee's reis zal doorgaan. Het landschap voor ons is onbekend, maar ik geloof dat de auteur met iedereen obstakels zal overwinnen en de hoogte- en dieptepunten zal proeven, en dat er voordelen zullen zijn.
Blijf op de hoogte: "Word lid van TI Z-Stack" blogposts!















Vorig:Zigbee Journey (9): Verschillende belangrijke basisexperimenten met CC2430 - systematische slaap en onderbroken wakkerheid
Volgend:Vandaag is het Halloween, hoe ga je je vermaken?
Geplaatst op 31-10-2014 08:04:14 |
Vergeef me dat ik niets begrijp
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com