|
1. Prepojenie hornej a dolnej úrovne V predchádzajúcej časti sme hovorili o použití ADC a vzorkovali sme teplotný senzor na čipe. V skutočných projektoch je počet senzorov často veľký a je potrebné spracovať veľké množstvo konverzných dát. Presúvanie týchto dát spôsobí veľkú záťaž na CPU. Aby sa CPU uvoľnil a získal energiu na iné veci, DMA (Direct Memory Access) sa môže hodiť~ Nasledujúci úvod je úryvok z Zigbee Technology Practice Tutorial: DMA je skratka pre priamy prístup do pamäte, čo znamená "priamy prístup do pamäte". Ide o vysokorýchlostný režim prenosu dát, v ktorom periférne jednotky ako ADC/UART/RF transceivery a pamäť môžu vymieňať dáta priamo pod kontrolou "DMA radiča" bez minimálneho zásahu CPU. Okrem drobného spracovania na začiatku a na konci prenosu môže CPU vykonávať aj inú prácu počas prenosu. Týmto spôsobom CPU a tieto dátové interakcie väčšinu času pracujú paralelne. Výsledkom je, že celková efektivita systému sa môže výrazne zlepšiť.
Ako vidíte z úvodu, DMA sa dá použiť v mnohých situáciách. Tento experiment zahŕňa iba najjednoduchší prenos DMA a jeho cieľom je demonštrovať všeobecné využitie DMA. Čo sa týka aplikácie DMA v iných scenároch, bude implementovaná v komplexných experimentoch v budúcnosti. 2. Experiment s prenosom DMA(1) Úvod do experimentuPostavy poľasourceStringObsah sa prenáša do poľa znakov cez DMAdestString, výsledok konverzie sa zobrazuje na PC cez sériový port. (2) Schéma toku programu
(3) Experimentálny zdrojový kód a analýza/*
Experimentálny popis: Obsah znakového poľa sourceString sa prenáša do znakového poľa destString cez DMA a výsledok konverzie sa zobrazuje na PC cez sériový port.
*/
#include
#define viedol1 P1_0
#define LED2 P1_1
#define LED3 P1_2
#define Lead4 P1_3
/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitové polia=obrátené
typedef struct
{
nepodpísané charSRCADDRH; //源地址高8位
nepodpísané charSRCADDRL; //源地址低8位
nepodpísané charDESTADDRH; //目的地址高8位
nepodpísané charDESTADDRL; //目的地址低8位
nepodpísané charVLEN :3; //长度域模式选择
nepodpísané charLENH :5; //传输长度高字节
nepodpísané charLENL:8; //传输长度低字节
nepodpísané charVEĽKOSŤ SLOVA :1; //字节(byte)或字(word)传输
nepodpísané charTMODE :2; //传输模式选择
nepodpísané charTRIG :5; //触发事件选择
nepodpísané charSRCINC :2; //源地址增量:-1/0/1/2
nepodpísané charDESTINC :2; //目的地址增量:-1/0/1/2
nepodpísané charIRQMASK :1; //中断屏蔽
nepodpísané charM8 :1; //7或8bit传输长度,仅在字节传输模式下适用
nepodpísané charPRIORITA :2; //优先级 }DMA_CFG; #pragma bitfields=default
/*系统时钟初始化
-------------------------------------------------------*/
prázdnotaxtal_init(prázdnota)
{ SPAJ &= ~0x04; //都上电
zatiaľ čo(! (SLEEP &0x40)); //晶体振荡器开启且稳定 CLKCON &= ~0x47; Vyberte 32MHz kryštálový oscilátor SPAK |=0x04;
}
/*LED初始化
-------------------------------------------------------*/
prázdnotaled_init(prázdnota)
{ P1SEL =0x00; P1 je bežný I/O port P1DIR |=0x0F; P1.0 P1.1 P1.2 P1.3 výstup
led1 =1; //关闭所有LED led2 =1; LED3 =1; LED4 =1;
}
/*UART0通信初始化
-------------------------------------------------------*/
prázdnotaUart0Init(nepodpísané charStopBits,nepodpísané charParita)
{ P0SEL |= 0x0C; //初始化UART0端口,设置P0.2与P0.3为外部设备IO口 PERCFG&= ~0x01; Vyberte UART0 ako prvú voliteľnú pozíciu, teda RXD na P0.2 a TXD na P0.3
U0CSR =0xC0; Nastavte režim UART a povolte akceptor
U0GCR =11; U0BAUD =216; //设置UART0波特率为115200bps
U0UCR |= StopBits| Parita; //设置停止位与奇偶校验
}
/*UART0发送数据
-------------------------------------------------------*/
prázdnota Uart0Send(nepodpísané chardáta)
{
zatiaľ čo(U0CSR&0x01); //等待UART空闲时发送数据 U0DBUF = dáta;
}
/*UART0发送字符串
-------------------------------------------------------*/
prázdnotaUart0SendString(nepodpísané char*s)
{
zatiaľ čo(*s !=0) //依次发送字符串s中的每个字符 Uart0Send(*s++);
}
/*主函数
-------------------------------------------------------*/
prázdnotamain(prázdnota)
{ DMA_CFG dmaConfig; //定义配置结构体
nepodpísané charsourceString[]="Som sourceString!"; //源字符串
nepodpísané chardestString[veľkosti(sourceString)] ="Ja som destString!"; //目的字符串
chari;
charerror=0;
xtal_init(); //系统时钟初始化 led_init(); Uart0Init(0x00,0x00); //UART初始化
Uart0SendString(sourceString); //传输前的原字符数组 Uart0SendString(destString); //传输前的目的字符数组
//配置DMA结构体 dmaConfig.SRCADDRH=(nepodpísané char)((nepodpísané int)&sourceString >>8); //源地址 dmaConfig.SRCADDRL=(nepodpísané char)((nepodpísané int)&sourceString);
dmaConfig.DESTADDRH=(nepodpísané char)((nepodpísané int)&destString >>8); //目的地址 dmaConfig.DESTADDRL=(nepodpísané char)((nepodpísané int)&destString);
dmaConfig.VLEN=0x00; //选择LEN作为传送长度
dmaConfig.LENH=(nepodpísané char)((nepodpísané int)veľkosti(sourceString) >>8); //传输长度 dmaConfig.LENL=(nepodpísané char)((nepodpísané int)veľkosti(sourceString));
dmaConfig.WORDSIZE=0x00; //选择字节(byte)传送
dmaConfig.TMODE=0x01; //选择块传送(block)模式
dmaConfig.TRIG=0; Bez spúšte (dá sa to chápať ako manuálne spúšťanie)
dmaConfig.SRCINC=0x01; //源地址增量为1
dmaConfig.DESTINC=0x01; //目的地址增量为1
dmaConfig.IRQMASK=0; //DMA中断屏蔽
dmaConfig.M8=0x00; //选择8位长的字节来传送数据
dmaConfig.PRIORITY=0x02; //传输优先级为高
DMA0CFGH=(nepodpísané char)((nepodpísané int)&dmaConfig >>8); //将配置结构体的首地址赋予相关SFR DMA0CFGL=(nepodpísané char)((nepodpísané int)&dmaConfig);
DMAARM=0x01; //启用配置
DMAIRQ=0x00; //清中断标志 DMAREQ=0x01; //启动DMA传输
zatiaľ čo(! (DMAIRQ&0x01)); //等待传输结束
pre(i=0; i <veľkosti(sourceString); i++) //校验传输的正确性 {
ak(sourceString!=destString) error++; }
ak(error==0) //将结果通过串口传输到PC { Uart0SendString("Správne!"); Uart0SendString(destString); //传输后的目的字符数组 }
else Uart0SendString("Chyba!");
zatiaľ čo(1);
}
Základný proces používania DMA je:Konfigurácia DMA → Povoliť konfiguráciu → Začnite prevod DMA → Čakajte, kým sa prevod DMA skončí.Nasledujúce sú: (1) Konfigurácia DMA: V prvom rade musí byť DMA nakonfigurované, ale konfigurácia DMA je špeciálna: namiesto priameho priraďovania hodnôt niektorým SFR definuje štruktúru externe, priraďuje jej hodnoty a potom priraďuje vysokých 8 bitov prvej adresy tejto štruktúryDMA0CFGH, čo mu dáva dolných 8 číslicDMA0CFGL。 (Pre podrobné inštrukcie v konfiguračnej štruktúre, prosím, pozrite si čínsky manuál CC2430) Tipy na CC2430Existujú dva body, ktoré treba objasniť ohľadom definície konfiguračných štruktúr v zdrojovom kóde vyššie: (1) Bitová doména Pri definovaní tejto štruktúry sa používa veľa dvojbodiek (:), nasledovaných číslom, ktoré sa nazýva "bitové pole": Bitová doména znamená, že informácie nemusia pri ukladaní zaberať celý bajt, ale iba niekoľko alebo jeden binárny bit. Napríklad pri ukladaní prepínacej veličiny existujú len dva stavy, 0 a 1, a môžete použiť jednobitový binárny systém. Aby sa ušetrilo miesto na pamäti a uľahčilo spracovanie, C poskytuje dátovú štruktúru nazývanú "bitové pole" alebo "bitové pole". Takzvané "bitové pole" rozdeľuje binárne súbory v bajte na niekoľko rôznych oblastí a popisuje počet bitov v každej oblasti. Každá doména má doménové meno, ktoré umožňuje operácie podľa doménového mena v programe. To umožňuje reprezentovať niekoľko rôznych objektov v bajtovom binárnom bitovom poli. (2) Abstraktné spoločné funkcie Pozorní čitatelia zistia, že priradenie hodnoty štruktúre často zahŕňa priradenie 16-bitovej hodnoty neznamienkového typu int dvom 8-bitovým hodnotám neznamienkového typu znaku, a to nasledovne: dmaConfig.SRCADDRH=(nepodpísané char)((nepodpísané int)&sourceString >>8); //源地址 dmaConfig.SRCADDRL=(nepodpísané char)((nepodpísané int)&sourceString);
Pre tento typ často používanej funkcie by sme ju mohli rovnako abstrahovať ako všeobecnú funkciu, nasledovne: #define SET_WORD(destH,destL,word)
robiť{ destH=(nepodpísané char)((nepodpísané int)slovo >>8); destL=(nepodpísané char)((nepodpísané int)slovo); }zatiaľ čo(0)
V budúcnosti, kedykoľvek budete potrebovať vykonať podobnú operáciu delenia, môžete ju zavolať priamo, nasledovne: SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);
(2) Povoliť konfiguráciu: Najprv prvá adresa štruktúry&dmaConfigNajvyšších/nízkych 8 bitov je priradených k SFRDMA0CFGHaDMA0CFGL(kde 0 predstavuje konfiguráciu pre kanál 0, CC2430 obsahuje 5 DMA kanálov, kanál 0 sa používa tu). ÁnoDMAARM.0Priraďte hodnotu 1, aby ste umožnili konfiguráciu kanála 0 tak, aby bol kanál 0 v pracovnom režime. (3) Povoliť prenos DMA:DopravaDMAREQ.0Priraďte hodnotu 1 na začatie DMA prenosu kanála 0. (4) Čakať na odoslanie DMA:Po odoslaní DMA kanála 0 sa spustí prerušenie a spustí sa príznak prerušenia kanála 0DMAIRQ.0sa automaticky nastaví na 1. Každý znak z týchto dvoch reťazcov sa potom porovná a výsledok overenia sa odošle PC. (4) Experimentálne výsledkyNajprv otvorte nástroj na ladenie sériových portov a potom začnite ladiť CC2430, a zobrazí sa nasledujúca obrazovka:
Zistíš, žedestStringObsah bol úplne odhalenýsourceStringnaplnené. Hotovo~ 3. ZáverTáto časť predstavuje použitie DMA, hoci je veľmi jednoduché, ale myslím, že ste pochopili základné použitie DMA a môžete ho pokojne analyzovať, keď sa v budúcnosti stretnete s jeho zložitými scenármi použitia. Nezáleží na tom, aký dobrý je desktop, zamrzne, a podobne zabudovaný systém nevyhnutne stagnuje. V ďalšej časti predstavíme veľmi efektívnu metódu systematického resetu: strážcov.
|