Miután március 3-án megírta a "Zigbee Journey (9)" című könyvet, eredetileg azt tervezte, hogy azonnal elkezd egy kis kísérletet a "hőmérséklet-megfigyelő rendszerről", amely összefoglalja a korábban elszórt tudáspontokat. Ugyanakkor azt is felismertem, hogy bár az előző kis kísérletek mindegyike részletesen le volt írva, a kódjának normatív és szerkezeti jellege elviselhetetlennek is nevezhető. Mivel összefoglaló, az eredeti alapon kell haladnunk, nem pedig mechanikusan rakkodnunk a korábbi apró tudáspontok összerakására. Ezért félretettem az eredeti tervemet, időt szántam arra, hogy elsajátítsam az ágyazott fejlesztés általános technikáit, és két esszét írtamBeágyazott C51 programozási specifikáció" és "A beágyazott projektkód szerkezetének hierarchiája》。 Ez a napló nemcsak Zigbee első utazásának összefoglalása, hanem a szerző legutóbbi napokban szerzett tapasztalatait is beépíti, remélve, hogy hasznos lehet a Zigbee kezdőknek.
A teljes szöveg a szoftverfejlesztés alapvető folyamata szerint van szervezve: követelmények elemzése, vázlattervezés, részletes tervezés, kódolás megvalósítása és tesztelés.
1. KeresletelemzésAz "ügyfél" és a "fejlesztő" közötti egyeztetés után a következő rendszerfunkció leírást határozták meg:
… Az aktuális szobahőmérsékletet CC2430-alapú csomópontok gyűjtik, és hőmérsékleti értékei PC segítségével figyelhetők
… A CC2430 csomópontnak magának bizonyos stabilitásnak kell lennie, és automatikusan visszatérhet normál állapotba
… A csomó mintavételi intervallumát és energiamenedzsmentjét egy PC vezérelheti
2. Vázlat tervezéseA fenti követelményelemzés alapján a rendszert két modulra oszthatjuk:CC2430 csomópontésPC。
[CC2430 csomópont]
… Külső paraméterek rendszeresen gyűjthetők és elküldhetők a PC-nek
… Automatikus visszaállítás, amikor a gép ki van kapcsolva
… A PC-ből érkező parancsok ennek megfelelően fogadhatók és feldolgozhatók: változtasd meg a mintaintervallumot/energiamenedzsmentet
[PC]
… A C gép adatokat fogad és jelenít meg a soros port eszközön keresztül
… Utasításokat a soros port eszközön keresztül küldhetnek a mikrokontrollernek, hogy szabályozzák a mintavételi sebességet és az energiagazdálkodást
3. Részletes tervezés(1) Kódstruktúra
A rendszer kódszerkezetének rétegeződését valójában az esszé is leírta "A beágyazott projektkód szerkezetének hierarchiája", és a másolat a következő:
(1) Hardveres absztrakciós réteg
[ioCC2430.h] (Rendszer benne):A CC2430 összes SFR és megszakítási vektora definiálva van
[hal.h] Tartalmazza a közös típusdefiníciókat, közös hozzárendelési makrókat, valamint a CC2430 chipen belüli erőforrások (I/O, soros kommunikáció, ADC, időzítő, energiamenedzsment stb.) konfigurációját
(2) Funkcionális modulréteg
[module.h] definiálja a chipen belüli erőforrásokat (időzítők, I/O), off-chip bővítő modulokat (LED-eket), valamint kapcsolódó függvények deklarációit
[module.cValósítsd meg minden modul (LED) inicializálását.
(3) Alkalmazási réteg
[main.cLásd a hal.h, ioCC2430.h és module.h fájlokat, hogy elérd a speciális alkalmazási követelményeket, mint például a hőmérséklet-mérés, a PC-vel való kommunikáció, valamint a leállítás és visszaállítás
(2) Minden modul megvalósítási módszerei
A modulok körvonal szerint elosztása szerint az intrinsikus rendszer két fő modulra osztható:CC2430 csomópontésPC。
Mivel a PC-n vannak soros port kommunikációs eszközök, a funkciók megfelelnek a követelményeknek, így nem kell ezt a részt elvégeznünk, és nem kell elemezni. Beszélj az alábbi CC2430 szakaszról
A pont minden alfüggvényének megvalósítási módszere:
… Használd az időzítő számának túlcsordulmas megszakítását az időzített mintavételezés elindításához
… Az UART0 mód soros porttal hőmérsékleti adatokat továbbít egy PC-re
… A CC2430 beépített watchdog áramkörét használják a rendszer automatikus visszaállítási funkciójának megvalósítására
… A soros port a megszakítások fogadására szolgál, amely a PC vezérlőparancsaira rögzíti és válaszol
1) Ha megkapják@A karakter a mintavételi intervallum vezérlőparancs, majd egy szám, amely a mintavételi intervallumot jelzi: 0-0,5s, 1-1s, 2-2s
如:@0,表示每隔0.5秒采样一次。
2) Ha megérkezik$ A karakter az alvó vezérlő parancs, amelyet egy szám követ az áramellátás módját jelzi
Például: $3, ami azt jelenti, hogy a rendszert 3-as üzemmódba kell állítani.
(3) Programáramlási diagram
- Mesterképzési folyamatábra
- 1. időzítő Túlcsordulás megszakítási program folyamatábra
- Soros port vételi megszakítási eljárás folyamatábra
4. Kódolási megvalósítás(1) Hardveres absztrakciós réteg
A hardveres absztrakciós réteg tartalmazza az ioCC2430.h és hal.h rendszert. Mivel az előzői rendszer is benne van, nem lesz feltüntetve.
Az alábbiakban felsoroljuk a hal.h összes tartalmát (mivel ez a fájl túl hosszú és kényelmetlennek tűnik, modulokban fogom megmutatni):
- fej
- I/O portok
- Megszakítva
- Soros port
- Teljesítmény- és órajel-menedzsment
- Időzítő
- Őrőr kutya
- ADC
[url=]
[/url]
/***********************************************************
*Fájl neve: hal.h
*Szerző: hustlzp
*Dátum: 2011. március 8.
*Kiadás: 1.1
*Funkcióleírás: Hardveres absztrakciós réteg
*Módosított rekordok:
***********************************************************/
#ifndef HAL_H
#defineHAL_H
#include
/***********************************************************
Gyakori típusmeghatározások
***********************************************************/
typedef nem aláírtchar BYTE;
typedef nem aláírtint SZÓ;
typedef nem aláírthosszú DWORD;
/***********************************************************
Gyakran használt makrodefiníciók
***********************************************************/
//8 helytel magasabb
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))
//8 hely alacsonyabb
#defineLOW_BYTE(a) ((BÁJT) ((SZÓ)(a)))
//Beosztás
#defineSET_WORD(regH,regL,word)
csinál{
(regH)=HIGH_BYTE(szó);
(regL)=LOW_BYTE(szó);
}miközben(0)
[url=] [/url]
[url=] [/url]
/***********************************************************
I/O portok
***********************************************************/
/*Konfiguráld az I/O port irányát
-----------------------------------------*/
#defineIO_DIR_PORT_PIN(port, tűz, direkció)
csinál{
ha(dir == IO_OUT)
P##port##DIR |= (0x01<<(tű));
más
P##port##DIR &= ~(0x01<<(tű));
}miközben(0)
//A dir paraméter értéke a következő:
#defineIO_IN 0
#defineIO_OUT 1
/*Konfiguráld az I/O port bemeneti módját
-----------------------------------------*/
#defineIO_IMODE_PORT_PIN(port, PIN, imode)
csinál{
ha(imode == IO_IMODE_TRI)
P##port##INP |= (0x01<<(tű));
más
P##port##INP &= ~(0x01<<(tű));
}miközben (0)
#define IO_PUD_PORT(port, pud)
do {
ha (pud == IO_PULLDOWN)
P2INP |= (0x01 << (port+5));
más
P2INP &= ~(0x01 << (port+5));
} míg (0)
A PUD paraméter értéke a következő:
#define IO_PULLUP 0 // Húzd fel
#define IO_PULLDOWN 1 // Húzd le
/*配置I/O口的功能
-----------------------------------------*/
#define IO_FUNC_PORT_PIN(port, tű, funkció)
do {
if((port == 2) && (pin == 3)){
if (func) {
P2SEL |= 0x02;
} más {
P2SEL &= ~0x02;
}
}
else if((port == 2) && (pin == 4)){
if (func) {
P2SEL |= 0x04;
} más {
P2SEL &= ~0x04;
}
}
else{
if (func) {
P##port##SEL |= (0x01<<(tű));
} más {
P##port##SEL &= ~(0x01<<(pin));
}
}
} míg (0)
A func paraméter értéke a következő:
#define IO_FUNC_GIO 0 // Általános I/O
#define IO_FUNC_PERIPH 1 // Perifériás I/O
Konfiguráld a perifériás I/O helyét
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } míg (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } míg (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN34() do { PERCFG = (PERCFG&~0x20)|0x00; } míg (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN67() do { PERCFG = (PERCFG&~0x20)|0x20; } míg (0)
#define IO_PER_LOC_TIMER4_AT_PORT1_PIN01() do { PERCFG = (PERCFG&~0x10)|0x00; } míg (0)
#define IO_PER_LOC_TIMER4_AT_PORT2_PIN03() do { PERCFG = (PERCFG&~0x10)|0x10; } míg (0)
#define IO_PER_LOC_SPI1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x08)|0x00; } míg (0)
#define IO_PER_LOC_SPI1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x08)|0x08; } míg (0)
#define IO_PER_LOC_SPI0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x00; } míg (0)
#define IO_PER_LOC_SPI0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x04; } míg (0)
#define IO_PER_LOC_UART1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x02)|0x00; } míg (0)
#define IO_PER_LOC_UART1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x02)|0x02; } míg (0)
#define IO_PER_LOC_UART0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x00; } míg (0)
#define IO_PER_LOC_UART0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x01; } míg (0)
//Az imode paraméter értéke a következő:
#defineIO_IMODE_PUD 0 //Húzd fel/húzd le
#defineIO_IMODE_TRI 1 //Három állam[url=] [/url]
[url=] [/url]
/***********************************************************
Megszakítva
***********************************************************/
//Kapcsolva/kikapcsolt megszakításokhoz
#defineINT_ON 1
#defineINT_OFF 0
//Megszakítási zászlókat helyezek/törölni használtak
#define1. INT_SET
#defineINT_CLR 0
//Globális megszakítás beállítások
#defineINT_GLOBAL_ENABLE(on) EA=(!! be)
//Definiáljuk a törést
#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
/*Megengedett megszakítások
-----------------------------------------*/
#defineINT_ENABLE(inum, on)
csinál{
ha (inum==INUM_RFERR) { RFERRIE = bekapcsolva; }
más ha(inum==INUM_ADC) { ADCIE = bekapcsolva; }
más ha(inum==INUM_URX0) { URX0IE = bekapcsolva; }
más ha(inum==INUM_URX1) { URX1IE = bekapcsolva; }
más ha(inum==INUM_ENC) { ENCIE = be; }
más ha(inum==INUM_ST) { STIE = bekapcsolva; }
más ha(inum==INUM_P2INT) { (bekapcsolva) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
más ha(inum==INUM_UTX0) { (bekapcsolva) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
más ha(inum==INUM_DMA) { DMAIE = bekapcsolva; }
más ha(inum==INUM_T1) { T1IE = bekapcsolva; }
más ha(inum==INUM_T2) { T2IE = bekapcsolva; }
más ha(inum==INUM_T3) { T3IE = bekapcsolva; }
más ha(inum==INUM_T4) { T4IE = bekapcsolva; }
más ha(inum==INUM_P0INT) { P0IE = bekapcsolva; }
más ha(inum==INUM_UTX1) { (bekapcsolva) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
más ha(inum==INUM_P1INT) { (bekapcsolva) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
más ha(inum==INUM_RF) { (bekapcsolva) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
más ha(inum==INUM_WDT) { (bekapcsolva) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
}miközben (0)
/*Állítsd be a kimaradási prioritást
-----------------------------------------*/
#defineINT_PRIORITY(csoport, pri)
csinál{
ha(pri ==0) { IP0 &= ~csoport; IP1 &= ~csoport; }
ha(pri ==1) { IP0 |= csoport; IP1 &= ~csoport; }
ha(pri ==2) { IP0 &= ~csoport; IP1 |= csoport; }
ha(pri ==3) { IP0 |= csoport; IP1 |= csoport; }
}miközben (0)
//A pri paraméter értéke: 0/1/2/3 (legmagasabb prioritás)
//A paramétercsoport értéke a következő:
#defineRFERR_RF_DMA 0x01//IP0 csoport
#defineADC_P2INT_T1 0x02//IP1 csoport
#defineURX0_UTX0_T2 0x04//IP2 csoport
#defineURX1_UTX1_T3 0x08//IP3 csoport
#defineENC_P1INT_T4 0x10//IP4 csoport
#defineST_WDT_P0INT 0x20//IP5 csoport
/*Szerezd meg a megszakítási zászlót
-----------------------------------------*/
#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
)
/*Állítsd be a megszakítási zászlót
-----------------------------------------*/
#defineINT_SETFLAG(inum, f)
csinál{
ha (inum==INUM_RFERR) { RFERRIF= f; }
más ha(inum==INUM_ADC) { ADCIF = f; }
más ha(inum==INUM_URX0) { URX0IF = f; }
más ha(inum==INUM_URX1) { URX1IF = f; }
más ha(inum==INUM_ENC) { ENCIF_1 = ENCIF_0 = f; }
más ha(inum==INUM_ST) { STIF = f; }
más ha(inum==INUM_P2INT) { P2IF = f; }
más ha(inum==INUM_UTX0) { UTX0IF= f; }
más ha(inum==INUM_DMA) { DMAIF = f; }
más ha(inum==INUM_T1) { T1IF = f; }
más ha(inum==INUM_T2) { T2IF = f; }
más ha(inum==INUM_T3) { T3IF = f; }
más ha(inum==INUM_T4) { T4IF = f; }
más ha(inum==INUM_P0INT) { P0IF = f; }
más ha(inum==INUM_UTX1) { UTX1IF= f; }
más ha(inum==INUM_P1INT) { P1IF = f; }
más ha(inum==INUM_RF) { (f)? (S1CON |=0x03) : (S1CON &= ~0x03); }
más ha(inum==INUM_WDT) { WDTIF = f; }
}miközben (0)
[url=] [/url]
[url=] [/url]
/***********************************************************
Soros port
***********************************************************/
//A BAUD_E értéke különböző baud sebességeknek felel meg
#defineBAUD_E(búd, 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 )
//A BAUD_M értéke különböző baud sebességeknek felel meg
#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)
/*Soros port konfiguráció UART módban
-----------------------------------------*/
#defineUART_SETUP(uart, receiveEnable, baudRate, opciók)
csinál{
ha((uart) ==0){
ha(PERCFG &0x01){
P1SEL |=0x30;
}más{
P0SEL |=0x0C;
}
}
más{
ha(PERCFG &0x02){
P1SEL |=0xC0;
}más{
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 |= ((opciók) |0x80);
}miközben(0)
//A receive paraméter értékeEnable értéke:
#defineUART_RECEIVE_ENABLE 0x40 //Engedély megszerzése
#defineUART_RECEIVE_DISABLE 0x00
//A paraméteropciók értéke:
#defineFLOW_CONTROL_ENABLE 0x40 //Áramlásirányítás
#defineFLOW_CONTROL_DISABLE 0x00
#defineEVEN_PARITY 0x20 //Alkalmi ellenőrzés
#defineODD_PARITY 0x00 //Furcsa ellenőrzés
#defineNINE_BIT_TRANSFER 0x10 //9 bájtos átvitel
#defineEIGHT_BIT_TRANSFER 0x00 //8 bájtos átvitel
#definePARITY_ENABLE 0x08 //Paritásellenőrzés engedélyezése
#definePARITY_DISABLE 0x00
#defineTWO_STOP_BITS 0x04 //2 pozíciós megállás pozíció
#defineONE_STOP_BITS 0x00 //1 álláspozíció
#defineHIGH_STOP 0x02 //A megállás szintje magas
#defineLOW_STOP 0x00 //A megállás pozíciója alacsony
#defineHIGH_START 0x01 //A kezdő bit szintje magas
#defineLOW_START 0x00 //A kezdő bit szintje alacsony
//A sorozatos port karaktereket küld
#defineUART_SEND(uart,data)
csinál{
miközben(U##uart##CSR &0x01);
U##uart##DBUF = data;
}miközben (0)
#defineUART0_SEND(adat) UART_SEND(0,adat)
#defineUART1_SEND(adat) UART_SEND(1,data)
//A sorozatos port karaktereket fogad
#defineUART_RECEIVE(uart,data)
csinál{
miközben(! (U##uart##CSR&0x04));
data=U##uart##DBUF;
}miközben(0)
#defineUART0_RECEIVE(adat) UART_RECEIVE(0,adat)
#defineUART1_RECEIVE(adat) UART_RECEIVE(1,adat)
[url=] [/url]
[url=] [/url]
/***********************************************************
Teljesítmény- és órajel-menedzsment
***********************************************************/
//Szerezd meg az óra keresztezését
#defineCLKSPD (CLKCON & 0x07)
//Állítsd be az energia üzemmódot
#defineSET_POWER_MODE(mód)
csinál{
ha(mód ==0) { ALVÁS &= ~0x03; }
más ha(mód ==3) { ALVÁS |=0x03; }
más{ ALVÁS &= ~0x03; ALVÁS |= mód; }
PCON |=0x01;
asm("NOP");
}miközben (0)
//A paramétermód a következő értékekre van állítva:
#definePOWER_MODE_0 0x00
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03
//A nagyfrekvenciás RC oszcillátorok stabilitásának detektálására használják
#defineHIGH_FREQUENCY_RC_OSC_STABLE (ALVÁS &0x20)
//A kristályoszcillátor stabil állapotának detektálására használják
#defineXOSC_STABLE (ALVÁS &0x40)
//Szerezd meg az időzítő tick frekvencia értékét
#defineTICKSPD ((CLKCON & 0x38) >> 3)
//Állítsuk be a mester órajel frekvenciát
#defineSET_MAIN_CLOCK_SOURCE(forrás)
csinál{
ha(forrás) {
CLKCON |=0x40;
miközben(! HIGH_FREQUENCY_RC_OSC_STABLE);
ha(TICKSPD ==0){
CLKCON |=0x08;
}
ALVÁS |=0x04;
}
más{
ALVÁS &= ~0x04;
miközben(! XOSC_STABLE);
asm("NOP");
CLKCON &= ~0x47;
ALVÁS |=0x04;
}
}miközben (0)
//A paraméterforrás értéke a következő:
#defineKRISTÁLY 0x00 //Kristályoszcillátor
#defineRC 0x01 //RC oszcillátor
[url=] [/url]
[url=] [/url]
/***********************************************************
Időzítő 1
***********************************************************/
//Az 1-es időzítő lehetővé teszi, hogy a számlálás túlcsordulása megszakítson
#defineTIMER1_ENABLE_OVERFLOW_INT(val)
(TIMIF = (val)? TIMIF |0x40: TIMIF & ~0x40)
//Állítsuk be az overflow megszakítási zászlót az 1-es időzítőhöz
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))
//Az 1-es időzítő indul
#defineTIMER1_RUN(érték) (T1CTL = (érték) ? T1CTL|0x02 : T1CTL&~0x03)
//Állítsd be az időzítő óraosztását
#defineSET_TIMER_TICK(érték) do{ CLKCON = ((CLKCON & (~0x38)) | érték); } while(0)
//Az érték értéke a következő:
#defineTIMER1_TICK_32M 0x00 //32MHz
#defineTIMER1_TICK_16M 0x08 //16MHz, a rendszer visszaállításának alapértelmezett értéke
#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
//Állítsd be a TICK keresztezést az 1-es időzítőre
#defineSET_TIMER1_TICKDIV(érték)
csinál{
T1CTL &= ~0x0c;
T1CTL |= érték;
}miközben (0)
//ahol az érték:
#defineTIMER1_TICKDIV_1 0x00 //1 osztály
#defineTIMER1_TICKDIV_8 0x04 //8-utas frekvencia
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c
//Állítsd be az időzítő túlcsordulási időszakát
#defineSET_TIMER1_PERIOD(érték)
csinál{
T1CC0H = HIGH_BYTE(érték);
T1CC0L = LOW_BYTE(érték);
}miközben (0)
//Állítsd be az 1-es időzítő üzemmódját
#defineSET_TIMER1_MODE(mód)
csinál{
T1CTL = ((T1CTL & (~0x03)) | mód);
}miközben (0)
//A mód értéke a következő:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]
[url=] [/url]
/***********************************************************
Őrőr kutya
***********************************************************/
//Állítsd be a túlcsordulási időszakot a watchdog időzítőhöz
#defineWDT_SET_TIMEOUT_PERIOD(időkorlát)
csinál{ WDCTL &= ~0x03; WDCTL |= időkorlát; }miközben (0)
//A paraméter időtúllépésének értéke:
#defineSEC_1 0x00 //1 másodperc után
#defineM_SEC_250 0x01 //250 ms után
#defineM_SEC_15 0x02 //15 ms után
#defineM_SEC_2 0x03 //2 másodperc után
//Kutyaetési eljárások
#defineWDT_RESET() do {
WDCTL = (WDCTL & ~0xF0) |0xA0;
WDCTL = (WDCTL & ~0xF0) |0x50;
} miközben (0)
//Indítsd el/állítsd le a watchdog időzítőt
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]
[url=] [/url]
/***********************************************************
ADC
***********************************************************/
//Egyetlen ADC konfigurálása
#defineADC_SINGLE_CONVERSION(beállítások)
csinál{ ADCCON3 = beállítások; }miközben(0)
//A paraméterbeállítás a következő kombinációkból áll:
//Referenciafeszültség
#defineADC_REF_1_25_V 0x00 //Belső 1,25V referenciafeszültség
#defineADC_REF_P0_7 0x40 //Külső referenciafeszültség az AIN7 tűn
#defineADC_REF_AVDD 0x80 //AVDD_SOC Kitűzők
#defineADC_REF_P0_6_P0_7 0xC0 //AIN6-AIN7 Külső referencia feszültség differenciálbemenetekhez
//Mintavételi sebesség
#defineADC_8_BIT 0x00 //8. hely
#defineADC_10_BIT 0x10 //10. hely
#defineADC_12_BIT 0x20 //12. hely
#defineADC_14_BIT 0x30 //14. hely
//Lépj be a csatornába
#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 //Föld
#defineADC_TEMP_SENS 0x0E //Chipen belüli hőmérséklet-érzékelő
#defineADC_VDD_3 0x0F //vdd/3
ADC átalakítás befejeződött
#define ADC_SAMPLE_READY() (ADCCON1 és 0x80)
#endif
//启动ADC转化
#define ADC_START()
do { ADCCON1 |= 0x40; } míg (0)//Válaszd ki az ADC trigger módját manuálisan (azaz ADC_SAMPLE_READY)
#defineADC_STOP()
csinál{ ADCCON1 |=0x30; }miközben (0)[url=] [/url]
(2) Funkcionális modulréteg
[url=] [/url]
/***********************************************************
*Fájlnév: module.h
*Szerző: hustlzp
*Dátum: 2011. március 6.
*Verzió: 1.0
*Funkcióleírás: Funkcionális modul réteg fejlécfájl
*Funkciólista: void led_init()
Void timer1_init()
void uart0_init(üresség);
void Uart0SendString(aláíratlan karakter *s);
Float adc_start(üres)
void get_temperature(nem jelzett karakter *output, float temp);
void watchdog_init(üres);
*Módosított rekordok:
***********************************************************/
#ifndef MODULE_H
#defineMODULE_H
#include"hal.h"
/***********************************************************
LED
***********************************************************/
//Definiáld a LED tűket
#defineled1 P1_0
#defineled2 P1_1
#defineLED3 P1_2
#defineLED4 P1_3
//LED fény és kikapcsolás
#defineLED_OFF 1
#defineLED_ON 0
//LED inicializáció
Semmiled_init(Semmi);
/***********************************************************
timer1
***********************************************************/
//A túlcsordulási időszak értékének beállításához használták az időzítőhöz
#defineTIMER1_OVF_2SEC 0xF424 //2s
#defineTIMER1_OVF_1SEC 0x7A12 //1-es
#defineTIMER1_OVF_dot5SEC 0x3D09 //0,5s
//Az 1-es időzítő inicializálja
Semmi timer1_init(Semmi);
/***********************************************************
UART0
***********************************************************/
//UART0 inicializáció
Semmi uart0_init(Semmi);
//Soros port átviteli lánc
Semmi Uart0SendString(nem aláírtchar*s);
/***********************************************************
ADC-14
***********************************************************/
//Az ADC által szerzett adatok Celsius-fokú hőmérsékletre történő átalakítására használják
#defineADC_TO_CELSIUS(temp) (hőmérséklet * 0.06229 - 311.43)
//ADC átalakítás indítása
Floatadc_start(Semmi);
//Átalakítás
Semmi get_temperature(aláíratlanulchar*kimenet,Floattemp);
/***********************************************************
WatchDog
***********************************************************/
//Őrkutya inicializáció
Semmi watchdog_init(Semmi);
#endif
[url=] [/url]
[url=] [/url]
/***********************************************************
*Fájlnév: module.c
*Szerző: hustlzp
*Dátum: 2011/3/11
*Verzió: 1.0
*Funkcióleírás: Funkcionális modul réteg forrásfájl
*Funkciólista: (kihagyva)
*Módosított rekordok:
***********************************************************/
#include"module.h"
/***********************************************************
*Funkció neve: led_init
*Funkciófüggvény: LED inicializáció
*Belépési paraméterek: Nincs
*Exportparaméterek: Nincs
***********************************************************/
Semmiled_init(Semmi)
{
//Konfiguráld a P1.0, P1.1, P1.2 és P1.3 általános I/O portokat
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);
//Konfiguráld a P1.0, P1.1, P1.2 és P1.3 kimeneteket
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;
}
/***********************************************************
*Funkció neve: timer1_init
* Függvényfüggvény: Timer 1 inicializálás
*Belépési paraméterek: Nincs
*Exportparaméterek: Nincs
***********************************************************/
Semmitimer1_init(Semmi)
{
INT_GLOBAL_ENABLE(INT_ON); //Nyisd meg a globális megszakítást
INT_ENABLE(INUM_T1, INT_ON); //Megnyitó T1 megszakítás
TIMER1_ENABLE_OVERFLOW_INT(INT_ON); //Open T1 count overflow interrupt
SET_TIMER_TICK(TIMER1_TICK_4M); //Állítsd be az időzítő TICK-jét 4MHz-re
SET_TIMER1_PERIOD(TIMER1_OVF_2SEC); //Állítsd be a T1-es számlálási időszakot 2-esre.
SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128); //Állítsuk be az óra átfedését T1-re 128-ra
SET_TIMER1_MODE(TIMER1_MODE_MODULE); //Állítsuk be a T1 futási módját modulra
}
/***********************************************************
*Funkció neve: uart0_init
*Funkciófüggvény: Soros port UART0 inicializáció
*Belépési paraméterek: Nincs
*Exportparaméterek: Nincs
***********************************************************/
Semmiuart0_init(Semmi)
{
//Válassza ki az UART helyszínt
IO_PER_LOC_UART0_AT_PORT0_PIN2345();
//UART konfigurálása: Engedélyezett vétel, 115200 bps, egybites megállító bit, pariitás nélkül
UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);
//Nyisd ki a teljes megszakítást
INT_GLOBAL_ENABLE(INT_ON);
//Nyisd ki a 0-s soros portot a megszakítások fogadásához
INT_ENABLE(INUM_URX0, INT_ON);
}
/***********************************************************
*Funkció neve: Uart0SendString
* Függvényfüggvény: Timer 1 inicializálás
*Bejegyzési paraméter: nem jelzett karakter *s
Az a zsinór, amit küldeni akarsz
*Exportparaméterek: Nincs
***********************************************************/
SemmiUart0SendString(nem aláírtchar*s)
{
miközben(*s !=0)
UART0_SEND(*s++);
}
/***********************************************************
*Funkció neve: adc_start
*Funkciófüggvény: ADC átalakítás indítása
*Belépési paraméterek: Nincs
*Export paraméter: float
A táblagép hőmérsékleti értéke
***********************************************************/
Floatadc_start(Semmi)
{
Aláírás nélkülintTemp;
//A referenciafeszültség 1,25V, a mintavételi pontosság 14 bit, és az átalakító célpont a chipen belüli hőmérséklet-érzékelő
ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
ADC_STOP(); //Állítsd be az ADC átalakítási trigger módszert manuálisra
ADC_START(); //ADC átalakítás indítása
miközben(! ADC_SAMPLE_READY()); //Várj a átalakítás befejezésére
temp = ADCL >>2; //Mentés az átváltás hőmérsékleten
temp |= ((nem aláírtint) ADCH) <<6);
VisszatérésADC_TO_CELSIUS(ideiglenes időben); //Visszaadja a tényleges hőmérsékleti értéket az átalakítás után
}
/***********************************************************
*Funkció neve: get_temperature
*Függvényfüggvény: Feldolgozzuk a hőmérsékleti értéket, és tároljuk a karaktertömbben soros kimenethez
*Entry paraméter: alárendellen karakter *output
A konvertált hőmérséklet-érték tárolására használják
Float hőmérséklet
Celsius-fokus hőmérsékleti érték
*Exportparaméterek: Nincs
***********************************************************/
Semmiget_temperature(aláíratlanulchar*kimenet,Floattemp)
{
Kimenet[0] = (aláíratlanchar(temp) /10 + 48; //Tíz hely
Kimenet[1] = (aláíratlanchar(temp) %10 + 48; //Egyjegyű
Kimenet[2] ='.'; //Tizedespont
Kimenet[3] = (aláíratlanchar(temp*10) %10 + 48; //Tizedik
Kimenet[4] = (aláíratlanchar(temp*100) %10 + 48; //Percentilis
Kimenet[5] =''; //String endifierek
}
/***********************************************************
*Funkció neve: watchdog_init
*Funkciófüggvény: Figyelőkutya inicializálás
*Belépési paraméterek: Nincs
*Exportparaméterek: Nincs
***********************************************************/
Semmiwatchdog_init(Semmi)
{
WDT_SET_TIMEOUT_PERIOD(SEC_1); //Állítsd be az időkorlátot 1s-re
WDT_ENABLE(); //Indítsd el a felügyeleti kutyát
}
[url=] [/url]
(3) Alkalmazási réteg
[url=] [/url]
/*******************************************************************
Fájlnév: main.c
Szerző: hustlzp
Dátum: 2011/3/11
Verzió: 1.0
Funkcióleírás: Mesterprogram fájl
Funkciólista: (kihagyva)
Módosítási feljegyzés:
*******************************************************************/
#include
/********************************************************************
Megszakítási szolgáltatási eljárások
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektor=T1_VECTOR
__interrupt üresség T1_ISR(üresség)
{
EA=0; A kapu megszakítva van
led2 = LED_ON;
get_temperature(kimenet,adc_start()); A hőmérsékleti értéket karaktertömbként alakítsuk át, hogy kihozható legyen
Uart0SendString(kimenet); Kimeneti hőmérséklet érték
Uart0SendString("°C");
led2
/* 串口接收中断子程序
-------------------------------------------------------*/
#pragma vektor=URX0_VECTOR
__interrupt üresség RE_ISR(üresség)
{
EA=0;
led3 = LED_ON;
receive = U0DBUF;
if(type==1) // type=1, ami azt jelzi, hogy a kapott karakter az időzítő túlcsordulási időszakának beállításához szolgál
{
type=0;
Kapcsoló (fogadás)
{
case '0': // Az időzítő túlcsordulási ideje 0,5s
{
SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
szünet;
}
case '1': // Az időzítő túlcsordulási ideje 1s
{
SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
szünet;
}
eset '2': // Az időzítő túlcsordulási ideje 2s
{
SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
szünet;
}
}
}
else-e if(type==2) // type=2, ami azt jelzi, hogy a kapott karaktereket alvó vezérlésre használják
{
type=0;
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
Kapcsoló (fogadás)
{
case '1': // Kapcsolódási mód PM1
{
SET_POWER_MODE(1);
szünet;
}
case '2': // Kapcsolódási mód PM2
{
SET_POWER_MODE(2);
szünet;
}
case '3': //Lépj be PM3 teljesítmény módot
{
SET_POWER_MODE(3);
szünet;
}
}
}
elseként if(type==0) // type=0, ami azt jelzi, hogy a kapott karakter a vezérlőparancs típusa: @ vagy $
{
if(receive=='@')
{
type=1; '@' jelzése szerint a következő karakter a túlcsordulási időszak beállításához
}
else if(receive=='$')
{
type=2; '$' jelenik meg, ami azt jelzi, hogy a következő karaktert használják a rendszer alvó vezérlésére
}
}
led3 = LED_OFF;
EA=1;
}
=LED_OFF;
TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR); Töröld a megszakító táblát
EA=1; Nyílt megszakítás
}
/* 主函数
-------------------------------------------------------*/
void main(void)
{
SET_MAIN_CLOCK_SOURCE(KRISTÁLY); Állítsd be a rendszer órajelét 32MHz-es kristályoszcillátorra
led_init(); LED inicializáció
uart0_init(); Soros port UART0 inicializáció
timer1_init(); Az 1-es időzítő inicializálja
watchdog_init(); Őrkutya inicializáció
while(1)
{
WDT_RESET(); Folyamatosan etetni a kutyát
}
}/********************************************************************
Fő műsor
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
alárendellen karakter kimenet[6]={0}; A hőmérsékleti adatokat tárolják a soros kimenet megkönnyítése érdekében
aláíratlan char receive; Tárolja a beérkezett karaktereket
névtelen karakter típus=0; A befogadott karakter típuszászlója 0/1/2-re van állítva."module.h"[url=] [/url]
5. TesztelésÓ~ A kód végre beillesztett, nagyon kimerítő, teszteljük ezt a kis rendszert:
(1) Időzített mintavételezés
Nyissuk ki a soros portot, indítsuk el az IAR hibakeresést, és látjuk, hogy led1 be van kapcsolva, a soros port eszköz hőmérsékleti értéke folyamatosan generálódik, és a mintavételi intervallum 2s lesz:
(2) Mintavételi intervallum szabályozás
Írd be a "@1"-et a soros port eszközbe, majd teszteld a mintavételi intervallumot, és találd meg, hogy az 1-essé vált; Adja be a "@0"-t, és a mintavételi intervallum 0,5 másodpercre változik.
(3) Alváskontroll
Írd be a "$1" jelzést a soros port eszközbe, és látod, hogy minden LED kikapcsolt, és a hőmérsékleti mintavétel megállt:
Tesztelés után a rendszer normálisan és stabilan működik, és lényegében megfelel a követelményeknek.
Olyan diákok, akiknek forráskódra van szükségükKattints ide a letöltéshez
6. ÖsszegzésEz a tanulmány egy kissé átfogó kísérletet vesz példaként, hogy megmutassa, hogyan lehet integrálni CC2430 chipen alapuló erőforrásokat egy viszonylag szabványosított kis rendszer megírásához. Néhány nap múlva időt szánok arra, hogy írjak egy egyszerű használati útmutatót a hal.h-hoz, hogy én és mindenki könnyen tudnánk használni a CC2430-at.
Ezután befejezem a CC2430 chipen található erőforrások kutatását, és elkötelezem magam a TI Z-Stack protokoll stack megtanulásának~
A sorozat blogbejegyzése egyelőre véget ért, de Zigbee útja folytatódik. A jövő látjai ismeretlenek, de hiszem, hogy az író mindenkivel együtt legyőzi az akadályokat, megkóstolja a hullámvölgyeket, és eredmények lesznek.
Maradjatok velünk: "Csatlakozz a TI Z-Stackhez" blogbejegyzések!