Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 8951|Odpověď: 0

Zigbee Journey (7): Několik důležitých základních experimentů CC2430 – přenos DMA

[Kopírovat odkaz]
Zveřejněno 30.10.2014 23:22:16 | | | |
1. Propojení horní a dolní úrovně

V předchozí části jsme mluvili o použití ADC a vzorkovali teplotní senzor na čipu. V reálných projektech je počet senzorů často velký a je třeba zpracovat velké množství konverzních dat. Přesun těchto dat by CPU hodně zatěžoval. Aby se CPU uvolnil a získal energii na jiné věci, může se hodit DMA (Direct Memory Access)~

Následující úvod je úryvek z Zigbee Technology Practice Tutorial:

DMA je zkratka pro přímý přístup do paměti, což znamená "přímý přístup do paměti". Jedná se o režim vysokorychlostního přenosu dat, ve kterém periferní jednotky jako ADC/UART/RF transceivery a paměť mohou vyměňovat data přímo pod kontrolou "DMA řadiče" bez minimálního zásahu CPU. Kromě drobného zpracování na začátku a na konci přenosu dat může CPU během přenosu vykonávat i další práci. Tímto způsobem CPU a tyto datové interakce většinou fungují paralelně. Díky tomu lze celkovou účinnost systému výrazně zvýšit.

Jak je vidět z úvodu, DMA lze použít v mnoha situacích. Tento experiment zahrnuje pouze nejjednodušší přenos DMA a má za cíl demonstrovat obecné využití DMA. Pokud jde o aplikaci DMA v jiných scénářích, bude v budoucnu implementována v komplexních experimentech.

2. Experiment přenosu DMA(1) Úvod do experimentu

Postavy polesourceStringObsah je přenášen do pole znaků přes DMAdestString, výsledek konverze se zobrazuje na PC přes sériový port.

(2) Programový diagram

(3) Experimentální zdrojový kód a analýza/*
    Experimentální popis: Obsah znakového pole sourceString je přenesen do znakového pole destString přes DMA a výsledek konverze se zobrazí na PC přes sériový port.
*/

#include

#define vedl1 P1_0         
#define vedl2 P1_1         
#define vedení3 P1_2         
#define Led4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitová pole=obrácené
typedef struct
{
  nepodepsáno charSRCADDRH;           //源地址高8位
  nepodepsáno charSRCADDRL;           //源地址低8位
  nepodepsáno charDESTADDRH;         //目的地址高8位
  nepodepsáno charDESTADDRL;         //目的地址低8位
  nepodepsáno charVLEN :3;     //长度域模式选择
  nepodepsáno charLENH :5;     //传输长度高字节
  nepodepsáno charLENL :8;     //传输长度低字节
  nepodepsáno charVELIKOST SLOVA :1;     //字节(byte)或字(word)传输
  nepodepsáno charTMODE :2;     //传输模式选择
  nepodepsáno charTRIGONOMETRIE:5;     //触发事件选择
  nepodepsáno charSRCINC :2;     //源地址增量:-1/0/1/2
  nepodepsáno charDESTINC:2;     //目的地址增量:-1/0/1/2
  nepodepsáno charIRQMASK :1;     //中断屏蔽
  nepodepsáno charM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  nepodepsáno charPRIORITA :2;     //优先级
}DMA_CFG;
#pragma bitfields=výchozí

