Kovo 3 d. parašęs "Zigbee Journey (9)", autorius iš pradžių planavo nedelsiant pradėti rašyti nedidelį eksperimentą apie "temperatūros stebėjimo sistemą" kaip išsklaidytų žinių santrauką. Tačiau taip pat supratau, kad nors kiekvienas iš ankstesnių nedidelių eksperimentų buvo išsamiai aprašytas, normatyvinis ir struktūrinis jo kodo pobūdis gali būti laikomas nepakeliamu. Kadangi tai yra santrauka, turėtume daryti pažangą originaliu pagrindu, o ne mechaniškai sujungti ankstesnius mažus žinių taškus. Todėl sustabdžiau savo pradinį planą, skyriau laiko išmokti bendrųjų įterptųjų kūrimo metodų ir parašiau du rašiniusĮterptojo C51 programavimo specifikacija" ir "Įdėtosios projekto kodo struktūros hierarchija》。 Šis žurnalas yra ne tik pirmosios Zigbee kelionės santrauka, bet ir apima autoriaus mokymosi patirtį pastarosiomis dienomis, tikintis, kad bus naudinga Zigbee pradedantiesiems.
Visas tekstas suskirstytas pagal pagrindinį programinės įrangos kūrimo procesą: reikalavimų analizė, metmenų projektavimas, detalusis projektavimas, kodavimo diegimas ir testavimas.
1. Paklausos analizėPo diskusijos tarp "kliento" ir "kūrėjo" buvo nustatytas toks sistemos funkcijos aprašymas:
… Esamą kambario temperatūrą renka CC2430 mazgai, o jos temperatūros vertes galima stebėti per kompiuterį
… Pats CC2430 mazgas turi turėti tam tikrą stabilumo laipsnį ir gali automatiškai grįžti į normalią būseną
… Mazgo atrankos intervalą ir galios valdymą galima valdyti kompiuteriu
2. Kontūro dizainasPagal aukščiau pateiktą reikalavimų analizę sistemą galime suskirstyti į du modulius:CC2430 mazgasirKompiuteris。
[CC2430 mazgas]
… Išorinius parametrus galima reguliariai rinkti ir siųsti į kompiuterį
… Automatinis atstatymas, kai mašina išjungta
… Komandos iš kompiuterio gali būti atitinkamai priimamos ir apdorojamos: pakeiskite mėginio intervalą / energijos valdymą
[PC]
… C įrenginys priima ir rodo duomenis per nuosekliojo prievado įrankį
… Instrukcijos gali būti siunčiamos į mikrovaldiklį per nuosekliojo prievado įrankį, kad būtų galima valdyti jo mėginių ėmimo greitį ir galios valdymą
3. Detalusis projektas(1) Kodo struktūra
Šios sistemos kodo struktūros sluoksniavimas iš tikrųjų buvo aprašytas esė "Įdėtosios projekto kodo struktūros hierarchija", o kopija yra tokia:
(1) Aparatūros abstrakcijos sluoksnis
[ioCC2430.h] (Sistema įtraukta):Visi CC2430 SFR ir pertraukimo vektoriai yra apibrėžti
[hal.h] Apima bendrus tipų apibrėžimus, bendras priskyrimo makrokomandas ir bendrą CC2430 lusto išteklių konfigūraciją (I/O, nuoseklusis ryšys, ADC, laikmatis, energijos valdymas ir kt.)
(2) Funkcinis modulio sluoksnis
[modulis.h] apibrėžia lusto išteklius (laikmačius, I/O), ne lusto išplėtimo modulius (LED) ir susijusių funkcijų deklaracijas
[modulis.cĮgyvendinkite kiekvieno modulio (LED) inicijavimą.
(3) Taikymo lygmuo
[main.cŽiūrėkite hal.h, ioCC2430.h ir module.h, kad pasiektumėte konkrečius taikymo reikalavimus, pvz., temperatūros nustatymą, ryšį su kompiuteriu ir išjungimą bei atstatymą
(2) Kiekvieno modulio įgyvendinimo metodai
Pagal modulius, suskirstytus pagal kontūro dizainą, vidinę sistemą galima suskirstyti į du pagrindinius modulius:CC2430 mazgasirKompiuteris。
Kadangi kompiuteryje yra nuosekliojo prievado ryšio įrankiai, jo funkcijos gali atitikti reikalavimus, todėl mums nereikia daryti šios kompiuterio dalies ir nereikia jos analizuoti. Pakalbėkime apie CC2430 skyrių žemiau
Kiekvienos taško subfunkcijos įgyvendinimo būdas:
… Naudokite laikmačio skaičiavimo perpildymo pertrauką, kad suaktyvintumėte laiko atranką
… UART0 režimas su nuosekliuoju prievadu perduoda temperatūros duomenis į kompiuterį
… CC2430 įmontuota stebėjimo grandinė naudojama automatinio sistemos atstatymo funkcijai įgyvendinti
… Nuoseklusis prievadas naudojamas pertraukimams priimti, kad būtų galima užfiksuoti ir reaguoti į valdymo komandas iš kompiuterio
1) Jei gauta@Simbolis yra atrankos intervalo valdymo komanda, po kurios seka skaičius, nurodantis atrankos intervalą: 0-0,5 s, 1-1 s, 2-2 s
如:@0,表示每隔0.5秒采样一次。
2) Jei gauta$ Simbolis yra miego valdymo komanda, po kurios eina skaičius, nurodantis maitinimo režimą
Pavyzdžiui: 3 USD, o tai reiškia, kad sistema turi būti įjungta į 3 maitinimo režimą.
(3) Programos schema
- Pagrindinė programos schema
- 1 laikmačio perpildymo pertraukimo programos schema
- Nuosekliojo prievado priėmimo nutraukimo procedūros schema
4. Kodavimo įgyvendinimas(1) Aparatūros abstrakcijos sluoksnis
Aparatūros abstrakcijos sluoksnis apima ioCC2430.h ir hal.h. Kadangi ankstesnė sistema ateina su juo, ji nebus įtraukta į sąrašą.
Toliau pateikiamas viso hal.h turinio sąrašas (kadangi šis failas yra per ilgas ir atrodo nepatogus, parodysiu jį moduliais):
- galva
- Įvesties / išvesties prievadai
- Nutraukta
- Nuoseklusis prievadas
- Maitinimo ir laikrodžio valdymas
- Laikmatis
- Sargybinis šuo
- ADC
[url=]
[/url]
/***********************************************************
*Failo pavadinimas: hal.h
*Autorius: hustlzp
*Data: 2011 m. kovo 8 d.
*Leidimas: 1.1
*Funkcijos aprašymas: Aparatūros abstrakcijos sluoksnis
*Modifikuoti įrašai:
***********************************************************/
#ifndef HAL_H
#defineHAL_H
#include
/***********************************************************
Bendrieji tipų apibrėžimai
***********************************************************/
typedef nepasirašytasanglis BAITAS;
typedef nepasirašytasint ŽODIS;
typedef nepasirašytasilgas DWORD;
/***********************************************************
Dažniausiai naudojami makrokomandų apibrėžimai
***********************************************************/
//8 vietos aukštesnės
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))
//8 vietomis žemiau
#defineLOW_BYTE(a) ((BYTE) ((WORD)(a)))
//Priskyrimas
#defineSET_WORD(regH, regL, žodis)
daryti{
(regH) = HIGH_BYTE (žodis);
(regL)=LOW_BYTE(žodis);
}Nors(0)
[url=] [/url]
[url=] [/url]
/***********************************************************
Įvesties / išvesties prievadai
***********************************************************/
/*Konfigūruokite įvesties / išvesties prievado kryptį
-----------------------------------------*/
#defineIO_DIR_PORT_PIN(prievadas, kaištis, režisierius)
daryti{
jei(dir == IO_OUT)
P##port##DIR |= (0x01<< (smeigtukas));
kitaip
P##port##DIR &= ~(0x01<< (smeigtukas));
}Nors(0)
//Parametro dir vertė yra:
#defineIO_IN 0
#define1 IO_OUT
/*Sukonfigūruokite įvesties / išvesties prievado įvesties režimą
-----------------------------------------*/
#defineIO_IMODE_PORT_PIN (prievadas, kaištis, imode)
daryti{
jei(imode == IO_IMODE_TRI)
P##port##INP |= (0x01<< (smeigtukas));
kitaip
P##port##INP &= ~(0x01<< (smeigtukas));
}Nors (0)
#define IO_PUD_PORT (uostas, pud)
do {
if (pud == IO_PULLDOWN)
P2INP |= (0x01 << (prievadas+5));
kitaip
P2INP &= ~(0x01 << (prievadas+5));
}, o (0)
Parametro PUD vertė yra:
#define IO_PULLUP 0 // Traukti aukštyn
#define IO_PULLDOWN 1 // Patraukite žemyn
/*配置I/O口的功能
-----------------------------------------*/
#define IO_FUNC_PORT_PIN (prievadas, kaištis, func)
do {
if((prievadas == 2) && (kaištis == 3)){
if (func) {
P2SEL |= 0x02;
} else {
P2SEL &= ~0x02;
}
}
else if((port == 2) && (pin == 4)){
if (func) {
P2SEL |= 0x04;
} else {
P2SEL &= ~0x04;
}
}
else{
if (func) {
P##port##SEL |= (0x01<<(pin));
} else {
P##port##SEL &= ~(0x01<<(pin));
}
}
}, o (0)
Parametro func vertė yra:
#define IO_FUNC_GIO 0 // Bendrasis I/O
#define IO_FUNC_PERIPH 1 // Periferinis įvestis / išvestis
Sukonfigūruokite periferinio įvesties / išvesties vietą
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; }, o (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; }, o (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN34() do { PERCFG = (PERCFG&~0x20)|0x00; }, o (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN67() do { PERCFG = (PERCFG&~0x20)|0x20; }, o (0)
#define IO_PER_LOC_TIMER4_AT_PORT1_PIN01() do { PERCFG = (PERCFG&~0x10)|0x00; }, o (0)
#define IO_PER_LOC_TIMER4_AT_PORT2_PIN03() do { PERCFG = (PERCFG&~0x10)|0x10; }, o (0)
#define IO_PER_LOC_SPI1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x08)|0x00; }, o (0)
#define IO_PER_LOC_SPI1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x08)|0x08; }, o (0)
#define IO_PER_LOC_SPI0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x00; }, o (0)
#define IO_PER_LOC_SPI0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x04; }, o (0)
#define IO_PER_LOC_UART1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x02)|0x00; }, o (0)
#define IO_PER_LOC_UART1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x02)|0x02; }, o (0)
#define IO_PER_LOC_UART0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x00; }, o (0)
#define IO_PER_LOC_UART0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x01; }, o (0)
//Parametro imode vertė yra:
#defineIO_IMODE_PUD 0 //Patraukite aukštyn / patraukite žemyn
#define1 IO_IMODE_TRI //Trys valstijos[url=] [/url]
[url=] [/url]
/***********************************************************
Nutraukta
***********************************************************/
//Įjungimo/išjungimo pertraukimams
#define1 INT_ON
#defineINT_OFF 0
//Naudojamas pertraukimo vėliavėlėms įdėti / išvalyti
#defineINT_SET 1
#defineINT_CLR 0
//Visuotiniai pertraukimo parametrai
#defineINT_GLOBAL_ENABLE(įjungta) EA=(!! įjungta)
//Apibrėžkite pertrauką
#defineINUM_RFERR 0
#define1 INUM_ADC
#define2 INUM_URX0
#defineINUM_URX1 3
#defineINUM_ENC 4
#defineINUM_ST 5
#defineINUM_P2INT 6
#define7 INUM_UTX0
#define8 INUM_DMA
#define9 INUM_T1
#defineINUM_T2 10
#defineINUM_T3 11
#defineINUM_T4 12
#defineINUM_P0INT 13
#defineINUM_UTX1 14
#defineINUM_P1INT 15
#defineINUM_RF 16
#defineINUM_WDT 17
/*Leidžiami pertraukimai
-----------------------------------------*/
#defineINT_ENABLE(inum, įjungta)
daryti{
jei (inum==INUM_RFERR) { RFERRIE = įjungta; }
kitaip jei(inum==INUM_ADC) { ADCIE = įjungta; }
kitaip jei(inum==INUM_URX0) { URX0IE = įjungta; }
kitaip jei(inum==INUM_URX1) { URX1IE = įjungta; }
kitaip jei(inum==INUM_ENC) { ENCIE = įjungta; }
kitaip jei(inum==INUM_ST) { STIE = įjungta; }
kitaip jei(inum==INUM_P2INT) { (įjungta) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
kitaip jei(inum==INUM_UTX0) { (įjungta) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
kitaip jei(inum==INUM_DMA) { DMAIE = įjungta; }
kitaip jei(inum==INUM_T1) { T1IE = įjungta; }
kitaip jei(inum==INUM_T2) { T2IE = įjungta; }
kitaip jei(inum==INUM_T3) { T3IE = įjungta; }
kitaip jei(inum==INUM_T4) { T4IE = įjungta; }
kitaip jei(inum==INUM_P0INT) { P0IE = įjungta; }
kitaip jei(inum==INUM_UTX1) { (įjungta) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
kitaip jei(inum==INUM_P1INT) { (įjungta) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
kitaip jei(inum==INUM_RF) { (įjungta) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
kitaip jei(inum==INUM_WDT) { (įjungta) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
}Nors (0)
/*Nustatykite nutraukimo prioritetą
-----------------------------------------*/
#defineINT_PRIORITY(grupė, pri)
daryti{
jei(pri ==0) { IP0 &= ~grupė; IP1 &= ~grupė; }
jei(pri ==1) { IP0 |= grupė; IP1 &= ~grupė; }
jei(pri ==2) { IP0 &= ~grupė; IP1 |= grupė; }
jei(pri ==3) { IP0 |= grupė; IP1 |= grupė; }
}Nors (0)
//Parametro pri vertė yra: 0/1/2/3 (aukščiausias prioritetas)
//Parametrų grupės vertė yra:
#defineRFERR_RF_DMA 0x01//IP0 grupė
#defineADC_P2INT_T1 0x02//IP1 grupė
#defineURX0_UTX0_T2 0x04//IP2 grupė
#defineURX1_UTX1_T3 0x08//IP3 grupė
#defineENC_P1INT_T4 0x10//IP4 grupė
#defineST_WDT_P0INT 0x20//IP5 grupė
/*Gaukite pertraukimo vėliavėlę
-----------------------------------------*/
#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) ? P2JEIGU:
(inum==INUM_UTX0) ? UTX0JEIGU:
(inum==INUM_DMA) ? DMAIF :
(inum==INUM_T1) ? T1JEIGU:
(inum==INUM_T2) ? T2JEIGU:
(inum==INUM_T3) ? T3JEIGU:
(inum==INUM_T4) ? T4JEIGU:
(inum==INUM_P0INT) ? P0JEIGU:
(inum==INUM_UTX1) ? UTX1JEIGU:
(inum==INUM_P1INT) ? P1JEIGU:
(inum==INUM_RF) ? S1CON &= ~0x03 :
(inum==INUM_WDT) ? WDTIF :
0
)
/*Pertraukimo vėliavėlės nustatymas
-----------------------------------------*/
#defineINT_SETFLAG(inum, f)
daryti{
jei (inum==INUM_RFERR) { RFERRIF= f; }
kitaip jei(inum==INUM_ADC) { ADCIF = f; }
kitaip jei(inum==INUM_URX0) { URX0IF = f; }
kitaip jei(inum==INUM_URX1) { URX1IF = f; }
kitaip jei(inum==INUM_ENC) { ENCIF_1 = ENCIF_0 = f; }
kitaip jei(inum==INUM_ST) { STIF = f; }
kitaip jei(inum==INUM_P2INT) { P2IF = f; }
kitaip jei(inum==INUM_UTX0) { UTX0IF= f; }
kitaip jei(inum==INUM_DMA) { DMAIF = f; }
kitaip jei(inum==INUM_T1) { T1IF = f; }
kitaip jei(inum==INUM_T2) { T2IF = f; }
kitaip jei(inum==INUM_T3) { T3IF = f; }
kitaip jei(inum==INUM_T4) { T4IF = f; }
kitaip jei(inum==INUM_P0INT) { P0IF = f; }
kitaip jei(inum==INUM_UTX1) { UTX1IF= f; }
kitaip jei(inum==INUM_P1INT) { P1IF = f; }
kitaip jei(inum==INUM_RF) { (f) ? (S1CON |=0x03) : (S1CON &= ~0x03); }
kitaip jei(inum==INUM_WDT) { WDTIF = f; }
}Nors (0)
[url=] [/url]
[url=] [/url]
/***********************************************************
Nuoseklusis prievadas
***********************************************************/
//BAUD_E vertė, atitinkanti skirtingą perdavimo spartą
#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 vertė, atitinkanti skirtingą perdavimo spartą
#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)
/*Nuosekliojo prievado konfigūracija UART režimu
-----------------------------------------*/
#defineUART_SETUP(uart, receiveEnable, baudRate, options)
daryti{
jei((uart) ==0){
jei(PERCFG &0x01){
P1SEL |=0x30;
}kitaip{
P0SEL |=0x0C;
}
}
kitaip{
jei(PERCFG &0x02){
P1SEL |=0xC0;
}kitaip{
P0SEL |=0x30;
}
}
U##uart##GCR = BAUD_E((baudų sparta),CLKSPD);
U##uart##BAUD = BAUD_M(baudų sparta);
U##uart##CSR |=0x80;
U##uart##CSR |= receiveEnable;
U##uart##UCR |= ((parinktys) |0x80);
}Nors(0)
//Parametro reikšmė receiveEnable:
#defineUART_RECEIVE_ENABLE 0x40 //Leidimo gavimas
#defineUART_RECEIVE_DISABLE 0x00
//Parametrų parinkčių vertė:
#defineFLOW_CONTROL_ENABLE 0x40 //Srauto valdymas
#defineFLOW_CONTROL_DISABLE 0x00
#defineEVEN_PARITY 0x20 //Retkarčiais atliekamas patikrinimas
#defineODD_PARITY 0x00 //Keistas patvirtinimas
#defineNINE_BIT_TRANSFER 0x10 //9 baitų perkėlimas
#defineEIGHT_BIT_TRANSFER 0x00 //8 baitų perkėlimas
#definePARITY_ENABLE 0x08 //Pariteto patikros įgalinimas
#definePARITY_DISABLE 0x00
#defineTWO_STOP_BITS 0x04 //2 padėčių sustabdymo padėtis
#defineONE_STOP_BITS 0x00 //1 sustabdymo padėtis
#defineHIGH_STOP 0x02 //Sustabdymo lygis yra aukštas
#defineLOW_STOP 0x00 //Sustabdymo padėtis žema
#defineHIGH_START 0x01 //Pradinis bitų lygis yra aukštas
#defineLOW_START 0x00 //Pradinis bitų lygis žemas
//Nuoseklusis prievadas siunčia simbolius
#defineUART_SEND(uart,duomenys)
daryti{
Nors(U##uart##CSR &0x01);
U##uart##DBUF = duomenys;
}Nors (0)
#defineUART0_SEND(duomenys) UART_SEND(0,duomenys)
#defineUART1_SEND(duomenys) UART_SEND(1,duomenys)
//Nuoseklusis prievadas priima simbolius
#defineUART_RECEIVE(uart,duomenys)
daryti{
Nors(! (U##uart##CSR&0x04));
data=U##uart##DBUF;
}Nors(0)
#defineUART0_RECEIVE(duomenys) UART_RECEIVE(0,duomenys)
#defineUART1_RECEIVE(duomenys) UART_RECEIVE(1,duomenys)
[url=] [/url]
[url=] [/url]
/***********************************************************
Maitinimo ir laikrodžio valdymas
***********************************************************/
//Gaukite laikrodžio kryžminį
#defineCLKSPD (CLKCON ir 0x07)
//Maitinimo režimo nustatymas
#defineSET_POWER_MODE (režimas)
daryti{
jei(režimas ==0) { MIEGAS &= ~0x03; }
kitaip jei(režimas ==3) { MIEGAS |=0x03; }
kitaip{ MIEGAS &= ~0x03; SLEEP |= režimas; }
PCON |=0x01;
asm("NOP");
}Nors (0)
//Parametrų režimas nustatomas į šias reikšmes:
#definePOWER_MODE_0 0x00
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03
//Naudojamas aukšto dažnio RC osciliatorių stabilumui aptikti
#defineHIGH_FREQUENCY_RC_OSC_STABLE (MIEGAS & 0x20)
//Naudojamas stabiliai kristalinio osciliatoriaus būklei nustatyti
#defineXOSC_STABLE (MIEGAS & 0x40)
//Gaukite laikmačio varnelės dažnio reikšmę
#defineTICKSPD ((CLKCON & 0x38) >> 3)
//Nustatykite pagrindinį laikrodžio dažnį
#defineSET_MAIN_CLOCK_SOURCE(šaltinis)
daryti{
jei(šaltinis) {
CLKCON |=0x40;
Nors(! HIGH_FREQUENCY_RC_OSC_STABLE);
jei(TICKSPD ==0){
CLKCON |=0x08;
}
MIEGO REŽIMAS |=0x04;
}
kitaip{
MIEGAS &= ~0x04;
Nors(! XOSC_STABLE);
asm("NOP");
CLKCON &= ~0x47;
MIEGO REŽIMAS |=0x04;
}
}Nors (0)
//Parametro šaltinio reikšmė yra:
#defineKRIŠTOLO 0x00 //Kristalinis osciliatorius
#defineRC 0x01 //RC osciliatorius
[url=] [/url]
[url=] [/url]
/***********************************************************
Laikmatis 1
***********************************************************/
//1 laikmatis leidžia nutraukti skaičiavimo perpildymą
#defineTIMER1_ENABLE_OVERFLOW_INT(val)
(TIMIF = (val) ? TIMIF |0x40: TIMIF & ~0x40)
//Nustatykite 1 laikmačio perpildymo pertraukimo vėliavėlę
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))
//1 laikmatis paleidžiamas
#defineTIMER1_RUN(reikšmė) (T1CTL = (reikšmė) ? T1CTL|0x02 : T1CTL&~0x03)
//Laikmačio laikrodžio padalijimo nustatymas
#defineSET_TIMER_TICK(value) do{ CLKCON = ((CLKCON & (~0x38)) | value); } kol(0)
//Vertės vertė yra:
#defineTIMER1_TICK_32M 0x00 //32 MHz
#defineTIMER1_TICK_16M 0x08 //16 MHz, numatytoji sistemos nustatymo iš naujo vertė
#defineTIMER1_TICK_8M 0x10 //8MHz
#defineTIMER1_TICK_4M 0x18 //4MHz
#defineTIMER1_TICK_2M 0x20 //2MHz
#defineTIMER1_TICK_1M 0x28 //1MHz
#defineTIMER1_TICK_500k 0x30 //500 kHz
#defineTIMER1_TICK_250k 0x38 //250 kHz
//Nustatykite TICK kryžminį laikmatį 1
#defineSET_TIMER1_TICKDIV(reikšmė)
daryti{
T1CTL &= ~0x0c;
T1CTL |= reikšmė;
}Nors (0)
//kur vertė yra:
#defineTIMER1_TICKDIV_1 0x00 //1 skyrius
#defineTIMER1_TICKDIV_8 0x04 //8 krypčių dažnis
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c
//Laikmačio perpildymo laikotarpio nustatymas
#defineSET_TIMER1_PERIOD(reikšmė)
daryti{
T1CC0H = HIGH_BYTE(reikšmė);
T1CC0L = LOW_BYTE(vertė);
}Nors (0)
//Nustatykite 1 laikmačio darbo režimą
#defineSET_TIMER1_MODE(režimas)
daryti{
T1CTL = ((T1CTL & (~0x03)) | režimas);
}Nors (0)
//Režimo vertė yra:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]
[url=] [/url]
/***********************************************************
Sargybinis šuo
***********************************************************/
//Nustatykite sargybos laikmačio perpildymo laikotarpį
#defineWDT_SET_TIMEOUT_PERIOD(skirtasis laikas)
daryti{ WDCTL &= ~0x03; WDCTL |= skirtasis laikas; }Nors (0)
//Parametro skirtojo laiko reikšmė yra:
#defineSEC_1 0x00 //po 1 sekundės
#defineM_SEC_250 0x01 //po 250 ms
#defineM_SEC_15 0x02 //po 15 ms
#defineM_SEC_2 0x03 //po 2 ms
//Šunų šėrimo procedūros
#defineWDT_RESET() do {
WDCTL = (WDCTL & ~0xF0) |0xA0;
WDCTL = (WDCTL & ~0xF0) |0x50;
} Nors (0)
//Paleiskite / sustabdykite sargybos laikmatį
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]
[url=] [/url]
/***********************************************************
ADC
***********************************************************/
//Vieno ADC konfigūravimas
#defineADC_SINGLE_CONVERSION(nustatymai)
daryti{ ADCCON3 = nustatymai; }Nors(0)
//Parametrų nustatymą sudaro šie deriniai:
//Etaloninė įtampa
#defineADC_REF_1_25_V 0x00 //Vidinė 1.25 V etaloninė įtampa
#defineADC_REF_P0_7 0x40 //Išorinė etaloninė įtampa ant AIN7 kaiščio
#defineADC_REF_AVDD 0x80 //AVDD_SOC smeigtukai
#defineADC_REF_P0_6_P0_7 0xC0 //AIN6-AIN7 Išorinė etaloninė įtampa diferencialiniams įėjimams
//Mėginių ėmimo dažnis
#defineADC_8_BIT 0x00 //8 vieta
#defineADC_10_BIT 0x10 //10 vieta
#defineADC_12_BIT 0x20 //12 vieta
#defineADC_14_BIT 0x30 //14 vieta
//Įveskite kanalą
#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 //Žemė
#defineADC_TEMP_SENS 0x0E //Lusto temperatūros jutiklis
#defineADC_VDD_3 0x0F //VDD/3
ADC konvertavimas baigtas
#define ADC_SAMPLE_READY() (ADCCON1 ir 0x80)
#endif
//启动ADC转化
#define ADC_START()
do { ADCCON1 |= 0x40; }, o (0)//Pasirinkite ADC paleidimo režimą kaip rankinį (ty ADC_SAMPLE_READY)
#defineADC_STOP()
daryti{ ADCCON1 |=0x30; }Nors (0)[url=] [/url]
(2) Funkcinis modulio sluoksnis
[url=] [/url]
/***********************************************************
*Failo pavadinimas: module.h
*Autorius: hustlzp
*Data: 2011 m. kovo 6 d.
*Versija: 1.0
*Funkcijos aprašymas: funkcinio modulio sluoksnio antraštės failas
*Funkcijų sąrašas: void led_init()
Void timer1_init()
negaliojantis uart0_init (negaliojantis);
void Uart0SendString(nepasirašytas simbolis *s);
plūduriuojantis adc_start(tuščias)
void get_temperature(nepasirašytas simbolis *output,float temp);
negaliojantis watchdog_init (negaliojantis);
*Modifikuoti įrašai:
***********************************************************/
#ifndef MODULE_H
#defineMODULE_H
#include"hal.h"
/***********************************************************
Šviesos diodas
***********************************************************/
//Apibrėžkite LED kaiščius
#defineLED1 P1_0
#defineLED2 P1_1
#defineLED3 P1_2
#defineLED4 P1_3
//LED lemputė ir išjungta
#defineLED_OFF 1
#defineLED_ON 0
//LED inicijavimas
tuščialed_init (tuščia);
/***********************************************************
laikmatis1
***********************************************************/
//Naudojamas laikmačio perpildymo laikotarpio vertei nustatyti
#defineTIMER1_OVF_2SEC 0xF424 //2s
#defineTIMER1_OVF_1SEC 0x7A12 //1s
#defineTIMER1_OVF_dot5SEC 0x3D09 //0,5 s
//1 laikmatis inicijuojamas
tuščia timer1_init(tuščia);
/***********************************************************
UART0
***********************************************************/
//UART0 inicijavimas
tuščia uart0_init(tuščia);
//Nuosekliojo prievado perdavimo eilutė
tuščia Uart0SendString(nepasirašytasanglis*s);
/***********************************************************
ADC-14
***********************************************************/
//Naudojamas ADC gautiems duomenims konvertuoti į Celsijaus temperatūrą
#defineADC_TO_CELSIUS (temp) (temp * 0,06229 - 311,43)
//Inicijuoti ADC konvertavimą
plūdėadc_start(tuščia);
//Konversija
tuščia get_temperature(nepasirašytasanglis*išvestis,plūdėtemp);
/***********************************************************
Sargybinis šuo
***********************************************************/
//Stebėjimo šuns inicijavimas
tuščia watchdog_init (tuščia);
#endif
[url=] [/url]
[url=] [/url]
/***********************************************************
*Failo pavadinimas: module.c
*Autorius: hustlzp
*Data: 2011/3/11
*Versija: 1.0
*Funkcijos aprašymas: funkcinio modulio sluoksnio šaltinio failas
*Funkcijų sąrašas: (praleista)
*Modifikuoti įrašai:
***********************************************************/
#include"modulis.h"
/***********************************************************
*Funkcijos pavadinimas: led_init
* Funkcijos funkcija: LED inicijavimas
*Įėjimo parametrai: Nėra
*Eksporto parametrai: Nėra
***********************************************************/
tuščialed_init (tuščia)
{
//Konfigūruokite P1.0, P1.1, P1.2 ir P1.3 kaip bendruosius įvesties / išvesties prievadus
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);
//Konfigūruokite P1.0, P1.1, P1.2 ir P1.3 kaip išėjimus
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;
}
/***********************************************************
*Funkcijos pavadinimas: timer1_init
* Funkcijos funkcija: 1 laikmačio inicijavimas
*Įėjimo parametrai: Nėra
*Eksporto parametrai: Nėra
***********************************************************/
tuščiatimer1_init(tuščia)
{
INT_GLOBAL_ENABLE (INT_ON); //Atidarykite visuotinį pertraukimą
INT_ENABLE (INUM_T1, INT_ON); //Atidaryti T1 pertraukti
TIMER1_ENABLE_OVERFLOW_INT (INT_ON); //Atidaryti T1 skaičiavimo perpildymo pertraukimą
SET_TIMER_TICK (TIMER1_TICK_4M); //Nustatykite laikmatį TICK į 4 MHz
SET_TIMER1_PERIOD straipsnio TIMER1_OVF_2SEC dalis; //Nustatykite skaičiavimo laikotarpį nuo T1 iki 2s
SET_TIMER1_TICKDIV (TIMER1_TICKDIV_128); //Nustatykite T1 laikrodžio kryžminį rodiklį į 128
SET_TIMER1_MODE straipsnio TIMER1_MODE_MODULE dalis; //Nustatykite T1 veikimo režimą į modulį
}
/***********************************************************
*Funkcijos pavadinimas: uart0_init
*Funkcijos funkcija: nuosekliojo prievado UART0 inicijavimas
*Įėjimo parametrai: Nėra
*Eksporto parametrai: Nėra
***********************************************************/
tuščiauart0_init(tuščia)
{
//Pasirinkite UART vietą
IO_PER_LOC_UART0_AT_PORT0_PIN2345 ();
//Konfigūruoti UART: Gauti leidžiama, 115200 bps, vieno bito stabdymo bitas, nėra pariteto
UART_SETUP (0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);
//Atidaryti bendrą pertrauką
INT_GLOBAL_ENABLE (INT_ON);
//Atidarykite nuoseklųjį prievadą 0, kad gautumėte pertraukimus
INT_ENABLE (INUM_URX0, INT_ON);
}
/***********************************************************
*Funkcijos pavadinimas: Uart0SendString
* Funkcijos funkcija: 1 laikmačio inicijavimas
*Įrašo parametras: nepasirašytas simbolis *s
Eilutė, kurią norite siųsti
*Eksporto parametrai: Nėra
***********************************************************/
tuščiaUart0SendString(nepasirašytasanglis*s)
{
Nors(*s !=0)
UART0_SEND(*s++);
}
/***********************************************************
*Funkcijos pavadinimas: adc_start
* Funkcijos funkcija: pradėkite ADC konvertavimą
*Įėjimo parametrai: Nėra
*Eksporto parametras: plūduriuojantis
Temperatūros vertė planšetiniame kompiuteryje
***********************************************************/
plūdėadc_start(tuščia)
{
nepasirašytasinttemp;
//Etaloninė įtampa yra 1,25 V, atrankos tikslumas yra 14 bitų, o konversijos tikslas yra lusto temperatūros jutiklis
ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
ADC_STOP(); //Nustatykite ADC konvertavimo paleidimo metodą į rankinį
ADC_START(); //Inicijuoti ADC konvertavimą
Nors(! ADC_SAMPLE_READY()); //Palaukite, kol konvertavimas bus baigtas
temp = ADCL >>2; //Išsaugokite konvertavimo rezultatus temp
temp |= (((nepasirašytasint) ADCH) <<6);
grįžtiADC_TO_CELSIUS (temp); //Grąžina faktinę temperatūros vertę po konvertavimo
}
/***********************************************************
*Funkcijos pavadinimas: get_temperature
* Funkcijos funkcija: apdorokite temperatūros vertę ir išsaugokite ją simbolių masyve, kad galėtumėte nuosekliai išvesti
*Įvesties parametras: nepasirašytas simbolis *išvestis
Naudojama konvertuotai temperatūros vertei saugoti
plūduriuojanti temperatūra
Celsijaus temperatūros vertė
*Eksporto parametrai: Nėra
***********************************************************/
tuščiaget_temperature(nepasirašytasanglis*išvestis,plūdėtemp)
{
Rezultatas[0] = (nepasirašytasanglis)(temp) /10 + 48; //Dešimt vietų
Rezultatas[1] = (nepasirašytasanglis)(temp) %10 + 48; //vienaženklis
Rezultatas[2] ='.'; //Dešimtainis kablelis
Rezultatas[3] = (nepasirašytasanglis)(temp*10) %10 + 48; //Dešimta
Rezultatas[4] = (nepasirašytasanglis)(temp*100) %10 + 48; //Procentilis
Rezultatas[5] =''; //Stygų endifiers
}
/***********************************************************
*Funkcijos pavadinimas: watchdog_init
* Funkcijos funkcija: laikrodžio šuns inicijavimas
*Įėjimo parametrai: Nėra
*Eksporto parametrai: Nėra
***********************************************************/
tuščiawatchdog_init (tuščia)
{
WDT_SET_TIMEOUT_PERIOD straipsnio SEC_1 dalis; //Nustatykite skirtąjį laiką į 1 s
WDT_ENABLE (); //Paleiskite sargybinį šunį
}
[url=] [/url]
(3) Taikymo lygmuo
[url=] [/url]
/*******************************************************************
Failo pavadinimas: main.c
Autorius: hustlzp
Data: 2011/3/11
Versija: 1.0
Funkcijos aprašymas: Pagrindinis programos failas
Funkcijų sąrašas: (praleista)
Modifikacijos įrašas:
*******************************************************************/
#include
/********************************************************************
Paslaugos nutraukimo procedūros
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektorius=T1_VECTOR
__interrupt negaliojantis T1_ISR(negaliojantis)
{
EA = 0; Vartai nutraukiami
led2 = LED_ON;
get_temperature(išvestis,adc_start()); Konvertuokite temperatūros reikšmę į išvesties simbolių masyvą
Uart0SendString(išvestis); Išėjimo temperatūros vertė
Uart0SendString("°C");
Šviesos diodas2
/* 串口接收中断子程序
-------------------------------------------------------*/
#pragma vektorius=URX0_VECTOR
__interrupt negaliojantis RE_ISR(negaliojantis)
{
EA = 0;
LED3 = LED_ON;
gauti = U0DBUF;
if(type==1) // type=1, kuris nurodo, kad gautas simbolis naudojamas laikmačio perpildymo laikotarpiui nustatyti
{
tipas = 0;
jungiklis (gauti)
{
atvejis "0": // Laikmačio perpildymo laikotarpis yra 0,5 s
{
SET_TIMER1_PERIOD (TIMER1_OVF_dot5SEC);
pertrauka;
}
atvejis '1': // Laikmačio perpildymo laikotarpis yra 1s
{
SET_TIMER1_PERIOD (TIMER1_OVF_1SEC);
pertrauka;
}
atvejis '2': // Laikmačio perpildymo laikotarpis yra 2s
{
SET_TIMER1_PERIOD straipsnio TIMER1_OVF_2SEC dalis;
pertrauka;
}
}
}
else if(type==2) // type=2, nurodantis, kad gauti simboliai naudojami miego režimo valdymui
{
tipas = 0;
LED1 = LED_OFF;
LED2 = LED_OFF;
led3 = LED_OFF;
jungiklis (gauti)
{
atvejis "1": // Įjungti maitinimo režimą PM1
{
SET_POWER_MODE straipsnio 1 dalis;
pertrauka;
}
atvejis '2': // Įjungti maitinimo režimą PM2
{
SET_POWER_MODE straipsnio 2 dalis;
pertrauka;
}
atvejis "3": //Įjungti maitinimo režimą PM3
{
SET_POWER_MODE straipsnio 3 dalis;
pertrauka;
}
}
}
else if(type==0) // type=0, kuris nurodo, kad gautas simbolis yra valdymo komandos tipas: @ arba $
{
if(receive=='@')
{
tipas = 1; "@" gaunamas nurodantis, kad kitas simbolis naudojamas perpildymo laikotarpiui nustatyti
}
else if(receive=='$')
{
tipas = 2; Gaunamas "$", nurodantis, kad kitas simbolis naudojamas sistemos ramybės režimo valdymui
}
}
led3 = LED_OFF;
EA = 1;
}
=LED_OFF;
TIMER1_OVERFLOW_INT_SETFLAG straipsnio INT_CLR dalis; Išvalykite pertraukimo ženklą
EA = 1; Atviras pertraukimas
}
/* 主函数
-------------------------------------------------------*/
void main(void)
{
SET_MAIN_CLOCK_SOURCE (KRIŠTOLAS); Nustatykite sistemos laikrodį į 32 MHz kristalinį osciliatorių
led_init (); LED inicijavimas
uart0_init(); Nuosekliojo prievado UART0 inicijavimas
timer1_init(); 1 laikmatis inicijuojamas
watchdog_init(); Stebėjimo šuns inicijavimas
nors (1)
{
WDT_RESET (); Nuolat maitinkite šunį
}
}/********************************************************************
Pagrindinė programa
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
nepasirašyta simbolių išvestis[6]={0}; Temperatūros duomenys saugomi, kad būtų lengva nuosekliai išvesti
nepasirašytas char gauti; Išsaugokite gautus simbolius
nepasirašytas simbolio tipas = 0; Gauto simbolio tipo vėliavėlė nustatyta į 0/1/2"modulis.h"[url=] [/url]
5. TestavimasO ~ Kodas pagaliau įklijuotas, tai tikrai varginantis, išbandykime šią mažą sistemą:
(1) Mėginių ėmimas pagal laiką
Atidarykite nuoseklųjį prievadą ir pradėkite IAR derinimą ir pastebėkite, kad šviesos diodas1 dega, o nuosekliojo prievado įrankio temperatūros vertė nuolat generuojama, o atrankos intervalas nustatomas kaip 2 s:
(2) Mėginių ėmimo intervalo kontrolė
Nuosekliojo prievado įrankyje įveskite "@1", tada patikrinkite atrankos intervalą ir pastebėkite, kad jis tapo 1s; Įveskite "@0" ir atrankos intervalas pasikeitė į 0.5 s.
(3) Miego valdymas
Nuosekliojo prievado įrankyje įveskite "$1" ir pastebėkite, kad visi šviesos diodai išjungti ir temperatūros mėginių ėmimas sustabdytas:
Po bandymo sistema veikia normaliai ir stabiliai ir iš esmės atitinka reikalavimus.
Studentai, kuriems reikalingas šaltinio kodasSpustelėkite čia, kad atsisiųstumėte
6. IšvadaŠiame straipsnyje pateikiamas šiek tiek išsamus eksperimentas, parodantis, kaip integruoti CC2430 lusto išteklius, kad būtų sukurta palyginti standartizuota maža sistema. Po kelių dienų skirsiu laiko parašyti paprastą hal.h vartotojo vadovą, kad aš ir visi galėtume lengvai valdyti CC2430.
Toliau baigsiu savo tyrimus apie CC2430 lusto išteklius ir atsiduosiu mokytis TI Z-Stack protokolo krūvos ~
Šios serijos tinklaraščio įrašas kol kas baigėsi, tačiau Zigbee kelionė tęsis. Peizažas į priekį nežinomas, bet tikiu, kad autorius įveiks kliūtis su visais ir paragaus pakilimų ir nuosmukių, ir bus laimėjimų.
Sekite naujienas: "Prisijunkite prie TI Z-Stack" tinklaraščio įrašų!