Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 10835|Απάντηση: 1

Zigbee Journey (10): Ολοκληρωμένο πείραμα - Σύστημα παρακολούθησης θερμοκρασίας βασισμένο στο CC2430

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 30/10/2014 11:47:44 μ.μ. | | | |
Αφού έγραψε το «Zigbee Journey (9)» στις 3 Μαρτίου, ο συγγραφέας σχεδίαζε αρχικά να αρχίσει αμέσως να γράφει ένα μικρό πείραμα για το «σύστημα παρακολούθησης θερμοκρασίας» ως περίληψη μιας σειράς διάσπαρτων σημείων γνώσης πριν. Ωστόσο, συνειδητοποίησα επίσης ότι παρόλο που κάθε ένα από τα προηγούμενα μικρά πειράματα περιγράφηκε λεπτομερώς, η κανονιστική και δομική φύση του κώδικά του θα μπορούσαμε να πούμε ότι είναι αφόρητη. Δεδομένου ότι είναι μια περίληψη, θα πρέπει να σημειώσουμε πρόοδο στην αρχική βάση, αντί να συναρμολογούμε μηχανικά τα προηγούμενα μικρά σημεία γνώσης. Ως εκ τούτου, έβαλα το αρχικό μου σχέδιο σε αναμονή, αφιέρωσα χρόνο για να μάθω τις γενικές τεχνικές της ενσωματωμένης ανάπτυξης και έγραψα δύο δοκίμιαΕνσωματωμένη προδιαγραφή προγραμματισμού C51" και "Ιεραρχία ενσωματωμένης δομής κώδικα έργου》。 Αυτό το αρχείο καταγραφής δεν είναι μόνο μια περίληψη του πρώτου ταξιδιού του Zigbee, αλλά ενσωματώνει επίσης τη μαθησιακή εμπειρία του συγγραφέα τις τελευταίες ημέρες, ελπίζοντας να είναι χρήσιμο στους αρχάριους του Zigbee.
Το πλήρες κείμενο οργανώνεται σύμφωνα με τη βασική διαδικασία ανάπτυξης λογισμικού: ανάλυση απαιτήσεων, σχεδιασμός περιγράμματος, λεπτομερής σχεδιασμός, υλοποίηση κωδικοποίησης και δοκιμή.
1. Ανάλυση ζήτησης
Μετά από συζήτηση μεταξύ του "πελάτη" και του "προγραμματιστή", καθορίστηκε η ακόλουθη περιγραφή της λειτουργίας του συστήματος:
… Η τρέχουσα θερμοκρασία δωματίου συλλέγεται από κόμβους που βασίζονται στο CC2430 και οι τιμές θερμοκρασίας της μπορούν να παρακολουθούνται μέσω υπολογιστή
… Ο ίδιος ο κόμβος CC2430 πρέπει να έχει έναν ορισμένο βαθμό σταθερότητας και μπορεί να επιστρέψει αυτόματα στην κανονική κατάσταση
… Το διάστημα δειγματοληψίας και η διαχείριση ισχύος του κόμβου μπορούν να ελεγχθούν από έναν υπολογιστή
2. Σχέδιο περιγράμματος
Σύμφωνα με την παραπάνω ανάλυση απαιτήσεων, μπορούμε να χωρίσουμε το σύστημα σε δύο ενότητες:Κόμβος CC2430καιΗ/Υ
  [Κόμβος CC2430]  
… Οι εξωτερικές παράμετροι μπορούν να συλλέγονται τακτικά και να αποστέλλονται στον υπολογιστή
… Αυτόματη επαναφορά όταν το μηχάνημα είναι απενεργοποιημένο
… Οι εντολές από τον υπολογιστή μπορούν να ληφθούν και να υποβληθούν σε επεξεργασία ανάλογα: αλλάξτε το διάστημα δείγματος/διαχείριση ενέργειας
  [Η/Υ]  
… Το μηχάνημα C λαμβάνει και εμφανίζει δεδομένα μέσω του εργαλείου σειριακής θύρας
… Οι οδηγίες μπορούν να σταλούν στον μικροελεγκτή μέσω του εργαλείου σειριακής θύρας για τον έλεγχο της ταχύτητας δειγματοληψίας και της διαχείρισης ενέργειας
3. Λεπτομερής σχεδιασμός
(1) Δομή κώδικα
Η διαστρωμάτωση της δομής του κώδικα αυτού του συστήματος έχει πράγματι περιγραφεί στο δοκίμιο "Ιεραρχία ενσωματωμένης δομής κώδικα έργου», και το αντίγραφο έχει ως εξής:
(1) Στρώμα αφαίρεσης υλικού
      [ioCC2430.h] (Περιλαμβάνεται σύστημα)Ορίζονται όλα τα SFR και τα διανύσματα διακοπής του CC2430
      [hal.h] Περιλαμβάνει κοινούς ορισμούς τύπων, κοινές μακροεντολές εκχώρησης και κοινή διαμόρφωση πόρων CC2430 στο τσιπ (I/O, σειριακή επικοινωνία, ADC, χρονοδιακόπτης, διαχείριση ενέργειας κ.λπ.)
  (2) Λειτουργικό επίπεδο μονάδας
      [module.h] ορίζει πόρους στο τσιπ (χρονόμετρα, I/O), μονάδες επέκτασης εκτός τσιπ (LED) και δηλώσεις σχετικών λειτουργιών
      [ενότητα.γΥλοποιήστε την αρχικοποίηση κάθε ενότητας (LED).
  (3) Επίπεδο εφαρμογής
      [main.cΑνατρέξτε στα hal.h, ioCC2430.h και module.h για να επιτύχετε συγκεκριμένες απαιτήσεις εφαρμογής, όπως λήψη θερμοκρασίας, ενδοεπικοινωνία με υπολογιστή και τερματισμό λειτουργίας και επαναφορά
(2) Μέθοδοι υλοποίησης κάθε ενότητας
Σύμφωνα με τις ενότητες που χωρίζονται σύμφωνα με το σχέδιο περιγράμματος, το εγγενές σύστημα μπορεί να χωριστεί σε δύο κύριες ενότητες:Κόμβος CC2430καιΗ/Υ
Δεδομένου ότι υπάρχουν εργαλεία επικοινωνίας σειριακής θύρας στον υπολογιστή, οι λειτουργίες του μπορούν να ικανοποιήσουν τις απαιτήσεις, επομένως δεν χρειάζεται να κάνουμε αυτό το μέρος του υπολογιστή και δεν χρειάζεται να το αναλύσουμε. Ας μιλήσουμε για την ενότητα CC2430 παρακάτω
Η μέθοδος υλοποίησης κάθε υπολειτουργίας του σημείου:
… Χρησιμοποιήστε τη διακοπή υπερχείλισης μέτρησης του χρονοδιακόπτη για να ενεργοποιήσετε τη χρονομετρημένη δειγματοληψία
… Η λειτουργία UART0 με σειριακή θύρα μεταδίδει δεδομένα θερμοκρασίας σε υπολογιστή
… Το ενσωματωμένο κύκλωμα παρακολούθησης του CC2430 χρησιμοποιείται για την πραγματοποίηση της λειτουργίας αυτόματης επαναφοράς του συστήματος
… Η σειριακή θύρα χρησιμοποιείται για τη λήψη διακοπών για τη λήψη και την απόκριση σε εντολές ελέγχου από τον υπολογιστή
1) Εάν παραληφθεί@Ο χαρακτήρας είναι η εντολή ελέγχου διαστήματος δειγματοληψίας, ακολουθούμενη από έναν αριθμό που υποδεικνύει το διάστημα δειγματοληψίας: 0-0,5 δευτ., 1-1 δευτ., 2-2 δευτ.
如:@0,表示每隔0.5秒采样一次。
2) Εάν παραληφθεί$  Ο χαρακτήρας είναι η εντολή ελέγχου ύπνου, ακολουθούμενη από έναν αριθμό που υποδεικνύει τη λειτουργία τροφοδοσίας
Για παράδειγμα: 3 $, που σημαίνει να θέσετε το σύστημα σε λειτουργία τροφοδοσίας 3.
(3) Διάγραμμα ροής προγράμματος
  • Διάγραμμα ροής κύριου προγράμματος
  • Διάγραμμα ροής προγράμματος διακοπής υπερχείλισης χρονοδιακόπτη 1
  • Διάγραμμα ροής της διαδικασίας διακοπής λήψης σειριακής θύρας




