Pärast "Zigbee Journey (9)" kirjutamist 3. märtsil plaanis autor kohe alustada väikese eksperimendi kirjutamist "temperatuuri jälgimissüsteemist", mis oleks kokkuvõte hajutatud teadmistepunktidest. Kuid ma mõistsin ka, et kuigi iga eelnev väike katse oli üksikasjalikult kirjeldatud, võib selle koodi normatiivset ja struktuurset olemust pidada talumatuks. Kuna tegemist on kokkuvõtega, peaksime tegema edusamme algsel alusel, mitte mehaaniliselt kokku panema eelnevaid väikeseid teadmiste punkte. Seetõttu panin oma algse plaani pausile, võtsin aega, et õppida sisseehitatud arenduse üldisi tehnikaid ja kirjutasin kaks esseedManustatud C51 programmeerimise spetsifikatsioon" ja "Manustatud projekti koodistruktuuri hierarhia》。 See päevik ei ole mitte ainult kokkuvõte Zigbee esimesest reisist, vaid sisaldab ka autori viimaste päevade õpikogemusi, lootes olla abiks Zigbee algajatele.
Täistekst on organiseeritud tarkvaraarenduse põhiprotsessi järgi: nõuete analüüs, ülevaate koostamine, detailne disain, kodeerimise rakendamine ja testimine.
1. Nõudluse analüüsPärast arutelu "kliendi" ja "arendaja" vahel määrati järgmine süsteemi funktsiooni kirjeldus:
… Praegust toatemperatuuri koguvad CC2430-põhised sõlmed ning selle temperatuuriväärtusi saab jälgida arvuti kaudu
… CC2430 sõlm ise peab omama teatud stabiilsust ja suudab automaatselt naasta normaalsesse olekusse
… Sõlme proovivõtuvahemikku ja toitehaldust saab juhtida PC
2. Kontuuri disainÜlaltoodud nõuete analüüsi kohaselt saame süsteemi jagada kaheks mooduliks:CC2430 sõlmjaPC。
[CC2430 sõlm]
… Väliseid parameetreid saab regulaarselt koguda ja saata arvutisse
… Automaatne lähtestus, kui masin on välja lülitatud
… Käske arvutilt saab vastu võtta ja töödelda vastavalt: muuta proovivahemikku/toitehaldust
[PC]
… C-masin võtab andmeid vastu ja kuvab jadapordi tööriista kaudu
… Juhiseid saab saata mikrokontrollerile seriaalpordi tööriista kaudu, et kontrollida selle proovivõtukiirust ja võimsuse juhtimist
3. Detailne disain(1) Koodistruktuur
Selle süsteemi koodistruktuuri kihilisust on tegelikult kirjeldatud essees "Manustatud projekti koodistruktuuri hierarhia", ja koopia on järgmine:
(1) Riistvaraline abstraktsioonikiht
[ioCC2430.h] (Süsteem kaasas):Kõik CC2430 SFR ja katkestusvektorid on defineeritud
[hal.h] Sisaldab ühiseid tüübidefinitsioone, ühiseid määramismakrosid ja CC2430 kiibisiseste ressursside (I/O, jadaside, ADC, taimer, toitehaldus jne) konfiguratsioone.
(2) Funktsionaalne moodulikiht
[module.h] määratleb kiibisisesed ressursid (taimerid, I/O), kiibivälised laiendusmoodulid (LED-id) ja seotud funktsioonide deklaratsioonid
[module.cRakenda iga mooduli (LED) initsialiseerimine.
(3) Rakenduskiht
[main.cVaata hal.h, ioCC2430.h ja module.h konkreetseid rakendusnõudeid, nagu temperatuuri mõõtmine, arvutiga suhtlemine ning väljalülitamine ja lähtestamine
(2) Iga mooduli rakendusmeetodid
Vastavalt moodulitele, mis on jagatud kontuurdisaini järgi, saab sisemise süsteemi jagada kaheks peamiseks mooduliks:CC2430 sõlmjaPC。
Kuna PC-l on olemas jadapordi suhtlusvahendid, suudavad selle funktsioonid vastata nõuetele, seega pole vaja seda osa arvutist teha ega analüüsida. Räägime allpool jaotisest CC2430
Iga punkti alamfunktsiooni rakendusmeetod:
… Kasuta taimeri loenduse ülevoolu katkestust, et käivitada ajastatud proovivõtt
… UART0 režiim koos jadapordiga edastab temperatuuriandmed arvutile
… CC2430 sisseehitatud valvekoera vooluringi kasutatakse süsteemi automaatse lähtestamise funktsiooni realiseerimiseks
… Serial-port on mõeldud katkestuste vastuvõtmiseks, et püüda ja reageerida arvuti juhtimiskäskudele
1) Kui vastu võetakse@Märk on proovivõtuvahemiku juhtkäsk, millele järgneb number, mis näitab proovivõtuvahemikku: 0-0,5s, 1-1s, 2-2s
如:@0,表示每隔0.5秒采样一次。
2) Kui vastu võetakse$ Tähemärgiks on unerežiimi käsk, millele järgneb number, mis näitab toiterežiimi
Näiteks: $3, mis tähendab süsteemi viimist võimsusrežiimi 3.
(3) Programmi vooskeem
- Põhiprogrammi vooskeem
- Taimer 1 ülevoolu katkestusprogrammi vooskeem
- Jadapordi vastuvõtu katkestusprotseduuri vooskeem
4. Kodeerimise rakendus(1) Riistvaraline abstraktsioonikiht
Riistvara abstraktsioonikiht sisaldab ioCC2430.h ja hal.h. Kuna esimene süsteem on sellega kaasas, siis seda ei loetleta.
Järgmine on nimekiri kõigist hal.h sisudest (kuna see fail on liiga pikk ja tundub ebamugav, näitan seda moodulites):
- pea
- Sisend/O pordid
- Katkestatud
- Seeriaport
- Võimsuse ja kella juhtimine
- Taimer
- Valvur
- ADC
[url=]
[/url]
/***********************************************************
*Faili nimi: hal.h
*Autor: hustlzp
*Kuupäev: 8. märts 2011
*Väljaanne: 1.1
*Funktsiooni kirjeldus: Riistvara abstraktsioonikiht
*Muudetud kirjed:
***********************************************************/
#ifndef HAL_H
#defineHAL_H
#include
/***********************************************************
Levinud tüübi definitsioonid
***********************************************************/
Typedef allkirjastamatachar BYTE;
Typedef allkirjastamataint SÕNA;
Typedef allkirjastamatapikk DWORD;
/***********************************************************
Levinud makrodefinitsioonid
***********************************************************/
//8 kohta kõrgemal
#defineHIGH_BYTE(a) ((BYTE) (((WORD)(a)) >> 8))
//8 kohta madalamal
#defineLOW_BYTE(a) ((BAIT) ((WORD)(a)))
//Määramine
#defineSET_WORD(regH,regL,word)
tegema{
(regH)=HIGH_BYTE(sõna);
(regL)=LOW_BYTE(sõna);
}samal ajal(0)
[url=] [/url]
[url=] [/url]
/***********************************************************
Sisend/O pordid
***********************************************************/
/*Seadista I/O pordi suund
-----------------------------------------*/
#defineIO_DIR_PORT_PIN(port, tihvt, suunas)
tegema{
kui(dir == IO_OUT)
P##port##DIR |= (0x01<<(nõel));
else
P##port##DIR &= ~(0x01<<(nõel));
}samal ajal(0)
//Parameetri dir väärtus on:
#defineIO_IN 0
#defineIO_OUT 1
/*Seadista I/O pordi sisendrežiim
-----------------------------------------*/
#defineIO_IMODE_PORT_PIN(port, PIN, imode)
tegema{
kui(imode == IO_IMODE_TRI)
P##port##INP |= (0x01<<(nõel));
else
P##port##INP &= ~(0x01<<(nõel));
}samal ajal (0)
#define IO_PUD_PORT(portvein, pud)
do {
kui (pud == IO_PULLDOWN)
P2INP |= (0x01 << (port+5));
else
P2INP &= ~(0x01 << (port+5));
} samal ajal (0)
Parameetri PUD väärtus on:
#define IO_PULLUP 0 // Tõmba üles
#define IO_PULLDOWN 1 // Tõmba alla
/*配置I/O口的功能
-----------------------------------------*/
#define IO_FUNC_PORT_PIN(port, tihvt, funktsionaalsus)
do {
if((port == 2) && (pin == 3)){
if (func) {
P2SEL |= 0x02;
} muidu {
P2SEL &= ~0x02;
}
}
else if((port == 2) && (PIN == 4)){
if (func) {
P2SEL |= 0x04;
} muidu {
P2SEL &= ~0x04;
}
}
else{
if (func) {
P##port##SEL |= (0x01<<(pin));
} muidu {
P##port##SEL &= ~(0x01<<(pin));
}
}
} samal ajal (0)
Parameetri func väärtus on:
#define IO_FUNC_GIO 0 // Üldine I/O
#define IO_FUNC_PERIPH 1 // Perifeerne I/O
Seadista perifeerse I/O asukoht
#define IO_PER_LOC_TIMER1_AT_PORT0_PIN234() do { PERCFG = (PERCFG&~0x40)|0x00; } samal ajal (0)
#define IO_PER_LOC_TIMER1_AT_PORT1_PIN012() do { PERCFG = (PERCFG&~0x40)|0x40; } samal ajal (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN34() do { PERCFG = (PERCFG&~0x20)|0x00; } samal ajal (0)
#define IO_PER_LOC_TIMER3_AT_PORT1_PIN67() do { PERCFG = (PERCFG&~0x20)|0x20; } samal ajal (0)
#define IO_PER_LOC_TIMER4_AT_PORT1_PIN01() do { PERCFG = (PERCFG&~0x10)|0x00; } samal ajal (0)
#define IO_PER_LOC_TIMER4_AT_PORT2_PIN03() do { PERCFG = (PERCFG&~0x10)|0x10; } samal ajal (0)
#define IO_PER_LOC_SPI1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x08)|0x00; } samal ajal (0)
#define IO_PER_LOC_SPI1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x08)|0x08; } samal ajal (0)
#define IO_PER_LOC_SPI0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x00; } samal ajal (0)
#define IO_PER_LOC_SPI0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x04)|0x04; } samal ajal (0)
#define IO_PER_LOC_UART1_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x02)|0x00; } samal ajal (0)
#define IO_PER_LOC_UART1_AT_PORT1_PIN4567() do { PERCFG = (PERCFG&~0x02)|0x02; } samal ajal (0)
#define IO_PER_LOC_UART0_AT_PORT0_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x00; } samal ajal (0)
#define IO_PER_LOC_UART0_AT_PORT1_PIN2345() do { PERCFG = (PERCFG&~0x01)|0x01; } samal ajal (0)
//Parameetri imode väärtus on:
#defineIO_IMODE_PUD 0 //Tõmba üles/alla
#defineIO_IMODE_TRI 1 //Kolm osariiki[url=] [/url]
[url=] [/url]
/***********************************************************
Katkestatud
***********************************************************/
//Sisse/välja katkestuste puhul
#defineINT_ON 1
#defineINT_OFF 0
//Kasutatakse katkestuslippude paigaldamiseks/puhastamiseks
#defineINT_SET 1
#defineINT_CLR 0
//Globaalsete katkestuste seaded
#defineINT_GLOBAL_ENABLE(sees) EA=(!! on)
//Defineeri katkestus
#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
/*Lubatud katkestused
-----------------------------------------*/
#defineINT_ENABLE(inum, on)
tegema{
kui (inum==INUM_RFERR) { RFERRIE = sees; }
else kui(inum==INUM_ADC) { ADCIE = sees; }
else kui(inum==INUM_URX0) { URX0IE = sees; }
else kui(inum==INUM_URX1) { URX1IE = sees; }
else kui(inum==INUM_ENC) { ENCIE = sees; }
else kui(inum==INUM_ST) { STIE = sees; }
else kui(inum==INUM_P2INT) { (on) ? (IEN2 |=0x02) : (IEN2 &= ~0x02); }
else kui(inum==INUM_UTX0) { (on) ? (IEN2 |=0x04) : (IEN2 &= ~0x04); }
else kui(inum==INUM_DMA) { DMAIE = sees; }
else kui(inum==INUM_T1) { T1IE = sees; }
else kui(inum==INUM_T2) { T2IE = sees; }
else kui(inum==INUM_T3) { T3IE = sees; }
else kui(inum==INUM_T4) { T4IE = sees; }
else kui(inum==INUM_P0INT) { P0IE = sees; }
else kui(inum==INUM_UTX1) { (on) ? (IEN2 |=0x08) : (IEN2 &= ~0x08); }
else kui(inum==INUM_P1INT) { (on) ? (IEN2 |=0x10) : (IEN2 &= ~0x10); }
else kui(inum==INUM_RF) { (on) ? (IEN2 |=0x01) : (IEN2 &= ~0x01); }
else kui(inum==INUM_WDT) { (on) ? (IEN2 |=0x20) : (IEN2 &= ~0x20); }
}samal ajal (0)
/*Sea katkestuste prioriteet
-----------------------------------------*/
#defineINT_PRIORITY(grupp, PRI)
tegema{
kui(pri ==0) { IP0 &= ~grupp; IP1 &= ~grupp; }
kui(pri ==1) { IP0 |= grupp; IP1 &= ~grupp; }
kui(pri ==2) { IP0 &= ~grupp; IP1 |= grupp; }
kui(pri ==3) { IP0 |= grupp; IP1 |= grupp; }
}samal ajal (0)
//Parameetri pri väärtus on: 0/1/2/3 (kõrgeim prioriteet)
//Parameetrite grupi väärtus on:
#defineRFERR_RF_DMA 0x01//Grupp IP0
#defineADC_P2INT_T1 0x02//Grupp IP1
#defineURX0_UTX0_T2 0x04//Grupp IP2
#defineURX1_UTX1_T3 0x08//Grupp IP3
#defineENC_P1INT_T4 0x10//Grupp IP4
#defineST_WDT_P0INT 0x20//Grupp IP5
/*Hangi katkestuslipp
-----------------------------------------*/
#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
)
/*Seadista katkestuslipp
-----------------------------------------*/
#defineINT_SETFLAG(inum, n)
tegema{
kui (inum==INUM_RFERR) { RFERRIF= f; }
else kui(inum==INUM_ADC) { ADCIF = f; }
else kui(inum==INUM_URX0) { URX0IF = f; }
else kui(inum==INUM_URX1) { URX1IF = f; }
else kui(inum==INUM_ENC) { ENCIF_1 = ENCIF_0 = f; }
else kui(inum==INUM_ST) { STIF = f; }
else kui(inum==INUM_P2INT) { P2IF = f; }
else kui(inum==INUM_UTX0) { UTX0IF= f; }
else kui(inum==INUM_DMA) { DMAIF = f; }
else kui(inum==INUM_T1) { T1IF = f; }
else kui(inum==INUM_T2) { T2IF = f; }
else kui(inum==INUM_T3) { T3IF = f; }
else kui(inum==INUM_T4) { T4IF = f; }
else kui(inum==INUM_P0INT) { P0IF = f; }
else kui(inum==INUM_UTX1) { UTX1IF= f; }
else kui(inum==INUM_P1INT) { P1IF = f; }
else kui(inum==INUM_RF) { (f)? (S1CON |=0x03) : (S1CON &= ~0x03); }
else kui(inum==INUM_WDT) { WDTIF = f; }
}samal ajal (0)
[url=] [/url]
[url=] [/url]
/***********************************************************
Seeriaport
***********************************************************/
//BAUD_E väärtus, mis vastab erinevatele baudi kiirustele
#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 väärtus, mis vastab erinevatele baudi kiirustele
#defineBAUD_M(pauk) (
(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)
/*Serial-pordi konfiguratsioon UART-režiimis
-----------------------------------------*/
#defineUART_SETUP(uart, receiveEnable, baudRate, valikud)
tegema{
kui((uart) ==0){
kui(PERCFG &0x01){
P1SEL |=0x30;
}else{
P0SEL |=0x0C;
}
}
else{
kui(PERCFG &0x02){
P1SEL |=0xC0;
}else{
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 |= ((valikud) |0x80);
}samal ajal(0)
//Parameetri väärtus receiveEnable:
#defineUART_RECEIVE_ENABLE 0x40 //Luba saamine
#defineUART_RECEIVE_DISABLE 0x00
//Parameetrite valikute väärtus:
#defineFLOW_CONTROL_ENABLE 0x40 //Voolu juhtimine
#defineFLOW_CONTROL_DISABLE 0x00
#defineEVEN_PARITY 0x20 //Aeg-ajalt verifitseerimine
#defineODD_PARITY 0x00 //Kummaline kinnitus
#defineNINE_BIT_TRANSFER 0x10 //9-baidine ülekanne
#defineEIGHT_BIT_TRANSFER 0x00 //8-baidine ülekanne
#definePARITY_ENABLE 0x08 //Pariteedikontrolli võimaldamine
#definePARITY_DISABLE 0x00
#defineTWO_STOP_BITS 0x04 //2-asendiline peatusasend
#defineONE_STOP_BITS 0x00 //1 peatusasend
#defineHIGH_STOP 0x02 //Peatustase on kõrge
#defineLOW_STOP 0x00 //Peatusasend on madal
#defineHIGH_START 0x01 //Algbiti tase on kõrge
#defineLOW_START 0x00 //Algbiti tase on madal
//Seeriaport saadab tegelasi
#defineUART_SEND(uart,andmed)
tegema{
samal ajal(U##uart##CSR &0x01);
U##uart##DBUF = andmed;
}samal ajal (0)
#defineUART0_SEND(andmed) UART_SEND(0,andmed)
#defineUART1_SEND(andmed) UART_SEND(1,andmed)
//Serial-port võtab tähemärgid vastu
#defineUART_RECEIVE(uart, andmed)
tegema{
samal ajal(! (U##uart##CSR&0x04));
data=U##uart##DBUF;
}samal ajal(0)
#defineUART0_RECEIVE(andmed) UART_RECEIVE(0,andmed)
#defineUART1_RECEIVE(andmed) UART_RECEIVE(1,andmed)
[url=] [/url]
[url=] [/url]
/***********************************************************
Võimsuse ja kella juhtimine
***********************************************************/
//Võta kella ristmik
#defineCLKSPD (CLKCON ja 0x07)
//Seadista võimsusrežiim
#defineSET_POWER_MODE(režiim)
tegema{
kui(režiim ==0) { UNI &= ~0x03; }
else kui(režiim ==3) { UNI |=0x03; }
else{ UNI &= ~0x03; SLEEP |= režiim; }
PCON |=0x01;
asm("NOP");
}samal ajal (0)
//Parameetrirežiimiks on seatud järgmised väärtused:
#definePOWER_MODE_0 0x00
#definePOWER_MODE_1 0x01
#definePOWER_MODE_2 0x02
#definePOWER_MODE_3 0x03
//Kasutatakse kõrgsageduslike RC-ostsillaatorite stabiilsuse tuvastamiseks
#defineHIGH_FREQUENCY_RC_OSC_STABLE (UNI &0x20)
//Kasutatakse kristallostsillaatori stabiilse seisundi tuvastamiseks
#defineXOSC_STABLE (UNI &0x40)
//Võta taimeri tick sageduse väärtus
#defineTICKSPD ((CLKCON & 0x38) >> 3)
//Seadista peakella sagedus
#defineSET_MAIN_CLOCK_SOURCE(allikas)
tegema{
kui(allikas) {
CLKCON |=0x40;
samal ajal(! HIGH_FREQUENCY_RC_OSC_STABLE);
kui(TICKSPD ==0){
CLKCON |=0x08;
}
UNI |=0x04;
}
else{
UNI &= ~0x04;
samal ajal(! XOSC_STABLE);
asm("NOP");
CLKCON &= ~0x47;
UNI |=0x04;
}
}samal ajal (0)
//Parameetri allika väärtus on:
#defineCRYSTAL 0x00 //Kristallostsillaator
#defineRC 0x01 //RC-ostsillaator
[url=] [/url]
[url=] [/url]
/***********************************************************
Taimer 1
***********************************************************/
//Taimer 1 võimaldab loenduse ülevoolu katkestada
#defineTIMER1_ENABLE_OVERFLOW_INT(val)
(TIMIF = (val)? TIMIF |0x40: TIMIF & ~0x40)
//Seadista ülevoolukatkestuse lipp taimeri 1 jaoks
#defineTIMER1_OVERFLOW_INT_SETFLAG(f) (T1CTL= ((T1CTL & (~0x10)) | f))
//Taimer 1 algab
#defineTIMER1_RUN(väärtus) (T1CTL = (väärtus)? T1CTL|0x02 : T1CTL&~0x03)
//Seadista taimeri kellajaotus
#defineSET_TIMER_TICK(väärtus) do{ CLKCON = ((CLKCON & (~0x38)) | väärtus); } while(0)
//Väärtuse väärtus on:
#defineTIMER1_TICK_32M 0x00 //32MHz
#defineTIMER1_TICK_16M 0x08 //16MHz, süsteemi lähtestamise vaikimisi väärtus
#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
//Sea TICK ristmik taimeriks 1
#defineSET_TIMER1_TICKDIV(väärtus)
tegema{
T1CTL &= ~0x0c;
T1CTL |= väärtus;
}samal ajal (0)
//kus väärtus on:
#defineTIMER1_TICKDIV_1 0x00 //1. divisjon
#defineTIMER1_TICKDIV_8 0x04 //8-suunaline sagedus
#defineTIMER1_TICKDIV_32 0x08
#defineTIMER1_TICKDIV_128 0x0c
//Sea taimeri ülevoolu periood
#defineSET_TIMER1_PERIOD(väärtus)
tegema{
T1CC0H = HIGH_BYTE(väärtus);
T1CC0L = LOW_BYTE(väärtus);
}samal ajal (0)
//Seadista taimer 1 töörežiim
#defineSET_TIMER1_MODE(režiim)
tegema{
T1CTL = ((T1CTL & (~0x03)) | režiimi);
}samal ajal (0)
//Režiimi väärtus on:
#defineTIMER1_MODE_STOP 0x00
#defineTIMER1_MODE_FREE 0x01
#defineTIMER1_MODE_MODULE 0x02
#defineTIMER1_MODE_UPDOWN 0x03
[url=] [/url]
[url=] [/url]
/***********************************************************
Valvur
***********************************************************/
//Sea valvekoera taimeri ületäitumise periood
#defineWDT_SET_TIMEOUT_PERIOD(aeg maha)
tegema{ WDCTL &= ~0x03; WDCTL |= timeout; }samal ajal (0)
//Parameetri ajapiirangu väärtus on:
#defineSEC_1 0x00 //pärast 1 sekundit
#defineM_SEC_250 0x01 //pärast 250 ms
#defineM_SEC_15 0x02 //pärast 15 ms
#defineM_SEC_2 0x03 //pärast 2 ms
//Koerte toitmise protseduurid
#defineWDT_RESET() do {
WDCTL = (WDCTL & ~0xF0) |0xA0;
WDCTL = (WDCTL & ~0xF0) |0x50;
} samal ajal (0)
//Käivita/peata valvekoera taimer
#defineWDT_ENABLE() WDCTL |= 0x08
#defineWDT_DISABLE() WDCTL &= ~0x08
[url=] [/url]
[url=] [/url]
/***********************************************************
ADC
***********************************************************/
//Seadista üks ADC
#defineADC_SINGLE_CONVERSION(seaded)
tegema{ ADCCON3 = seaded; }samal ajal(0)
//Parameetrite seadistus koosneb järgmistest kombinatsioonidest:
//Võrdluspinge
#defineADC_REF_1_25_V 0x00 //Sisemine 1,25V viitepinge
#defineADC_REF_P0_7 0x40 //Väline viitepinge AIN7 kontaktil
#defineADC_REF_AVDD 0x80 //AVDD_SOC Nõelad
#defineADC_REF_P0_6_P0_7 0xC0 //AIN6-AIN7 Väline viitepinge diferentsiaalsisenditele
//Proovivõtusagedus
#defineADC_8_BIT 0x00 //8. koht
#defineADC_10_BIT 0x10 //10. koht
#defineADC_12_BIT 0x20 //12. koht
#defineADC_14_BIT 0x30 //14. koht
//Siseneme kanalisse
#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 //Maa
#defineADC_TEMP_SENS 0x0E //Kiibisisene temperatuuriandur
#defineADC_VDD_3 0x0F //vdd/3
ADC konverteerimine on lõpetatud
#define ADC_SAMPLE_READY() (ADCCON1 ja 0x80)
#endif
//启动ADC转化
#define ADC_START()
do { ADCCON1 |= 0x40; } samal ajal (0)//Vali ADC päästikurežiim käsitsi (st ADC_SAMPLE_READY)
#defineADC_STOP()
tegema{ ADCCON1 |=0x30; }samal ajal (0)[url=] [/url]
(2) Funktsionaalne moodulikiht
[url=] [/url]
/***********************************************************
*Faili nimi: module.h
*Autor: hustlzp
*Kuupäev: 6. märts 2011
*Versioon: 1.0
*Funktsiooni kirjeldus: Funktsionaalse mooduli kihi päise fail
*Funktsioonide nimekiri: tühi led_init()
tühi timer1_init()
void uart0_init(void);
void Uart0SendString(märgistamata tegelane *s);
float adc_start (tühi)
void get_temperature(märgistamata karakter *väljund, float temp);
void watchdog_init(tühi);
*Muudetud kirjed:
***********************************************************/
#ifndef MODULE_H
#defineMODULE_H
#include"hal.h"
/***********************************************************
LED
***********************************************************/
//Määratle LED-tihvtid
#defineled1 P1_0
#defineLED2 P1_1
#defineLED3 P1_2
#defineLED4 P1_3
//LED-tuli ja välja lülitatud
#defineLED_OFF 1
#defineLED_ON 0
//LED-i initsialiseerimine
tühiled_init(tühi);
/***********************************************************
timer1
***********************************************************/
//Kasutatakse taimeri ülevooluperioodi väärtuse määramiseks
#defineTIMER1_OVF_2SEC 0xF424 //2s
#defineTIMER1_OVF_1SEC 0x7A12 //1s
#defineTIMER1_OVF_dot5SEC 0x3D09 //0,5s
//Taimer 1 initsialiseerib
tühi timer1_init(tühi);
/***********************************************************
UART0
***********************************************************/
//UART0 initsialiseerimine
tühi uart0_init(tühi);
//Serial-pordi edastusjada
tühi Uart0SendString(allkirjastamatachar*s);
/***********************************************************
ADC-14
***********************************************************/
//Kasutatakse ADC poolt saadud andmete teisendamiseks Celsiuse temperatuuriks
#defineADC_TO_CELSIUS(temperatuur) (temperatuur * 0,06229 - 311,43)
//Algata ADC konverteerimine
floatadc_start(tühi);
//Ümberehitus
tühi get_temperature(allkirjastamatachar*väljund,floattemp);
/***********************************************************
WatchDog
***********************************************************/
//Vahtkoera initsialiseerimine
tühi watchdog_init(tühi);
#endif
[url=] [/url]
[url=] [/url]
/***********************************************************
*Failinimi: module.c
*Autor: hustlzp
*Kuupäev: 2011/3/11
*Versioon: 1.0
*Funktsiooni kirjeldus: Funktsionaalse mooduli kihi lähtefail
*Funktsioonide nimekiri: (välja jäetud)
*Muudetud kirjed:
***********************************************************/
#include"module.h"
/***********************************************************
*Funktsiooni nimi: led_init
*Funktsioonifunktsioon: LED-i initsialiseerimine
*Sissepääsu parameetrid: Puuduvad
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühiled_init(tühi)
{
//Seadista P1.0, P1.1, P1.2 ja P1.3 üldisteks I/O portideks
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);
//Seadista väljunditeks P1.0, P1.1, P1.2 ja 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;
}
/***********************************************************
*Funktsiooni nimi: timer1_init
* Funktsioonifunktsioon: taimer 1 initsialiseerimine
*Sissepääsu parameetrid: Puuduvad
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühitimer1_init(tühi)
{
INT_GLOBAL_ENABLE(INT_ON); //Ava globaalne katkestus
INT_ENABLE(INUM_T1, INT_ON); //Avatud T1 katkestus
TIMER1_ENABLE_OVERFLOW_INT(INT_ON); //Open T1 loenduse ülevoolu katkestus
SET_TIMER_TICK(TIMER1_TICK_4M); //Sea taimeri TICK 4MHz peale
SET_TIMER1_PERIOD(TIMER1_OVF_2SEC); //Määra T1 loendamise periood kaheks sekundiks
SET_TIMER1_TICKDIV(TIMER1_TICKDIV_128); //Seadista kella ristlõige T1 jaoks 128
SET_TIMER1_MODE(TIMER1_MODE_MODULE); //Määra T1 töörežiimiks moodul
}
/***********************************************************
*Funktsiooni nimi: uart0_init
*Funktsioonifunktsioon: Serial port UART0 initsialiseerimine
*Sissepääsu parameetrid: Puuduvad
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühiuart0_init(tühi)
{
//Vali UART asukoht
IO_PER_LOC_UART0_AT_PORT0_PIN2345();
//UART-i seadistamine: Vastuvõtt lubatud, 115200 bps, ühe biti stopp-bitt, pariteeti puudub
UART_SETUP(0, UART_RECEIVE_ENABLE,115200, ONE_STOP_BITS | PARITY_DISABLE);
//Ava täielik katkestus
INT_GLOBAL_ENABLE(INT_ON);
//Ava seriaalport 0 katkestuste vastuvõtmiseks
INT_ENABLE(INUM_URX0, INT_ON);
}
/***********************************************************
*Funktsiooni nimi: Uart0SendString
* Funktsioonifunktsioon: taimer 1 initsialiseerimine
*Kirjeparameeter: märgistamata tegelane *s
Nöör, mida sa tahad saata
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühiUart0SendString(allkirjastamatachar*s)
{
samal ajal(*s !=0)
UART0_SEND(*s++);
}
/***********************************************************
*Funktsiooni nimi: adc_start
*Funktsioonifunktsioon: Käivita ADC konverteerimine
*Sissepääsu parameetrid: Puuduvad
*Ekspordiparameeter: float
Tahvelarvuti temperatuuriväärtus
***********************************************************/
floatadc_start(tühi)
{
Allkirjastamataintajutine;
//Võrdluspinge on 1,25V, proovivõtu täpsus 14 bitti ning teisenduse sihtmärgiks on kiibil olev temperatuuriandur
ADC_SINGLE_CONVERSION(ADC_REF_1_25_V | ADC_14_BIT | ADC_TEMP_SENS);
ADC_STOP(); //Sea ADC teisendamise käivitamismeetod käsitsi
ADC_START(); //Algata ADC konverteerimine
samal ajal(! ADC_SAMPLE_READY()); //Oota, kuni konverteerimine lõpule jõuab
temp = ADCL >>2; //Salvesta konverteerimise tulemused temperatuuris
temp |= (((allkirjastamataint) ADCH) <<6);
TagasitulekADC_TO_CELSIUS(ajutiselt); //Tagastab tegeliku temperatuuri väärtuse pärast teisendamist
}
/***********************************************************
*Funktsiooni nimi: get_temperature
*Funktsioonifunktsioon: Töötle temperatuuri väärtust ja salvesta see tähemärgimassiivi seriaalseks väljundiks
*Entry parameeter: märgistamata tegelane *väljund
Kasutatakse teisendatud temperatuuri väärtuse salvestamiseks
Ujumistemperatuur
Celsiuse järgi mõõdetud temperatuuriväärtus
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühiget_temperature(allkirjastamatachar*väljund,floattemp)
{
Väljund[0] = (allkirjastamatachar)(ajutine) /10 + 48; //Kümme kohta
Väljund[1] = (allkirjastamatachar)(temp) %10 + 48; //ühekohaline arv
Väljund[2] ='.'; //Kümnendkork
Väljund[3] = (allkirjastamatachar)(ajutine*10) %10 + 48; //Kümnes
Väljund[4] = (allkirjastamatachar)(ajutine*100) %10 + 48; //Protsentiil
Väljund[5] =''; //Keelte endifierid
}
/***********************************************************
*Funktsiooni nimi: watchdog_init
*Funktsioonifunktsioon: Jälgimiskoera initsialiseerimine
*Sissepääsu parameetrid: Puuduvad
*Ekspordiparameetrid: Puuduvad
***********************************************************/
tühiwatchdog_init(tühi)
{
WDT_SET_TIMEOUT_PERIOD(SEC_1); //Sea timeout aeg 1s peale
WDT_ENABLE(); //Alusta valvekoera
}
[url=] [/url]
(3) Rakenduskiht
[url=] [/url]
/*******************************************************************
Faili nimi: main.c
Autor: hustlzp
Kuupäev: 2011/3/11
Versioon: 1.0
Funktsiooni kirjeldus: Põhiprogrammi fail
Funktsioonide nimekiri: (välja jäetud)
Muudatuste kirje:
*******************************************************************/
#include
/********************************************************************
Katkestusteenuse protseduurid
********************************************************************/
/* 定时器1溢出中断子程序
-------------------------------------------------------*/
#pragma vektor=T1_VECTOR
__interrupt tühi T1_ISR(tühi)
{
EA=0; Värav on katkestatud
led2 = LED_ON;
get_temperature(väljund,adc_start()); Teisenda temperatuuri väärtus väljundiks tähemärkide massiiviks
Uart0SendString (väljund); Väljundtemperatuuri väärtus
Uart0SendString("°C");
LED2
/* 串口接收中断子程序
-------------------------------------------------------*/
#pragma vektor=URX0_VECTOR
__interrupt tühjus RE_ISR(tühi)
{
EA=0;
led3 = LED_ON;
vastuvõtt = U0DBUF;
if(type==1) // type=1, mis näitab, et vastuvõetud tähemärki kasutatakse taimeri ületäitumise perioodi määramiseks
{
type=0;
Lüliti (vastuvõtt)
{
juhtum '0': // Taimeri ülevoolu periood on 0,5s
{
SET_TIMER1_PERIOD(TIMER1_OVF_dot5SEC);
paus;
}
juhtum '1': // Taimeri üleujutuse periood on 1s
{
SET_TIMER1_PERIOD(TIMER1_OVF_1SEC);
paus;
}
juhtum '2': // Taimeri ülevoolu periood on 2s
{
SET_TIMER1_PERIOD(TIMER1_OVF_2SEC);
paus;
}
}
}
else if(type==2) // type=2, mis näitab, et vastuvõetud tähemärke kasutatakse unerežiimi juhtimiseks
{
type=0;
led1 = LED_OFF;
led2 = LED_OFF;
led3 = LED_OFF;
Lüliti (vastuvõtt)
{
juhtum '1': // Sisene toiterežiimi PM1
{
SET_POWER_MODE(1);
paus;
}
juhtum '2': // Sisene toiterežiimi PM2
{
SET_POWER_MODE(2);
paus;
}
juhtum '3': //Sisene toiterežiimi PM3
{
SET_POWER_MODE(3);
paus;
}
}
}
else if(type==0) // type=0, mis näitab, et vastuvõetud märk on juhtimiskäsu tüüp: @ või $
{
if(receive=='@')
{
type=1; '@' võetakse selleks, et näidata, et järgmine tähemärk määrab ülevooluperioodi
}
else if(receive=='$')
{
type=2; Saabub '$', mis näitab, et järgmine tähemärk kasutatakse süsteemi unerežiimi juhtimiseks
}
}
led3 = LED_OFF;
EA=1;
}
=LED_OFF;
TIMER1_OVERFLOW_INT_SETFLAG(INT_CLR); Puhasta katkestusmärk
EA=1; Avatud katkestus
}
/* 主函数
-------------------------------------------------------*/
Void main(void)
{
SET_MAIN_CLOCK_SOURCE(CRYSTAL); Seadista süsteemi taktsagedus 32MHz kristall-ostsillaatorile
led_init(); LED-i initsialiseerimine
uart0_init(); Serial-port UART0 initsialiseerimine
timer1_init(); Taimer 1 initsialiseerib
watchdog_init(); Vahtkoera initsialiseerimine
while(1)
{
WDT_RESET(); Toida koera pidevalt
}
}/********************************************************************
Põhiprogramm
********************************************************************/
/* 全局变量
-------------------------------------------------------*/
märgistamata märgi väljund[6]={0}; Temperatuuriandmed salvestatakse lihtsaks jadaväljundiks
allkirjastamata Char Receive; Salvesta saadud tähemärgid
märgistamata tähe tüüp=0; Vastuvõetud tähemärgi tüübilipp on seatud 0/1/2 väärtusele"module.h"[url=] [/url]
5. TestimineOh~ Kood on lõpuks kleebitud, see on tõesti väsitav, proovime seda väikest süsteemi:
(1) Ajastatud valim
Ava seriaalport ja alusta IAR silumist ning leia, et led1 on sisse lülitatud, seriaalpordi tööriista temperatuuriväärtus genereeritakse pidevalt ja proovivõtuvahemik on määratud 2s:
(2) Proovivõtuintervalli kontroll
Sisesta "@1" serial port tööriista, testi seejärel proovivõtuvahemikku ja leia, et see on muutunud 1s-ks; Sisesta "@0" ja proovivõtuvahemik on muutunud 0,5 sekundiks.
(3) Une kontroll
Sisesta jadapordi tööriista "$1" ja leia, et kõik LED-id on välja lülitatud ning temperatuuri proovivõtt on peatunud:
Pärast testimist töötab süsteem normaalselt ja stabiilselt ning vastab põhimõtteliselt nõuetele.
Õpilased, kes vajavad lähtekoodiKlõpsa siia, et alla laadida
6. KokkuvõteSee artikkel toob näiteks veidi põhjaliku eksperimendi, et näidata, kuidas integreerida CC2430 kiibil olevaid ressursse, et kirjutada suhteliselt standardiseeritud väike süsteem. Mõne päeva pärast võtan aega, et kirjutada hal.h jaoks lihtne kasutusjuhend, et mina ja kõik teised saaksime CC2430-d hõlpsasti kasutada.
Järgmisena lõpetan oma uurimistöö CC2430 kiibil olevate ressursside kohta ja pühendun TI Z-Stack protokollide virna õppimisele~
Selle sarja blogipostitus on praegu lõppenud, kuid Zigbee teekond jätkub. Eesootav maastik on teadmata, kuid usun, et autor suudab kõigiga takistusi ületada, maitseb tõuse ja mõõnu ning sellest tuleb ka edusamme.
Jääge lainel: "Liituge TI Z-Stackiga" blogipostitused!