|
1. Ylä- ja alakerrosten yhdistäminen Edellisessä osiossa keskustelimme ADC-laitteiden käytöstä ja otimme näytteitä sirun sisäisestä lämpötila-anturista. Varsinaisissa projekteissa antureiden määrä on usein suuri ja suuri määrä muunnosdataa täytyy käsitellä. Tämän datan siirtäminen rasittaa prosessoria paljon. Prosessorin vapauttamiseksi ja energian antamiseksi muihin asioihin DMA (Direct Memory Access) voi olla hyödyllinen~ Seuraava johdanto on ote Zigbee Technology Practice Tutorialista: DMA on lyhenne suorasta muistin käytöstä, eli "suora muistikäyttö". Tämä on nopea tiedonsiirtotila, jossa oheisyksiköt, kuten ADC/UART/RF-lähettimet ja muisti, voivat vaihtaa dataa suoraan "DMA-ohjaimen" ohjauksessa ilman vähäistä suorittimen puuttumista. Prosessori voi tehdä hieman käsittelyä tiedonsiirron alussa ja lopussa, mutta myös muuta työtä siirron aikana. Näin prosessori ja nämä datan vuorovaikutukset toimivat useimmiten rinnakkain. Tämän seurauksena järjestelmän kokonaistehokkuutta voidaan merkittävästi parantaa.
Kuten johdannosta näkyy, DMA:ta voi käyttää monissa tilanteissa. Tämä koe sisältää vain yksinkertaisimman DMA-siirron ja pyrkii osoittamaan DMA:n yleisen käytön. Mitä tulee DMA:n soveltamiseen muissa skenaarioissa, sitä tullaan toteuttamaan laajoissa kokeissa tulevaisuudessa. 2. DMA-siirtokokeilu(1) Johdanto kokeeseenTaulukon merkitsourceStringSisältö siirretään hahmotaulukkoon DMA:n kauttadestString, muunnostulos näytetään PC:llä sarjaportin kautta. (2) Ohjelman vuokaavio
(3) Kokeellinen lähdekoodi ja analyysi/*
Kokeellinen kuvaus: Merkkitaulukon sourceStringin sisältö siirretään DMA:n kautta destStringiin, ja muunnostulos näytetään PC:llä sarjaportin kautta.
*/
#include
#define johti1 P1_0
#define led2 P1_1
#define johti 3 P1_2
#define johti 4 P1_3
/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bittikentät=käännetty
typedef rakenne
{
Allekirjoittamaton charSRCADDRH; //源地址高8位
Allekirjoittamaton charSRCADDRL; //源地址低8位
Allekirjoittamaton charDESTADDRH; //目的地址高8位
Allekirjoittamaton charDESTADDRL; //目的地址低8位
Allekirjoittamaton charVLEN :3; //长度域模式选择
Allekirjoittamaton charLENH :5; //传输长度高字节
Allekirjoittamaton charLENL :8; //传输长度低字节
Allekirjoittamaton charSANAKOKO :1; //字节(byte)或字(word)传输
Allekirjoittamaton charTMODE :2; //传输模式选择
Allekirjoittamaton charTRIG :5; //触发事件选择
Allekirjoittamaton charSRCINC :2; //源地址增量:-1/0/1/2
Allekirjoittamaton charDESTINC :2; //目的地址增量:-1/0/1/2
Allekirjoittamaton charIRQMASK :1; //中断屏蔽
Allekirjoittamaton charM8 :1; //7或8bit传输长度,仅在字节传输模式下适用
Allekirjoittamaton charPRIORITEETTI :2; //优先级 }DMA_CFG; #pragma bittikentät=oletus
/*系统时钟初始化
-------------------------------------------------------*/
voidxtal_init(void)
{ UNI &= ~0x04; //都上电
kun(! (UNI &0x40)); //晶体振荡器开启且稳定 CLKCON &= ~0x47; Valitse 32MHz:n kideoskillaattori UNI |=0x04;
}
/*LED初始化
-------------------------------------------------------*/
voidled_init(void)
{ P1SEL =0x00; P1 on tavallinen I/O-portti P1DIR |=0x0F; P1.0 P1.1 P1.2 P1.3 ulostulo
led1 =1; //关闭所有LED led2 =1; led3 =1; led4 =1;
}
/*UART0通信初始化
-------------------------------------------------------*/
voidUart0Init(Allekirjoittamaton charStopBits,Allekirjoittamaton charParity)
{ P0SEL |= 0x0C; //初始化UART0端口,设置P0.2与P0.3为外部设备IO口 PERCFG&= ~0x01; Valitse UART0 ensimmäiseksi valinnaiseksi paikaksi, eli RXD:stä P0.2:een ja TXD:stä P0.3:een
U0CSR =0xC0; Aseta UART-tilaan ja ota vastaanotin käyttöön
U0GCR =11; U0BAUD =216; //设置UART0波特率为115200bps
U0UCR |= StopBits| Tasavertaisuus; //设置停止位与奇偶校验
}
/*UART0发送数据
-------------------------------------------------------*/
void Uart0Send(Allekirjoittamaton chardata)
{
kun(U0CSR&0x01); //等待UART空闲时发送数据 U0DBUF = data;
}
/*UART0发送字符串
-------------------------------------------------------*/
voidUart0SendString(Allekirjoittamaton char*s)
{
kun(*s !=0) //依次发送字符串s中的每个字符 Uart0Send(*s++);
}
/*主函数
-------------------------------------------------------*/
voidpää(void)
{ DMA_CFG dmaConfig; //定义配置结构体
Allekirjoittamaton charsourceString[]="Minä olen lähdeString!"; //源字符串
Allekirjoittamaton chardestString[koon(sourceString)] ="Minä olen destString!"; //目的字符串
chari;
charerror=0;
xtal_init(); //系统时钟初始化 led_init(); Uart0Init(0x00,0x00); //UART初始化
Uart0SendString(sourceString); //传输前的原字符数组 Uart0SendString(destString); //传输前的目的字符数组
//配置DMA结构体 dmaConfig.SRCADDRH=(Allekirjoittamaton char)((Allekirjoittamaton int)&sourceString >>8); //源地址 dmaConfig.SRCADDRL=(Allekirjoittamaton char)((Allekirjoittamaton int)&sourceString);
dmaConfig.DESTADDRH=(Allekirjoittamaton char)((Allekirjoittamaton int)&destString >>8); //目的地址 dmaConfig.DESTADDRL=(Allekirjoittamaton char)((Allekirjoittamaton int)&destString);
dmaConfig.VLEN=0x00; //选择LEN作为传送长度
dmaConfig.LENH=(Allekirjoittamaton char)((Allekirjoittamaton int)koon(sourceString) >>8); //传输长度 dmaConfig.LENL=(Allekirjoittamaton char)((Allekirjoittamaton int)koon(sourceString));
dmaConfig.WORDSIZE=0x00; //选择字节(byte)传送
dmaConfig.TMODE=0x01; //选择块传送(block)模式
dmaConfig.TRIG=0; Ei liipaisinta (voidaan ymmärtää manuaaliseksi laukaisuksi)
dmaConfig.SRCINC=0x01; //源地址增量为1
dmaConfig.DESTINC=0x01; //目的地址增量为1
dmaConfig.IRQMASK=0; //DMA中断屏蔽
dmaConfig.M8=0x00; //选择8位长的字节来传送数据
dmaConfig.PRIORITY=0x02; //传输优先级为高
DMA0CFGH=(Allekirjoittamaton char)((Allekirjoittamaton int)&dmaConfig >>8); //将配置结构体的首地址赋予相关SFR DMA0CFGL=(Allekirjoittamaton char)((Allekirjoittamaton int)&dmaConfig);
DMAARM=0x01; //启用配置
DMAIRQ=0x00; //清中断标志 DMAREQ=0x01; //启动DMA传输
kun(! (DMAIRQ&0x01)); //等待传输结束
for(i=0; i <koon(sourceString); i++) //校验传输的正确性 {
jos(sourceString!=destString) virhe++; }
jos(virhe==0) //将结果通过串口传输到PC { Uart0SendString("Oikein!"); Uart0SendString(destString); //传输后的目的字符数组 }
else Uart0SendString("Virhe!");
kun(1);
}
DMA:n perusprosessi on:Määritä DMA → Ota konfiguraatio käyttöön → Aloita DMA-siirto → Odota, että DMA-siirto valmistuu.Seuraavat ovat asianmukaisesti: (1) Määritä DMA: Ensinnäkin DMA täytyy konfiguroida, mutta DMA:n konfiguraatio on erityinen: sen sijaan, että arvoja annetaan suoraan joillekin SFR:ille, se määrittelee rakenteen ulkoisesti, antaa sille arvot ja sitten määrittää tämän rakenteen ensimmäisen osoitteen korkeat 8 bittiäDMA0CFGH, mikä antaa sille alemman 8 numeronDMA0CFGL。 (Yksityiskohtaiset ohjeet konfiguraatiorakenteesta löydät CC2430:n kiinan käsikirjasta) CC2430-vinkitOn kaksi seikkaa, jotka on selvennettävä konfiguraatiorakenteiden määritelmästä yllä olevassa lähdekoodissa: (1) Bittidomeeni Kun tätä rakennetta määritellään, käytetään paljon kaksoispisteitä (:), joita seuraa numero, jota kutsutaan "bittikentäksi": Bittialue tarkoittaa, että tiedon ei tarvitse täyttää täyttä tavua tallennetessa, vaan se vie vain muutaman tai yhden binääribitin. Esimerkiksi, kun tallennetaan kytkentäsuure, on vain kaksi tilaa, 0 ja 1, ja voit käyttää yhtä bittibinääriä. Tallennustilan säästämiseksi ja prosessoinnin helpottamiseksi C tarjoaa tietorakenteen nimeltä "bittikenttä" tai "bittikenttä". Niin sanottu "bittikenttä" jakaa tavun binäärit useisiin eri alueisiin ja kuvaa kunkin alueen bittien määrää. Jokaisella verkkotunnuksella on verkkotunnus, mikä mahdollistaa ohjelmassa toiminnannimen perusteella tehtävät toiminnot. Tämä mahdollistaa useiden eri olioiden esittämisen tavun binääribittikentässä. (2) Abstraktit yhteiset funktiot Tarkkaavaiset lukijat huomaavat, että arvon antaminen rakenteelle tarkoittaa usein 16-bittisen allekirjoittamattoman int-tyypin arvon antamista kahdelle 8-bittiselle allekirjoittamattomalle hahmotyypille seuraavasti: dmaConfig.SRCADDRH=(Allekirjoittamaton char)((Allekirjoittamaton int)&sourceString >>8); //源地址 dmaConfig.SRCADDRL=(Allekirjoittamaton char)((Allekirjoittamaton int)&sourceString);
Tälle usein käytetylle funktiotyypille voimme yhtä hyvin abstrahoida sen yleiseksi funktioksi seuraavasti: #define SET_WORD(destH,destL,sana)
tehdä{ destH=(Allekirjoittamaton char)((Allekirjoittamaton int)sana >>8); destL=(Allekirjoittamaton char)((Allekirjoittamaton int)sana); }kun(0)
Tulevaisuudessa, aina kun tarvitset vastaavan jakamistoiminnon, voit kutsua sitä suoraan seuraavasti: SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);
(2) Ota konfigurointi käyttöön: Ensiksi rakenteen ensimmäinen osoite&dmaConfigYlä- ja matalat 8-bitit on määritetty SFR:lle vastaavastiDMA0CFGHjaDMA0CFGL(missä 0 edustaa kanavan 0 konfiguraatiota, CC2430 sisältää 5 DMA-kanavaa, kanavaa 0 käytetään tässä). KylläDMAARM.0Aseta arvoksi 1, jotta kanava 0 voidaan konfiguroida niin, että kanava 0 toimii toimintatilassa. (3) Ota DMA-lähetys käyttöön:OikeaDMAREQ.0Anna arvoksi 1 aloittaaksesi kanavan 0 DMA-lähetyksen. (4) Odota, että DMA lähetetään:Kun kanavan 0 DMA on lähetetty, keskeytys käynnistyy ja kanavan 0 keskeytyslippu laukeaaDMAIRQ.0asetetaan automaattisesti arvoon 1. Jokaista merkkijonon merkkiä verrataan ja vahvistustulos lähetetään PC:lle. (4) Kokeelliset tuloksetAvaa ensin sarjaportin virheenkorjaustyökalu ja aloita CC2430:n virheenkorjaus, jolloin seuraava näyttö ilmestyy:
Tulet löytämäändestStringSisältö on täysin paljastettusourceStringtäynnä. Valmista~ 3. JohtopäätösTässä osiossa esitellään DMA:n käyttö, vaikka se onkin hyvin yksinkertainen, mutta uskon, että olet ymmärtänyt DMA:n peruskäytön, ja voit myös analysoida sitä rauhallisesti, kun kohtaat sen monimutkaisia käyttötilanteita tulevaisuudessa. Ei ole väliä kuinka hyvä työpöytä on, se jäätyy, ja vastaavasti sulautettu järjestelmä jää väistämättä paikoilleen. Seuraavassa osiossa esittelemme erittäin tehokkaan systemaattisen nollausmenetelmän: vahtikoirat.
|