4. Εφαρμογή κωδικοποίησης
(1) Στρώμα αφαίρεσης υλικού
Το επίπεδο αφαίρεσης υλικού περιλαμβάνει τα ioCC2430.h και hal.h. Δεδομένου ότι το προηγούμενο σύστημα συνοδεύεται από αυτό, δεν θα καταχωρηθεί.
Ακολουθεί μια λίστα με όλα τα περιεχόμενα του hal.h (επειδή αυτό το αρχείο είναι πολύ μεγάλο και φαίνεται άβολο, θα το δείξω σε ενότητες):
  • κεφάλι
  • Θύρες εισόδου/εξόδου
  • Διακόπηκε
  • Σειριακή θύρα
  • Διαχείριση ισχύος και ρολογιού
  • Χρονοδιακόπτης
  • Σκύλος φύλακας
  • ADC
[url=] [/url]
/***********************************************************
*Όνομα αρχείου: hal.h
*Συγγραφέας: hustlzp
*Ημερομηνία: 8 Μαρτίου 2011
*Έκδοση: 1.1
*Περιγραφή λειτουργίας: Επίπεδο αφαίρεσης υλικού
*Τροποποιημένες εγγραφές:
**********************************************************
*/


#ifndef HAL_H
#defineHAL_H


#include


/***********************************************************
                       Κοινοί ορισμοί τύπων
**********************************************************
*/
typedef ανυπόγραφοκάρβουνο   BYTE;
typedef ανυπόγραφοΔιεθνές    ΛΈΞΗ;
typedef ανυπόγραφομακρύς   DWORD;



/***********************************************************
                       Ορισμοί μακροεντολών που χρησιμοποιούνται συχνά
**********************************************************
*/

//8 θέσεις ψηλότερα
#defineHIGH_BYTE(α) ((BYTE) (((WORD)(α)) >> 8))


//8 θέσεις χαμηλότερα
#defineLOW_BYTE(α) ((BYTE) ((WORD)(α)))


//Ανάθεση
#defineSET_WORD(regH,regL,λέξη)  
   κάνω{                           
      (regH)=HIGH_BYTE(λέξη);     
      (regL)=LOW_BYTE(λέξη);      
   }ενώ(0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Θύρες εισόδου/εξόδου
**********************************************************
*/
/*Διαμόρφωση της κατεύθυνσης θύρας I/O
-----------------------------------------
*/
#defineIO_DIR_PORT_PIN (θύρα, καρφίτσα, σκηνοθεσία)  
   κάνω{                                 
      αν(dir == IO_OUT)                 
         P##port##DIR |= (0x01<<(καρφίτσα));  
      αλλιώς                              
         P##port##DIR &= ~(0x01<<(καρφίτσα));
   }ενώ(0)



//Η τιμή της παραμέτρου dir είναι:
#defineIO_IN 0
#defineIO_OUT 1


/*Διαμορφώστε τη λειτουργία εισόδου της θύρας I/O
-----------------------------------------
*/
#defineIO_IMODE_PORT_PIN (θύρα, PIN, IMODE)
   κάνω{                                    
      αν(imode == IO_IMODE_TRI)            
         P##port##INP |= (0x01<<(καρφίτσα));     
      αλλιώς                                 
         P##port##INP &= ~(0x01<<(καρφίτσα));   
   }ενώ (0)



#define IO_PUD_PORT (λιμάνι, πουτί)        
   κάνω {                              
      αν (pud == IO_PULLDOWN)         
         P2INP |= (0x01 << (θύρα+5));
      αλλιώς                           
         P2INP &= ~(0x01 << (θύρα+5));
   } ενώ (0)


Η τιμή της παραμέτρου PUD είναι:
#define IO_PULLUP 0 // Τραβήξτε προς τα πάνω
#define IO_PULLDOWN 1 // Τραβήξτε προς τα κάτω


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

#define IO_FUNC_PORT_PIN (θύρα, καρφίτσα, λειτουργία)  
   κάνω {                                    
      if((θύρα == 2) && (pin == 3)){      
         αν (func) {                       
            P2SEL |= 0x02;                 
         } αλλιώς {                          
            P2SEL &= ~0x02;               
         }                                 
      }                                    
      αλλιώς if((θύρα == 2) && (καρφίτσα == 4)){  
         αν (func) {                       
            P2SEL |= 0x04;                 
         } αλλιώς {                          
            P2SEL &= ~0x04;               
         }                                 
      }                                    
      αλλιώς{                                
         αν (func) {                       
            P##port##SEL |= (0x01<<(καρφίτσα));
         } αλλιώς {                          
            P##port##SEL &= ~(0x01<<(pin));
        }                                 
      }                                    
   } ενώ (0)


Η τιμή της παραμέτρου func είναι:
#define IO_FUNC_GIO 0 // Γενικά I/O
#define IO_FUNC_PERIPH 1 // Περιφερειακά I/O


Διαμορφώστε τη θέση της περιφερειακής εισόδου/εξόδου
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } ενώ (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } ενώ (0)

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

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

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

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

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

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

