Ez a cikk egy tükör gépi fordítás, kérjük, kattintson ide, hogy ugorjon az eredeti cikkre.

Nézet: 8951|Válasz: 0

Zigbee Journey (7): Több fontos CC2430 alap kísérlet – DMA átvitel

[Linket másol]
Közzétéve 2014. 10. 30. 23:22:16 | | | |
1. A felső és alsó szintek összekapcsolása

Az előző részben az ADC-k használatáról beszéltünk, és mintáztuk a chipen belüli hőmérséklet-érzékelőt. A tényleges projektekben gyakran nagy az érzékelők száma, és nagy mennyiségű átalakító adatot kell feldolgozni. Az adatok mozgatása nagy terhet ró a CPU-ra. Ahhoz, hogy felszabadítsa a CPU-t és energiát adjon más dolgokra, a DMA (Direct Memory Access) hasznos lehet~

Az alábbi bevezető a Zigbee Technológiai Gyakorlati Tutorialból származik:

A DMA a közvetlen memóriahozzáférés rövidítése, ami "közvetlen memória-hozzáférés" (direct memory access). Ez egy nagy sebességű adatátviteli mód, amelyben perifériás egységek, mint az ADC/UART/RF adóvevők és a memória közvetlenül a "DMA vezérlő" irányítása alatt cserélhetnek adatokat, kevés CPU beavatkozás nélkül. Az adatátvitel elején és végén végzett némi feldolgozáson túl a CPU más munkát is végezhet az átvitel során. Így a CPU és ezek az adatinterakciók többnyire párhuzamosan működnek. Ennek eredményeként a rendszer általános hatékonysága jelentősen javítható.

Ahogy a bevezetőből is láthatod, a DMA sok esetben használható. Ez a kísérlet csak a legegyszerűbb DMA átvitelt foglalja magában, és célja a DMA általános alkalmazásának bemutatása. A DMA alkalmazása más forgatókönyvekben a jövőben átfogó kísérletekben fog alkalmazni.

2. DMA átviteli kísérlet(1) Bevezetés a kísérlethez

TömbszereplőksourceStringA tartalmat DMA segítségével továbbítják a karaktertömbbedestString, az átalakítási eredmény a PC-n a soros porton keresztül jelenik meg.

(2) Programáram

(3) Kísérleti forráskód és elemzés/*
    Kísérleti leírás: A sourceString karaktertömbének tartalma DMA-n keresztül kerül át a destString karaktertömbbe, és az átalakítási eredmény a PC-n jelenik meg a soros porton keresztül.
*/

#include

#define lead1 P1_0         
#define led2 P1_1         
#define lead3 P1_2         
#define lead4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitmezők=fordítva
typedef szerkezet
{
  Aláírás nélkül charSRCADDRH;           //源地址高8位
  Aláírás nélkül charSRCADDRL;           //源地址低8位
  Aláírás nélkül charDESTADDRH;         //目的地址高8位
  Aláírás nélkül charDESTADDRL;         //目的地址低8位
  Aláírás nélkül charVLEN :3;     //长度域模式选择
  Aláírás nélkül charLENH :5;     //传输长度高字节
  Aláírás nélkül charLENL :8;     //传输长度低字节
  Aláírás nélkül charSZÓMÉRET:1;     //字节(byte)或字(word)传输
  Aláírás nélkül charTMODE :2;     //传输模式选择
  Aláírás nélkül charTRIG :5;     //触发事件选择
  Aláírás nélkül charSRCINC :2;     //源地址增量:-1/0/1/2
  Aláírás nélkül charDESTINC :2;     //目的地址增量:-1/0/1/2
  Aláírás nélkül charIRQMASK :1;     //中断屏蔽
  Aláírás nélkül charM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  Aláírás nélkül charPRIORITÁS :2;     //优先级
}DMA_CFG;
#pragma bitmezők=alapértelmezett