/*系统时钟初始化
-------------------------------------------------------*/
prázdnotaxtal_init(prázdnota)
{
  SPÁT &= ~0x04;            //都上电
  zatímco(! (SPÁT &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Vyberte krystalový oscilátor s frekvencí 32 MHz
  SPÁT |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
prázdnotaled_init(prázdnota)
{
  P1SEL =0x00;         P1 je běžný I/O port
  P1DIR |=0x0F;         P1.0 P1.1 P1.1 P1.2 P1.3 výstup
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
prázdnotaUart0Init(nepodepsáno charStopBits,nepodepsáno charParita)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Vyberte UART0 jako první volitelnou pozici, tedy 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(nepodepsáno chardata)
{
  zatímco(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = data;
}

/*UART0发送字符串
-------------------------------------------------------*/
prázdnotaUart0SendString(nepodepsáno char*s)
{
  zatímco(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
prázdnotamain(prázdnota)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  nepodepsáno charsourceString[]="Jsem sourceString!";      //源字符串
  nepodepsáno chardestString[velikostof(sourceString)] ="Jsem destString!";  //目的字符串
  
  chari;
  charerror=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(nepodepsáno char)((nepodepsáno int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(nepodepsáno char)((nepodepsáno int)&sourceString);
   
  dmaConfig.DESTADDRH=(nepodepsáno char)((nepodepsáno int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(nepodepsáno char)((nepodepsáno int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(nepodepsáno char)((nepodepsáno int)velikostof(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(nepodepsáno char)((nepodepsáno int)velikostof(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Žádná spoušť (lze chápat jako manuální spoušť)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(nepodepsáno char)((nepodepsáno int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(nepodepsáno char)((nepodepsáno int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  zatímco(! (DMAIRQ&0x01));               //等待传输结束
  
  pro(i=0; i <velikostof(sourceString); i++)   //校验传输的正确性
  {
    pokud(sourceString!=destString)
      error++;
  }
  
  pokud(chyba==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Správně!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  jinak
    Uart0SendString("Chyba!");

  zatímco(1);
}

Základní proces používání DMA je:Konfigurovat DMAPovolit konfiguraciZačněte převod DMA → Čekejte, až převod do DMA skončí.Následující jsou:

  (1) Konfigurovat DMA: Především musí být DMA konfigurována, ale konfigurace DMA je specifická: místo přímého přiřazování hodnot některým SFR definuje strukturu externě, přiřazuje jí hodnoty a poté přiřazuje vysokých 8 bitů první adresy této strukturyDMA0CFGH, což mu dává nižší 8 číslicDMA0CFGL。 (Pro podrobné instrukce ke struktuře konfigurace prosím viz čínský manuál CC2430)

Tipy na CC2430
Existují dva body, které je třeba upřesnit ohledně definice konfiguračních struktur ve zdrojovém kódu výše:
(1) Bitová doména
Při definování této struktury se používá mnoho dvojteček (:), následovaných číslem, které se nazývá "bitové pole":
Bitová doména znamená, že informace nemusí při ukládání zabírat celý bajt, ale pouze několik nebo jeden binární bit. Například při ukládání přepínací veličiny existují pouze dva stavy, 0 a 1, a můžete použít binární jednobitovou hodnotu. Pro úsporu úložného prostoru a usnadnění zpracování poskytuje C datovou strukturu nazývanou "bitové pole" nebo "bitové pole". Takzvané "bitové pole" rozděluje binární soubory v bajtu do několika různých oblastí a popisuje počet bitů v každé oblasti. Každá doména má doménové jméno, což umožňuje operace podle doménového jména v programu. To umožňuje reprezentovat několik různých objektů v binárním bitovém poli bajtu.
(2) Abstraktní společné funkce
Pozorní čtenáři zjistí, že přiřazení hodnoty struktuře často zahrnuje přiřazení 16bitové hodnoty neznaménkového typu int dvěma 8bitovým hodnotám neznaménkového typu char, a to následovně:
dmaConfig.SRCADDRH=(nepodepsáno char)((nepodepsáno int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(nepodepsáno char)((nepodepsáno int)&sourceString);

U tohoto typu často používané funkce bychom ji mohli stejně tak abstrahovat jako obecnou funkci, a to následovně:
#define SET_WORD(destH,destL,word)
    dělat{
       destH=(nepodepsáno char)((nepodepsáno int)slovo >>8);     
       destL=(nepodepsáno char)((nepodepsáno int)slovo);
    }zatímco(0)

V budoucnu, kdykoli budete potřebovat provést podobnou operaci rozdělení, můžete ji přímo zavolat, a to následovně:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Povolit konfiguraci: Nejprve první adresa struktury&dmaConfigVysoký/nízký 8 bitů je přiřazen k SFRDMA0CFGHaDMA0CFGL(kde 0 představuje konfiguraci kanálu 0, CC2430 obsahuje 5 DMA kanálů, kanál 0 se používá zde). AnoDMAARM.0Přiřaďte hodnotu 1, aby bylo možné nastavit kanál 0 tak, aby kanál 0 byl v pracovním režimu.

  (3) Povolit přenos DMA:VpravoDMAREQ.0Přiřaďte hodnotu 1 pro zahájení DMA přenosu kanálu 0.

  (4) Čekat na přenos DMA:Po přenosu DMA kanálu 0 bude spuštěno přerušení a příznak přerušení kanálu 0DMAIRQ.0bude automaticky nastaveno na 1. Každý znak ze dvou řetězců je poté porovnán a výsledek ověření je odeslán PC.

(4) Experimentální výsledky

Nejprve otevřete nástroj pro ladění sériových portů a pak začněte ladit CC2430, a zobrazí se následující obrazovka:

Zjistíte, žedestStringObsah byl zcela odhalensourceStringnaplněný.

Hotovo~

3. Závěr

Tato část představuje použití DMA, i když je velmi jednoduché, ale myslím, že jste pochopili základní využití DMA a můžete jej klidně analyzovat, až se v budoucnu setkáte s jeho složitými scénáři použití.

Ať je desktop jakkoliv dobrý, zamrzne, a podobně i vestavěný systém nevyhnutelně stagnuje. V následující části představíme velmi účinnou metodu systematického resetu: hlídací psy.






Předchozí:Zigbee Journey (6): Několik důležitých základních experimentů CC2430 – jednorázové vzorkování ADC
Další:Zigbee Journey (8): Několik důležitých základních experimentů CC2430 – hlídací psi
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com