//Η τιμή της παραμέτρου imode είναι:
#defineIO_IMODE_PUD 0   //Τραβήξτε προς τα πάνω/τραβήξτε προς τα κάτω
#defineIO_IMODE_TRI 1   //Τρεις πολιτείες[url=] [/url]

[url=] [/url]
/***********************************************************
                       Διακόπηκε
**********************************************************
*/
//Για διακοπές ενεργοποίησης/απενεργοποίησης
#defineINT_ON 1
#defineINT_OFF 0


//Χρησιμοποιείται για την τοποθέτηση/διαγραφή σημαιών διακοπής
#defineINT_SET 1
#defineINT_CLR 0


//Καθολικές ρυθμίσεις διακοπής
#defineINT_GLOBAL_ENABLE(on) EA=(!! επί)


//Ορισμός του διαλείμματος
#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


/*Επιτρέπονται διακοπές
-----------------------------------------
*/
#defineINT_ENABLE (inum, on)                        
   κάνω{                                             
      αν      (inum==INUM_RFERR) { RFERRIE = ενεργό; }  
      αλλιώς αν(inum==INUM_ADC)   { ADCIE = ενεργό; }  
      αλλιώς αν(inum==INUM_URX0)  { URX0IE = ενεργό; }  
      αλλιώς αν(inum==INUM_URX1)  { URX1IE = ενεργό; }  
      αλλιώς αν(inum==INUM_ENC)   { ENCIE = ενεργό; }  
      αλλιώς αν(inum==INUM_ST)    { STIE = ενεργό; }  
      αλλιώς αν(inum==INUM_P2INT) { (στις) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
      αλλιώς αν(inum==INUM_UTX0)  { (στις) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
      αλλιώς αν(inum==INUM_DMA)   { DMAIE = ενεργό; }  
      αλλιώς αν(inum==INUM_T1)    { T1IE = ενεργό; }  
      αλλιώς αν(inum==INUM_T2)    { T2IE = ενεργό; }  
      αλλιώς αν(inum==INUM_T3)    { T3IE = ενεργό; }  
      αλλιώς αν(inum==INUM_T4)    { T4IE = ενεργό; }  
      αλλιώς αν(inum==INUM_P0INT) { P0IE = ενεργό; }  
      αλλιώς αν(inum==INUM_UTX1)  { (στις) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
      αλλιώς αν(inum==INUM_P1INT) { (στις) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
      αλλιώς αν(inum==INUM_RF)    { (στις) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
      αλλιώς αν(inum==INUM_WDT)   { (στις) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
   }ενώ (0)


/*Ορίστε την προτεραιότητα διακοπής λειτουργίας
-----------------------------------------
*/
#defineINT_PRIORITY(ομάδα, pri)                     
   κάνω{                                               
      αν(pri ==0) { IP0 &= ~ομάδα; IP1 &= ~ομάδα; }
      αν(pri ==1) { IP0 |= ομάδα; IP1 &= ~ομάδα; }
      αν(pri ==2) { IP0 &= ~ομάδα; IP1 |= ομάδα; }
      αν(pri ==3) { IP0 |= ομάδα; IP1 |= ομάδα; }
   }ενώ (0)

//Η τιμή της παραμέτρου pri είναι: 0/1/2/3 (υψηλότερη προτεραιότητα)


//Η τιμή της ομάδας παραμέτρων είναι:
#defineRFERR_RF_DMA 0x01//Ομάδα IP0
#defineADC_P2INT_T1 0x02//Ομάδα IP1
#defineURX0_UTX0_T2 0x04//Ομάδα IP2
#defineURX1_UTX1_T3 0x08//Ομάδα IP3
#defineENC_P1INT_T4 0x10//Ομάδα IP4
#defineST_WDT_P0INT 0x20//Ομάδα IP5


/*Λήψη της σημαίας διακοπής
-----------------------------------------
*/
#defineINT_GETFLAG (inum) (                       
   (inum==INUM_RFERR) ? RFERRIF :
   (inum==INUM_ADC) ? ADCIF :
   (inum==INUM_URX0) ? URX0ΑΝ :
   (inum==INUM_URX1) ? URX1ΑΝ :
   (inum==INUM_ENC) ? ENCIF_0 :
   (inum==INUM_ST) ? ΣΤΙΦ :
   (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) ? Ρ0ΑΝ :
   (inum==INUM_UTX1) ? UTX1ΑΝ :
   (inum==INUM_P1INT) ? P1IF :
   (inum==INUM_RF) ? S1CON &= ~0x03    :
   (inum==INUM_WDT) ? WDTIF :
   0                                             
)


/*Ορισμός της σημαίας διακοπής
-----------------------------------------
*/
#defineINT_SETFLAG(inum, f)                     
   κάνω{                                          
      αν      (inum==INUM_RFERR) { RFERRIF= f; }
      αλλιώς αν(inum==INUM_ADC)   { ADCIF = f; }
      αλλιώς αν(inum==INUM_URX0)  { URX0IF = f; }
      αλλιώς αν(inum==INUM_URX1)  { URX1IF = f; }
      αλλιώς αν(inum==INUM_ENC)   { ENCIF_1 = ENCIF_0 = f; }
      αλλιώς αν(inum==INUM_ST)    { STIF = f;  }
      αλλιώς αν(inum==INUM_P2INT) { P2IF = f;  }
      αλλιώς αν(inum==INUM_UTX0)  { UTX0IF= f;  }
      αλλιώς αν(inum==INUM_DMA)   { DMAIF = f;  }
      αλλιώς αν(inum==INUM_T1)    { T1IF = f;  }
      αλλιώς αν(inum==INUM_T2)    { T2IF = f;  }
      αλλιώς αν(inum==INUM_T3)    { T3IF = f;  }
      αλλιώς αν(inum==INUM_T4)    { T4IF = f;  }
      αλλιώς αν(inum==INUM_P0INT) { P0IF = f;  }
      αλλιώς αν(inum==INUM_UTX1)  { UTX1IF= f;  }
      αλλιώς αν(inum==INUM_P1INT) { P1IF = f;  }
      αλλιώς αν(inum==INUM_RF)    { (στ) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
      αλλιώς αν(inum==INUM_WDT)   { WDTIF = f;  }
   }ενώ (0)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Σειριακή θύρα
**********************************************************
*/
//Η τιμή του BAUD_E που αντιστοιχεί σε διαφορετικούς ρυθμούς baud
#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  )


//Η τιμή του BAUD_M που αντιστοιχεί σε διαφορετικούς ρυθμούς baud
#defineBAUD_M(baud) (      
    (baud==2400)   ?  59  :
    (baud==4800)   ?  59  :
    (baud==9600)   ?  59  :
    (baud==14400)  ?  216 :
    (baud==19200)  ?  59  :
    (baud==28800)  ?  216 :
    (baud==38400)  ?  59  :
    (baud==57600)  ?  216 :
    (baud==76800)  ?  59  :
    (baud==115200) ?  216 :
    (baud==153600) ?  59  :
    (baud==230400) ?  216 :
    (baud==307200) ?  59  :
  0)


/*Διαμόρφωση σειριακής θύρας σε λειτουργία UART
-----------------------------------------
*/
#defineUART_SETUP(uart, receiveEnable, baudRate, επιλογές)      
   κάνω{                                                         
      αν((uart) ==0){                                          
         αν(PERCFG &0x01){                                    
            P1SEL |=0x30;                                      
         }αλλιώς{                                               
            P0SEL |=0x0C;                                      
         }                                                      
      }                                                         
      αλλιώς{                                                   
         αν(PERCFG &0x02){                                    
            P1SEL |=0xC0;                                      
         }αλλιώς{                                               
            P0SEL |=0x30;                                      
         }                                                      
      }                                                         
                                                               
      U##uart##GCR = BAUD_E((baudRate),CLKSPD);                 
      U##uart##BAUD = BAUD_M(baudRate);                        
                                                               
      U##uart##CSR |=0x80;                                    
                                                               
      U##uart##CSR |= receiveEnable;                           
                                                               
      U##uart##UCR |= ((επιλογές) |0x80);                       
   }ενώ(0)
     
//Η τιμή της παραμέτρου receiveEnable:
#defineUART_RECEIVE_ENABLE 0x40   //Λήψη άδειας
#defineUART_RECEIVE_DISABLE 0x00   
     
//Η τιμή των επιλογών παραμέτρων:
#defineFLOW_CONTROL_ENABLE 0x40   //Έλεγχος ροής
#defineFLOW_CONTROL_DISABLE 0x00


#defineEVEN_PARITY 0x20   //Περιστασιακή επαλήθευση
#defineODD_PARITY 0x00   //Παράξενη επαλήθευση


#defineNINE_BIT_TRANSFER 0x10   //Μεταφορά 9 byte
#defineEIGHT_BIT_TRANSFER 0x00   //Μεταφορά 8 byte


#definePARITY_ENABLE 0x08   //Ενεργοποίηση ελέγχου ισοτιμίας
#definePARITY_DISABLE 0x00

#defineTWO_STOP_BITS 0x04   //Θέση στάσης 2 θέσεων
#defineONE_STOP_BITS 0x00   //1 θέση στάσης


#defineHIGH_STOP 0x02   //Το επίπεδο στάσης είναι υψηλό
#defineLOW_STOP 0x00   //Η θέση στάσης είναι χαμηλή
     
#defineHIGH_START 0x01   //Το αρχικό επίπεδο bit είναι υψηλό
#defineLOW_START 0x00   //Το επίπεδο bit εκκίνησης είναι χαμηλό


//Η σειριακή θύρα στέλνει χαρακτήρες
#defineUART_SEND(uart,δεδομένα)            
   κάνω{                                 
     ενώ(U##uart##CSR &0x01);        
       U##uart##DBUF = δεδομένα;            
   }ενώ (0)
#defineUART0_SEND(δεδομένα) UART_SEND(0, δεδομένα)
#defineUART1_SEND(δεδομένα) UART_SEND(1,δεδομένα)


//Η σειριακή θύρα λαμβάνει χαρακτήρες
#defineUART_RECEIVE(uart,δεδομένα)         
   κάνω{                                 
     ενώ(! (U##uart##CSR&0x04));      
       δεδομένα=U##uart##DBUF;              
   }ενώ(0)
#defineUART0_RECEIVE(δεδομένα) UART_RECEIVE(0, δεδομένα)
#defineUART1_RECEIVE(δεδομένα) UART_RECEIVE(1,δεδομένα)
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Διαχείριση ισχύος και ρολογιού
**********************************************************
*/
//Αποκτήστε το crossover ρολογιού
#defineCLKSPD (CLKCON & 0x07)


//Ρυθμίστε τη λειτουργία τροφοδοσίας
#defineSET_POWER_MODE(λειτουργία)                  
   κάνω{                                       
      αν(λειτουργία ==0) { ΎΠΝΟΣ &= ~0x03; }
      αλλιώς αν(λειτουργία ==3) { ΎΠΝΟΣ |=0x03;  }
      αλλιώς{ ΎΠΝΟΣ &= ~0x03; SLEEP |= κατάσταση·  }
      ΠΚΟΝ |=0x01;                           
      asm("ΝΟΠ");                              
   }ενώ (0)


//Η λειτουργία παραμέτρων έχει οριστεί στις ακόλουθες τιμές:
#definePOWER_MODE_0 0x00  
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03


//Χρησιμοποιείται για την ανίχνευση της σταθερότητας ταλαντωτών RC υψηλής συχνότητας
#defineHIGH_FREQUENCY_RC_OSC_STABLE (ΎΠΝΟΣ &0x20)


//Χρησιμοποιείται για την ανίχνευση της σταθερής κατάστασης του κρυσταλλικού ταλαντωτή
#defineXOSC_STABLE (ΎΠΝΟΣ &0x40)


//Λάβετε την τιμή συχνότητας επιλογής του χρονοδιακόπτη
#defineTICKSPD ((CLKCON & 0x38) >> 3)


//Ρύθμιση της συχνότητας του κύριου ρολογιού
#defineSET_MAIN_CLOCK_SOURCE(πηγή)
   κάνω{                              
      αν(πηγή) {                    
        ΚΛΚΟΝ |=0x40;               
        ενώ(! HIGH_FREQUENCY_RC_OSC_STABLE);
        αν(TICKSPD ==0){            
          ΚΛΚΟΝ |=0x08;            
        }                             
        ΥΠΝΟΣ |=0x04;               
      }                              
      αλλιώς{                          
        ΥΠΝΟΣ &= ~0x04;               
        ενώ(! XOSC_STABLE);         
        asm("ΝΟΠ");                  
        CLKCON &= ~0x47;              
        ΥΠΝΟΣ |=0x04;               
      }                              
   }ενώ (0)


//Η τιμή της πηγής παραμέτρων είναι:
#defineΚΡΥΣΤΑΛΛΟ 0x00   //Κρυσταλλικός ταλαντωτής
#defineRC 0x01   //Ταλαντωτής RC
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Χρονοδιακόπτης 1
**********************************************************
*/
//Ο χρονοδιακόπτης 1 επιτρέπει τη διακοπή της υπερχείλισης μέτρησης
#defineTIMER1_ENABLE_OVERFLOW_INT(val)
   (TIMIF = (val) ? ΤΙΜΙΦ |0x40: TIMIF & ~0x40)


//Ορίστε τη σημαία διακοπής υπερχείλισης για το χρονόμετρο 1
#defineTIMER1_OVERFLOW_INT_SETFLAG(στ) (T1CTL= ((T1CTL & (~0x10)) | στ))


//Ξεκινά ο χρονοδιακόπτης 1
#defineTIMER1_RUN(τιμή) (T1CTL = (τιμή) ? T1CTL|0x02 : T1CTL&~0x03)


//Ρυθμίστε τη διαίρεση ρολογιού για το χρονόμετρο
#defineSET_TIMER_TICK(τιμή) do{ CLKCON = ((CLKCON &; (~0x38)) | τιμή); } ενώ(0)


//Η αξία της αξίας είναι:
#defineTIMER1_TICK_32M 0x00  //32 MHz
#defineTIMER1_TICK_16M 0x08  //16 MHz, η προεπιλεγμένη τιμή για επαναφορά συστήματος
#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  //500 kHz
#defineTIMER1_TICK_250k 0x38  //250 kHz

//Ρυθμίστε το crossover TICK για το χρονόμετρο 1
#defineSET_TIMER1_TICKDIV(τιμή)  
   κάνω{                             
     T1CTL &= ~0x0c;               
     T1CTL |= τιμή;               
   }ενώ (0)
      
//όπου η τιμή είναι:      
#defineTIMER1_TICKDIV_1 0x00   //1 τμήμα
#defineTIMER1_TICKDIV_8 0x04   //Συχνότητα 8 κατευθύνσεων
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c


//Ορίστε την περίοδο υπερχείλισης του χρονοδιακόπτη
#defineSET_TIMER1_PERIOD(τιμή)
   κάνω{                           
     T1CC0H = HIGH_BYTE(τιμή);  
     T1CC0L = LOW_BYTE(τιμή);   
   }ενώ (0)
     
//Ρυθμίστε τον τρόπο λειτουργίας του χρονοδιακόπτη 1
#defineSET_TIMER1_MODE(λειτουργία)  
   κάνω{                        
     T1CTL = ((T1CTL & (~0x03)) | τρόπος)·           
   }ενώ (0)


//Η τιμή της λειτουργίας είναι:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]

[url=] [/url]
/***********************************************************
                       Σκύλος φύλακας
**********************************************************
*/
//Ορισμός της περιόδου υπερχείλισης για το χρονόμετρο επιτήρησης
#defineWDT_SET_TIMEOUT_PERIOD(τάιμ άουτ)
   κάνω{ WDCTL &= ~0x03; WDCTL |= τάιμ άουτ; }ενώ (0)


//Η τιμή του χρονικού ορίου παραμέτρου είναι:
#defineSEC_1 0x00     //μετά από 1 δευτερόλεπτο
#defineM_SEC_250 0x01     //μετά από 250 ms
#defineM_SEC_15 0x02     //μετά από 15 ms
#defineM_SEC_2 0x03     //μετά από 2 ms


//Διαδικασίες σίτισης σκύλων
#defineWDT_RESET() κάνω {           
   WDCTL = (WDCTL & ~0xF0) |0xA0;
   WDCTL = (WDCTL & ~0xF0) |0x50;
} ενώ (0)


//Έναρξη/διακοπή του χρονοδιακόπτη επιτήρησης
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]

[url=] [/url]
/***********************************************************
                       ADC
**********************************************************
*/
//Διαμόρφωση ενός μεμονωμένου ADC
#defineADC_SINGLE_CONVERSION(ρυθμίσεις)
   κάνω{ ADCCON3 = ρυθμίσεις; }ενώ(0)

//Η ρύθμιση παραμέτρων αποτελείται από τους ακόλουθους συνδυασμούς:
//Τάση αναφοράς
#defineADC_REF_1_25_V 0x00     //Εσωτερική τάση αναφοράς 1,25V
#defineADC_REF_P0_7 0x40     //Εξωτερική τάση αναφοράς στον ακροδέκτη AIN7
#defineADC_REF_AVDD 0x80     //AVDD_SOC Καρφίτσες
#defineADC_REF_P0_6_P0_7 0xC0     //AIN6-AIN7 Εξωτερική τάση αναφοράς για διαφορικές εισόδους


//Ρυθμός δειγματοληψίας
#defineADC_8_BIT 0x00     //8η θέση
#defineADC_10_BIT 0x10     //10η θέση
#defineADC_12_BIT 0x20     //12η θέση
#defineADC_14_BIT 0x30     //14η θέση


//Μπείτε στο κανάλι
#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     //Οικόπεδα
#defineADC_TEMP_SENS 0x0E     //Αισθητήρας θερμοκρασίας εντός τσιπ
#defineADC_VDD_3 0x0F     //vdd/3




Η μετατροπή ADC ολοκληρώθηκε
#define ADC_SAMPLE_READY() (ADCCON1 &0x80)

#endif
//启动ADC转化
#define ADC_START()
  do { ADCCON1 |= 0x40; } ενώ (0)//Επιλέξτε τη λειτουργία ενεργοποίησης του ADC ως χειροκίνητη (δηλαδή, ADC_SAMPLE_READY)
#defineADC_STOP()  
  κάνω{ ADCCON1 |=0x30; }ενώ (0)[url=] [/url]


(2) Λειτουργικό επίπεδο μονάδας
  • module.h
  • ενότητα.γ
[url=] [/url]
/***********************************************************
*Όνομα αρχείου: module.h
*Συγγραφέας: hustlzp
*Ημερομηνία: 6 Μαρτίου 2011
*Έκδοση: 1.0
*Περιγραφή λειτουργίας: Αρχείο κεφαλίδας λειτουργικού επιπέδου μονάδας
*Λίστα λειτουργιών: void led_init()
            άκυρο timer1_init()
            άκυρο uart0_init(άκυρο)·
            void Uart0SendString(ανυπόγραφος χαρακτήρας *s);
            float adc_start(κενό)
            void get_temperature(ανυπόγραφος χαρακτήρας *έξοδος, float temp);
            άκυρο watchdog_init(κενό)·
*Τροποποιημένες εγγραφές:
**********************************************************
*/

#ifndef MODULE_H
#defineMODULE_H


#include"hal.h"


/***********************************************************
                        Λυχνία LED
**********************************************************
*/
//Ορίστε τις ακίδες LED
#defineLED1 P1_0         
#defineLED2 P1_1         
#defineLED3 P1_2         
#defineLED4 P1_3   

//Φως LED και σβηστό
#defineLED_OFF 1
#defineLED_ON 0

//Αρχικοποίηση LED
άκυροled_init(άκυρο);




/***********************************************************
                        Χρονόμετρο1
**********************************************************
*/
//Χρησιμοποιείται για τον ορισμό της τιμής της περιόδου υπερχείλισης για το χρονόμετρο
#defineTIMER1_OVF_2SEC 0xF424   //2 δευτ.
#defineTIMER1_OVF_1SEC 0x7A12   //1 δευτ
#defineTIMER1_OVF_dot5SEC 0x3D09   //0,5 δευτ.   

//Ο χρονοδιακόπτης 1 αρχικοποιείται
άκυρο  timer1_init(άκυρο);
                  

/***********************************************************
                        UART0
**********************************************************
*/
//Προετοιμασία UART0
άκυρο  uart0_init(άκυρο);                    

//Συμβολοσειρά μετάδοσης σειριακής θύρας
άκυρο  Uart0SendString(ανυπόγραφοκάρβουνο*s);
   

/***********************************************************
                        ADC-14
**********************************************************
*/
//Χρησιμοποιείται για τη μετατροπή των δεδομένων που λαμβάνονται από το ADC σε θερμοκρασία Κελσίου
#defineADC_TO_CELSIUS(temp) (θερμοκρασία * 0,06229 - 311,43)

//Έναρξη μετατροπής ADC
επιπλέουνadc_start(άκυρο);

//Μετατροπή
άκυρο  get_temperature (ανυπόγραφοκάρβουνο*παραγωγή,επιπλέουνθερμοκρασία);


/***********************************************************
                        Φύλακας
**********************************************************
*/
//Προετοιμασία σκύλου παρακολούθησης
άκυρο  watchdog_init(άκυρο);                 

#endif
[url=] [/url]

[url=] [/url]
/***********************************************************
*Όνομα αρχείου: module.c
*Συγγραφέας: hustlzp
*Ημερομηνία: 2011/3/11
*Έκδοση: 1.0
*Περιγραφή λειτουργίας: Αρχείο πηγής λειτουργικού επιπέδου μονάδας
*Λίστα λειτουργιών: (παραλείπεται)
*Τροποποιημένες εγγραφές:
**********************************************************
*/


#include"module.h"


/***********************************************************
*Όνομα λειτουργίας: led_init
*Λειτουργία λειτουργίας: Προετοιμασία LED
*Παράμετροι εισόδου: Καμία
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροled_init(άκυρο)
{
  //Διαμορφώστε τα P1.0, P1.1, P1.2 και P1.3 ως γενικές θύρες I/O
  IO_FUNC_PORT_PIN(1, 0, IO_FUNC_GIO)·
  IO_FUNC_PORT_PIN(1, 1, IO_FUNC_GIO)·
  IO_FUNC_PORT_PIN(1, 2, IO_FUNC_GIO)·
  IO_FUNC_PORT_PIN(1, 3, IO_FUNC_GIO)·
  
  //Διαμορφώστε τα P1.0, P1.1, P1.2 και P1.3 ως εξόδους
  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;
}


/***********************************************************
*Όνομα λειτουργίας: timer1_init
* Λειτουργία λειτουργίας: Προετοιμασία χρονοδιακόπτη 1
*Παράμετροι εισόδου: Καμία
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροtimer1_init(άκυρο)
{
  INT_GLOBAL_ENABLE(INT_ON);                 //Άνοιγμα της καθολικής διακοπής
  
  INT_ENABLE(INUM_T1, INT_ON)·               //Ανοίξτε τη διακοπή T1

  TIMER1_ENABLE_OVERFLOW_INT παράγραφος INT_ON)·        //Ανοίξτε τη διακοπή υπερχείλισης μέτρησης T1
  
  SET_TIMER_TICK παράγραφος TIMER1_TICK_4M)·            //Ρυθμίστε το χρονόμετρο TICK στα 4 MHz
  
  SET_TIMER1_PERIOD παράγραφος TIMER1_OVF_2SEC)·        //Ορίστε την περίοδο μέτρησης για το T1 σε 2 δευτερόλεπτα
  
  SET_TIMER1_TICKDIV παράγραφος TIMER1_TICKDIV_128)·   //Ρυθμίστε το crossover ρολογιού για το T1 στο 128
  
  SET_TIMER1_MODE παράγραφος TIMER1_MODE_MODULE·      //Ρυθμίστε τη λειτουργία λειτουργίας του T1 σε μονάδα
}


/***********************************************************
*Όνομα λειτουργίας: uart0_init
*Λειτουργία λειτουργίας: Προετοιμασία σειριακής θύρας UART0
*Παράμετροι εισόδου: Καμία
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροuart0_init(άκυρο)
{
  //Επιλέξτε τη θέση UART
  IO_PER_LOC_UART0_AT_PORT0_PIN2345();
  
  //Διαμόρφωση UART: Επιτρέπεται λήψη, 115200bps, bit διακοπής ενός bit, χωρίς ισοτιμία
  UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);

  //Ανοίξτε την ολική διακοπή
  INT_GLOBAL_ENABLE(INT_ON);      

  //Ανοίξτε τη σειριακή θύρα 0 για να λάβετε διακοπές
  INT_ENABLE(INUM_URX0, INT_ON)·   
}


/***********************************************************
*Όνομα συνάρτησης: Uart0SendString
* Λειτουργία λειτουργίας: Προετοιμασία χρονοδιακόπτη 1
*Παράμετρος εισόδου: ανυπόγραφος χαρακτήρας *s
            Η συμβολοσειρά που θέλετε να στείλετε
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροUart0SendString(ανυπόγραφοκάρβουνο*ιθ)
{
  ενώ(*s !=0)         
    UART0_SEND(*s++);
}


/***********************************************************
*Όνομα λειτουργίας: adc_start
*Λειτουργία λειτουργίας: Έναρξη μετατροπής ADC
*Παράμετροι εισόδου: Καμία
*Παράμετρος εξαγωγής: πλωτήρας
            Η τιμή θερμοκρασίας στο δισκίο
**********************************************************
*/
επιπλέουνadc_start(άκυρο)
{
  ανυπόγραφοΔιεθνέςθερμοκρασία;
  
  //Η τάση αναφοράς είναι 1,25 V, η ακρίβεια δειγματοληψίας είναι 14 bit και ο στόχος μετατροπής είναι ο αισθητήρας θερμοκρασίας στο τσιπ
  ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
  
  ADC_STOP();                           //Ορίστε τη μέθοδο ενεργοποίησης για τη μετατροπή ADC σε μη αυτόματη
  
  ADC_START();                           //Έναρξη μετατροπής ADC
  
  ενώ(! ADC_SAMPLE_READY())·            //Περιμένετε να ολοκληρωθεί η μετατροπή
  
  temp = ADCL >>2;                     //Αποθηκεύστε τα αποτελέσματα μετατροπής σε θερμοκρασία
  temp |= (((ανυπόγραφοΔιεθνές) ADCH) <<6);
  
  ΕπιστροφήADC_TO_CELSIUS(temp);           //Επιστρέφει την πραγματική τιμή θερμοκρασίας μετά τη μετατροπή
}


/***********************************************************
*Όνομα λειτουργίας: get_temperature
*Λειτουργία λειτουργίας: Επεξεργαστείτε την τιμή θερμοκρασίας και αποθηκεύστε την στον πίνακα χαρακτήρων για σειριακή έξοδο
*Παράμετρος εισόδου: ανυπόγραφος χαρακτήρας *έξοδος
            Χρησιμοποιείται για την αποθήκευση της τιμής θερμοκρασίας που έχει μετατραπεί
            Θερμοκρασία επίπλευσης
            Τιμή θερμοκρασίας Κελσίου
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροget_temperature (ανυπόγραφοκάρβουνο*παραγωγή,επιπλέουνtemp)
{
  output[0] = (ανυπόγραφοκάρβουνο)(temp) /10 + 48;         //Δέκα θέσεις
  output[1] = (ανυπόγραφοκάρβουνο(temp) %10 + 48;         //μονοψήφιο
  output[2] ='.';                                      //Υποδιαστολή
  output[3] = (ανυπόγραφοκάρβουνο)(temp*10) %10 + 48;      //Δέκατο
  output[4] = (ανυπόγραφοκάρβουνο)(temp*100) %10 + 48;      //Εκατοστημόριο
  output[5] ='';                                    //Ενδοποιητές συμβολοσειρών
}


/***********************************************************
*Όνομα λειτουργίας: watchdog_init
*Λειτουργία λειτουργίας: Προετοιμασία σκύλου ρολογιού
*Παράμετροι εισόδου: Καμία
*Παράμετροι εξαγωγής: Καμία
**********************************************************
*/
άκυροwatchdog_init(άκυρο)
{
  WDT_SET_TIMEOUT_PERIOD παράγραφος SEC_1)·   //Ορίστε το χρονικό όριο σε 1 δευτερόλεπτο
  WDT_ENABLE();                    //Ξεκινήστε τον φύλακα
}
[url=] [/url]


(3) Επίπεδο εφαρμογής
  • main.c
[url=] [/url]
/*******************************************************************
Όνομα αρχείου: main.c
Συγγραφέας: hustlzp
Ημ/νία: 2011/3/11
Έκδοση: 1.0
Περιγραφή λειτουργίας: Κύριο αρχείο προγράμματος
Λίστα λειτουργιών: (παραλείπεται)
Εγγραφή τροποποίησης:
******************************************************************
*/


#include




/********************************************************************
                             Διαδικασίες διακοπής υπηρεσίας
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma διάνυσμα=T1_VECTOR
__interrupt άκυρο T1_ISR(άκυρο)
{
  ΕΑ=0;                                   Η πύλη διακόπτεται
  
  LED2 = LED_ON;                          
  
  get_temperature(έξοδος,adc_start());    Μετατρέψτε την τιμή θερμοκρασίας σε έναν πίνακα χαρακτήρων που θα εξάγονται
   
  Uart0SendString(έξοδος);                Τιμή θερμοκρασίας εξόδου
  Uart0SendString("°C");  


  LED2


/* 串口接收中断子程序
-------------------------------------------------------*/
#pragma διάνυσμα=URX0_VECTOR
__interrupt άκυρο RE_ISR(άκυρο)
{
  ΕΑ=0;
  
  LED3 = LED_ON;

  λήψη = U0DBUF;   
  
  if(type==1) // type=1, το οποίο υποδεικνύει ότι ο λαμβανόμενος χαρακτήρας χρησιμοποιείται για τον ορισμό της περιόδου υπερχείλισης του χρονοδιακόπτη
  {
    τύπος=0;
    διακόπτης (λήψη)
    {
      περίπτωση '0': // Η περίοδος υπερχείλισης του χρονοδιακόπτη είναι 0,5 δευτερόλεπτα
      {
        SET_TIMER1_PERIOD παράγραφος TIMER1_OVF_dot5SEC·
        διάλειμμα;
      }
      περίπτωση '1': // Η περίοδος υπερχείλισης του χρονοδιακόπτη είναι 1 δευτερόλεπτο
      {
        SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
        διάλειμμα;
      }
      περίπτωση '2': // Η περίοδος υπερχείλισης του χρονοδιακόπτη είναι 2 δευτερόλεπτα
      {
        SET_TIMER1_PERIOD παράγραφος TIMER1_OVF_2SEC)·
        διάλειμμα;         
      }
    }
  }
  else if(type==2) // type=2, υποδεικνύοντας ότι οι χαρακτήρες που λαμβάνονται χρησιμοποιούνται για τον έλεγχο του ύπνου
  {
    τύπος=0;
    led1 = LED_OFF;
    LED2 = LED_OFF;
    LED3 = LED_OFF;
    διακόπτης (λήψη)
    {
      περίπτωση «1»: // Είσοδος σε κατάσταση κατανάλωσης PM1
      {
        SET_POWER_MODE παράγραφος 1·  
        διάλειμμα;
      }
      περίπτωση «2»: // Είσοδος σε κατάσταση κατανάλωσης PM2
      {
        SET_POWER_MODE παράγραφος 2·  
        διάλειμμα;
      }
      περίπτωση «3»: //Είσοδος σε κατάσταση κατανάλωσης PM3
      {
        SET_POWER_MODE παράγραφος 3·  
        διάλειμμα;
      }
    }
  }
  else if(type==0) // type=0, που υποδεικνύει ότι ο λαμβανόμενος χαρακτήρας είναι ο τύπος της εντολής ελέγχου: @ ή $
  {
    if(receive=='@')  
    {
      τύπος=1;     Το '@' λαμβάνεται για να υποδείξει ότι ο επόμενος χαρακτήρας χρησιμοποιείται για τον ορισμό της περιόδου υπερχείλισης
    }
    αλλιώς if(receive=='$')
    {
      τύπος=2;     Λαμβάνεται το '$', υποδεικνύοντας ότι ο επόμενος χαρακτήρας χρησιμοποιείται για τον έλεγχο αναστολής λειτουργίας του συστήματος
    }
  }
  
  LED3 = LED_OFF;
   
  ΕΑ=1;
}
=LED_OFF;
  
  TIMER1_OVERFLOW_INT_SETFLAG παράγραφος INT_CLR)·   Διαγράψτε το σύμβολο διακοπής
  
  ΕΑ=1;                                   Ανοιχτή διακοπή  
}
/* 主函数
-------------------------------------------------------*/
void main(κενό)
{
  SET_MAIN_CLOCK_SOURCE(ΚΡΎΣΤΑΛΛΟ);  Ρυθμίστε το ρολόι του συστήματος σε ταλαντωτή κρυστάλλου 32 MHz
  
  led_init();                      Αρχικοποίηση LED
  
  uart0_init();                    Προετοιμασία UART0 σειριακής θύρας
  
  timer1_init();                   Ο χρονοδιακόπτης 1 αρχικοποιείται
  
  watchdog_init();                 Προετοιμασία σκύλου παρακολούθησης
  
  ενώ(1)
  {
    WDT_RESET();                   Ταΐστε τον σκύλο συνεχώς
  }
}/********************************************************************
                            Κυρίως πρόγραμμα   
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
ανυπόγραφη έξοδος χαρακτήρων[6]={0};       Τα δεδομένα θερμοκρασίας αποθηκεύονται για εύκολη σειριακή έξοδο
ανυπόγραφο char λαμβάνω?             Αποθηκεύστε τους χαρακτήρες που λάβατε
ανυπόγραφος τύπος χαρακτήρων=0;              Η σημαία τύπου του ληφθέντος χαρακτήρα έχει οριστεί σε 0/1/2"module.h"[url=] [/url]


5. Δοκιμές
Ω~ Ο κώδικας επιτέλους επικολλήθηκε, είναι πραγματικά εξαντλητικός, ας δοκιμάσουμε αυτό το μικρό σύστημα:
(1) Χρονομετρημένη δειγματοληψία
Ανοίξτε τη σειριακή θύρα και ξεκινήστε τον εντοπισμό σφαλμάτων IAR και βρείτε ότι το led1 είναι ενεργοποιημένο και η τιμή θερμοκρασίας στο εργαλείο σειριακής θύρας δημιουργείται συνεχώς και το διάστημα δειγματοληψίας προσδιορίζεται σε 2 δευτερόλεπτα:
(2) Έλεγχος διαστήματος δειγματοληψίας
Πληκτρολογήστε "@1" στο εργαλείο σειριακής θύρας και, στη συνέχεια, δοκιμάστε το διάστημα δειγματοληψίας και βρείτε ότι έχει γίνει 1s. Πληκτρολογήστε "@0" και το διάστημα δειγματοληψίας έχει αλλάξει σε 0,5 δευτ.
(3) Έλεγχος ύπνου
Εισαγάγετε "$1" στο εργαλείο σειριακής θύρας και βρείτε ότι όλα τα LED είναι σβηστά και η δειγματοληψία θερμοκρασίας έχει σταματήσει:
Μετά τη δοκιμή, το σύστημα λειτουργεί κανονικά και σταθερά και βασικά πληροί τις απαιτήσεις.
Μαθητές που χρειάζονται πηγαίο κώδικαΚάντε κλικ εδώ για να κατεβάσετε
6. Συμπέρασμα
Αυτή η εργασία παίρνει ένα ελαφρώς περιεκτικό πείραμα ως παράδειγμα για να δείξει πώς να ενσωματώσετε πόρους CC2430 στο τσιπ για να γράψετε ένα σχετικά τυποποιημένο μικρό σύστημα. Σε λίγες μέρες, θα αφιερώσω χρόνο για να γράψω ένα απλό εγχειρίδιο χρήσης για το hal.h, ώστε εγώ και όλοι να μπορούμε να χειριστούμε εύκολα το CC2430.
Στη συνέχεια, θα ολοκληρώσω την έρευνά μου σχετικά με τους πόρους CC2430 στο τσιπ και θα αφοσιωθώ στην εκμάθηση της στοίβας πρωτοκόλλου TI Z-Stack~
Η συγγραφή της ανάρτησης ιστολογίου σε αυτή τη σειρά έχει τελειώσει προς το παρόν, αλλά το ταξίδι του Zigbee θα συνεχιστεί. Το τοπίο μπροστά είναι άγνωστο, αλλά πιστεύω ότι ο συγγραφέας θα ξεπεράσει τα εμπόδια με όλους και θα γευτεί τα σκαμπανεβάσματα και θα υπάρξουν κέρδη.
Μείνετε συντονισμένοι: Αναρτήσεις ιστολογίου "Εγγραφείτε στο TI Z-Stack"!















Προηγούμενος:Ταξίδι με Zigbee (9): Αρκετά σημαντικά βασικά πειράματα CC2430 - συστηματικός ύπνος και διακοπτόμενη εγρήγορση
Επόμενος:Σήμερα είναι Απόκριες, πώς θα διασκεδάσετε;
Δημοσιεύτηκε στις 31/10/2014 8:04:14 π.μ. |
Συγχωρέστε με που δεν καταλαβαίνω τίποτα
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com