/*系统时钟初始化
-------------------------------------------------------*/
Semmixtal_init(Semmi)
{
  ALVÁS &= ~0x04;            //都上电
  miközben(! (ALVÁS &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Válassz egy 32 MHz-es kristályoscillátort
  ALVÁS |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
Semmiled_init(Semmi)
{
  P1SEL =0x00;         A P1 a normál I/O port
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3 kimenet
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
SemmiUart0Init(Aláírás nélkül charStopBits,Aláírás nélkül charParity)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Válaszd az UART0-t az első opcionális pozíciónak, vagyis az RXD-től P0.2-ig, TXD-től P0.3-ig
   
   U0CSR =0xC0;                    Állítsd UART módra, és kapcsold be az akszuctort
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Parititás;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
Semmi  Uart0Send(Aláírás nélkül charadatok)
{
  miközben(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = adat;
}

/*UART0发送字符串
-------------------------------------------------------*/
SemmiUart0SendString(Aláírás nélkül char*s)
{
  miközben(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
Semmimain(Semmi)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  Aláírás nélkül charsourceString[]="Én vagyok a sourceString!";      //源字符串
  Aláírás nélkül chardestString[mérete(sourceString)] ="Én vagyok a végzősString!";  //目的字符串
  
  chari;
  charerror=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(Aláírás nélkül char)((Aláírás nélkül int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(Aláírás nélkül char)((Aláírás nélkül int)&sourceString);
   
  dmaConfig.DESTADDRH=(Aláírás nélkül char)((Aláírás nélkül int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(Aláírás nélkül char)((Aláírás nélkül int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(Aláírás nélkül char)((Aláírás nélkül int)mérete(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(Aláírás nélkül char)((Aláírás nélkül int)mérete(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Nincs trigger (érthető, mint kézi trigger-ezés)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(Aláírás nélkül char)((Aláírás nélkül int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(Aláírás nélkül char)((Aláírás nélkül int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  miközben(! (DMAIRQ&0x01));               //等待传输结束
  
  for(i=0; i <mérete(sourceString); i++)   //校验传输的正确性
  {
    ha(sourceString!=destString)
      hiba++;
  }
  
  ha(hiba==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Így van!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  más
    Uart0SendString("Hiba!");

  miközben(1);
}

A DMA használatának alapvető folyamata a következő:Konfiguráld a DMA-tBeállítás engedélyezéseKezdd el a DMA átadást → Várd meg, amíg a DMA átadás befejeződik.Az alábbiak rendre következnek:

  (1) A DMA konfigurálása: Először is, a DMA-t konfigurálni kell, de a DMA konfigurációja különleges: ahelyett, hogy közvetlenül az SFR-ekhez osztana meg értékeket, kívülről definiál egy struktúrát, értékeket rendel hozzá, majd az első cím 8 bitjét rendeli hozzáDMA0CFGH, így alacsonyabb 8 számjegyet adDMA0CFGL。 (A konfigurációs szerkezet részletes utasításaiért kérjük, tekintse meg a CC2430 kínai kézikönyvet)

CC2430 tippek
Két pontot kell tisztázni a konfigurációs struktúrák definifikációjával kapcsolatban a fenti forráskódban:
(1) Bittartomány
Ennek a szerkezetnek a meghatározásához sok oszlopot (:) használnak, majd egy számot, amit "bitmezőnek" neveznek:
A bitdomén azt jelenti, hogy az információ tároláskor nem kell teljes bájtot elfoglalnia, hanem csak néhány vagy egy bináris bitet foglal el. Például, amikor egy kapcsoló mennyiséget tárolunk, csak két állapot van, 0 és 1, és használható egy bites bináris. A tárolóhely megtakarítása és a feldolgozás megkönnyítése érdekében C egy adatstruktúrát biztosít, amit "bitmezőnek" vagy "bitmezőnek" neveznek. Az úgynevezett "bitmező" a bájtban lévő binárokat több különböző régióra osztja, és leírja az egyes régiókban lévő bitek számát. Minden domainnek van domain neve, ami lehetővé teszi a programban a doménnév szerinti műveleteket. Ez lehetővé teszi, hogy több különböző objektumot ábrázoljanak egy bájtos bináris bitmezőben.
(2) Absztrakt közös függvények
A figyelmes olvasók azt tapasztalják, hogy egy szerkezethez való érték hozzárendelése gyakran azt jelenti, hogy egy 16 bites, nem aláírt int típusú értéket kell két 8 bites alárendeletlen karakter típus értékhez rendelni, az alábbiak szerint:
dmaConfig.SRCADDRH=(Aláírás nélkül char)((Aláírás nélkül int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(Aláírás nélkül char)((Aláírás nélkül int)&sourceString);

Ezen a típusú, gyakran használt függvény esetén akár általános függvényként is elvonhatjuk, az alábbiakban:
#define SET_WORD(destH,destL,szó)
    csinál{
       destH=(Aláírás nélkül char)((Aláírás nélkül int)szó >>8);     
       destL=(Aláírás nélkül char)((Aláírás nélkül int)szó);
    }miközben(0)

A jövőben, amikor hasonló splittési műveletet kell végrehajtani, közvetlenül hívhatod az alábbiakkal:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Beállítás engedélyezése: Először a szerkezet első címe&dmaConfigA magas/alacsony 8 bitet SFR-hez rendelikDMA0CFGHésDMA0CFGL(ahol 0 a 0-as csatorna konfigurációját jelöli, a CC2430 5 DMA csatornát tartalmaz, itt a 0-as csatornát használják). IgenDMAARM.0Rendelj 1-es értéket, hogy engedélyezd a 0-as csatorna konfigurálását, hogy a 0-as csatorna munkamódban legyen.

  (3) Engedélyezze a DMA átvitelt:JobbraDMAREQ.0Rendelj 1-es értéket a 0-as csatorna DMA adásának megindításához.

  (4) Várjuk meg, amíg a DMA továbbításra kerül:Miután a 0-as csatorna DMA-ját továbbították, a megszakítás aktiválódik, és az 0-as csatorna megszakítási zászlója is aktiválódikDMAIRQ.0automatikusan 1-re lesz állítva. A két karakterlánc minden karakterét összehasonlítják, és az ellenőrző eredményt elküldik a PC-nek.

(4) Kísérleti eredmények

Először nyisd meg a soros port hibakereső eszközt, majd indítsd el a CC2430 hibakeresést, és a következő képernyő jelenik meg:

Meg fogod találnidestStringA tartalom teljesen feltárultsourceStringtele vagyok.

Kész~

3. Következtetés

Ez a rész bemutatja a DMA használatát, bár nagyon egyszerű, de úgy gondolom, megértetted a DMA alapvető használatát, és nyugodtan elemezheted, amikor a jövőben bonyolult használati helyzetekkel találkozunk.

Bármilyen jó is egy asztali gép, lefagy, és hasonlóan egy beágyazott rendszer elkerülhetetlenül stagnál. A következő részben bemutatunk egy nagyon hatékony rendszerszintű újraindítási módszert: a watchdogokat.






Előző:Zigbee Journey (6): Több fontos CC2430 alapkísérlet – ADC egy-egy mintavétel
Következő:Zigbee Journey (8): Több fontos CC2430 alapkísérlet – őrkutyák
Lemondás:
A Code Farmer Network által közzétett összes szoftver, programozási anyag vagy cikk kizárólag tanulási és kutatási célokra szolgál; A fenti tartalmat nem szabad kereskedelmi vagy illegális célokra használni, különben a felhasználók viselik az összes következményet. Az oldalon található információk az internetről származnak, és a szerzői jogi vitáknak semmi köze ehhez az oldalhoz. A fenti tartalmat a letöltés után 24 órán belül teljesen törölni kell a számítógépéről. Ha tetszik a program, kérjük, támogassa a valódi szoftvert, vásároljon regisztrációt, és szerezzen jobb hiteles szolgáltatásokat. Ha bármilyen jogsértés történik, kérjük, vegye fel velünk a kapcsolatot e-mailben.

Mail To:help@itsvse.com