Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 8951|Antwoord: 0

Zigbee Journey (7): Verschillende belangrijke CC2430 basisexperimenten - DMA-transmissie

[Link kopiëren]
Geplaatst op 30-10-2014 23:22:16 | | | |
1. Het verbinden van de boven- en benedenverdiepingen

In de vorige sectie bespraken we het gebruik van ADC's en namen we een monster van de on-chip temperatuursensor. In daadwerkelijke projecten is het aantal sensoren vaak groot en moet er een grote hoeveelheid conversiegegevens worden verwerkt. Het verplaatsen van deze data zal veel druk op de CPU leggen. Om de CPU vrij te maken en energie te geven voor andere dingen, kan DMA (Direct Memory Access) handig zijn~

De volgende inleiding is een fragment uit de Zigbee Technology Practice Tutorial:

DMA is een afkorting voor directe geheugentoegang, wat "directe geheugentoegang" betekent. Dit is een hogesnelheidsdatatransmissiemodus waarbij randapparatuur zoals ADC/UART/RF-transceivers en geheugen gegevens direct kan uitwisselen onder controle van de "DMA-controller" zonder weinig CPU-interventie. Naast het aan het begin en einde van de data-overdracht wat verwerking kan de CPU ook ander werk doen tijdens de overdracht. Op deze manier werken de CPU en deze data-interacties meestal parallel. Hierdoor kan de algehele efficiëntie van het systeem aanzienlijk worden verbeterd.

Zoals je uit de inleiding kunt zien, kan DMA in veel situaties worden gebruikt. Dit experiment omvat slechts de eenvoudigste DMA-overdracht en heeft als doel het algemene gebruik van DMA aan te tonen. Wat betreft de toepassing van DMA in andere scenario's, zal het in de toekomst worden toegepast in uitgebreide experimenten.

2. DMA-transmissie-experiment(1) Inleiding tot het experiment

Array-personagesbronStringDe inhoud wordt via DMA naar de karakterarray overgedragendestString, wordt het conversieresultaat op de pc weergegeven via de seriële poort.

(2) Programmastroomdiagram

(3) Experimentele broncode en analyse/*
    Experimentele beschrijving: De inhoud van de character array sourceString wordt via DMA overgezet naar de character array destString, en het conversieresultaat wordt op de pc weergegeven via de seriële poort.
*/

#include

#define led1 P1_0         
#define led2 P1_1         
#define led3 P1_2         
#define led4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitvelden=omgekeerd
typedef struct
{
  Onondertekend charSRCADDRH;           //源地址高8位
  Onondertekend charSRCADDRL;           //源地址低8位
  Onondertekend charDESTADDRH;         //目的地址高8位
  Onondertekend charDESTADDRL;         //目的地址低8位
  Onondertekend charVLEN:3;     //长度域模式选择
  Onondertekend charLENH :5;     //传输长度高字节
  Onondertekend charLENL :8;     //传输长度低字节
  Onondertekend charWOORDGROOTTE:1;     //字节(byte)或字(word)传输
  Onondertekend charTMODE :2;     //传输模式选择
  Onondertekend charTRIG:5;     //触发事件选择
  Onondertekend charSRCINC :2;     //源地址增量:-1/0/1/2
  Onondertekend charDESTINC :2;     //目的地址增量:-1/0/1/2
  Onondertekend charIRQMASK :1;     //中断屏蔽
  Onondertekend charM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  Onondertekend charPRIORITEIT:2;     //优先级
}DMA_CFG;
#pragma bitvelden=standaard

/*系统时钟初始化
-------------------------------------------------------*/
leegtextal_init(leegte)
{
  SLAAP &= ~0x04;            //都上电
  terwijl(! (SLAAP &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Kies een 32MHz kristaloscillator.
  SLAAP |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
leegteled_init(leegte)
{
  P1SEL =0x00;         P1 is de normale I/O-poort
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3 uitgang
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
leegteUart0Init(Onondertekend charStopBits,Onondertekend charPariteit)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Selecteer UART0 als eerste optionele positie, dat wil zeggen, RXD naar P0.2 en TXD naar P0.3
   
   U0CSR =0xC0;                    Zet hem op UART-modus en schakel de acceptor in
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Pariteit;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
leegte  Uart0Send(Onondertekend chargegevens)
{
  terwijl(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = data;
}

/*UART0发送字符串
-------------------------------------------------------*/
leegteUart0SendString(Onondertekend char*s)
{
  terwijl(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
leegtehoofd(leegte)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  Onondertekend charsourceString[]="Ik ben de sourceString!";      //源字符串
  Onondertekend chardestString[Sizeof(sourceString)] ="Ik ben de destString!";  //目的字符串
  
  charIk;
  charfout=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString (sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(Onondertekend char)((Onondertekend int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(Onondertekend char)((Onondertekend int)&sourceString);
   
  dmaConfig.DESTADDRH=(Onondertekend char)((Onondertekend int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(Onondertekend char)((Onondertekend int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(Onondertekend char)((Onondertekend int)Sizeof(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(Onondertekend char)((Onondertekend int)Sizeof(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Geen trigger (kan worden opgevat als handmatig triggeren)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(Onondertekend char)((Onondertekend int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(Onondertekend char)((Onondertekend int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  terwijl(! (DMAIRQ&0x01));               //等待传输结束
  
  voor(i=0; Ik <Sizeof(sourceString); i++)   //校验传输的正确性
  {
    als(sourceString)!=destString)
      fout++;
  }
  
  als(fout==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Correct!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  anders
    Uart0SendString("Fout!");

  terwijl(1);
}

Het basisproces van het gebruik van DMA is:Configureer DMAConfiguratie inschakelenBegin met de DMA-overdracht → Wacht tot de DMA-overdracht klaar is.De volgende zijn respectievelijk:

  (1) DMA configureren: Allereerst moet DMA worden geconfigureerd, maar de configuratie van DMA is speciaal: in plaats van direct waarden toe te wijzen aan sommige SFR's, definieert het een structuur extern, wijst waarden toe, en wijst vervolgens de hoge 8 bits van het eerste adres van deze structuur toeDMA0CFGH, wat het een lagere 8 cijfers geeft, wat hem een lagere 8 cijfers geeftDMA0CFGL。 (Voor gedetailleerde instructies in de configuratiestructuur, zie de CC2430 Chinese handleiding)

CC2430 Tips
Er zijn twee punten die verduidelijkt moeten worden over de definitie van configuratiestructuren in de broncode hierboven:
(1) Bitdomein
Bij het definiëren van deze structuur worden veel dubbele punten (:)) gebruikt, gevolgd door een getal dat "bitveld" wordt genoemd:
Bitdomein betekent dat informatie niet een volledige byte hoeft te beslaan wanneer opgeslagen, maar slechts een paar of één binaire bit bezet. Bijvoorbeeld, bij het opslaan van een schakelende grootheid zijn er slechts twee toestanden, 0 en 1, en kun je een binaire binaire versie van één bit gebruiken. Om opslagruimte te besparen en verwerking gemakkelijker te maken, biedt C een datastructuur genaamd "bitveld" of "bitveld". Het zogenaamde "bitveld" verdeelt de binaire bestanden in een byte in verschillende gebieden en beschrijft het aantal bits in elk gebied. Elk domein heeft een domeinnaam, waardoor bewerkingen per domeinnaam in het programma mogelijk zijn. Dit maakt het mogelijk om verschillende objecten te representeren in een byte binair bitveld.
(2) Abstracte gemeenschappelijke functies
Oplettende lezers zullen merken dat het toewijzen van een waarde aan een struct vaak inhoudt dat een 16-bits ongetekende int-typewaarde wordt toegekend aan twee 8-bits onondertekende char-typewaarden, als volgt:
dmaConfig.SRCADDRH=(Onondertekend char)((Onondertekend int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(Onondertekend char)((Onondertekend int)&sourceString);

Voor dit type vaak gebruikte functie kunnen we het net zo goed abstraheren als een algemene functie, als volgt:
#define SET_WORD(destH,destL,woord)
    doen{
       destH=(Onondertekend char)((Onondertekend int)woord >>8);     
       destL=(Onondertekend char)((Onondertekend int)woord);
    }terwijl(0)

In de toekomst, wanneer je een soortgelijke splitsingsoperatie moet uitvoeren, kun je deze direct aanroepen, als volgt:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Configuratie inschakelen: Eerst het eerste adres van de structuur&dmaConfigDe hoge/lage 8 bits worden respectievelijk aan SFR toegewezenDMA0CFGHenDMA0CFGL(waarbij 0 de configuratie voor kanaal 0 vertegenwoordigt, CC2430 5 DMA-kanalen bevat, kanaal 0 wordt hier gebruikt). JaDMAARM.0Ken een waarde van 1 toe om de configuratie van kanaal 0 te activeren zodat kanaal 0 in werkmodus is.

  (3) DMA-transmissie inschakelen:RechtsDMAREQ.0Ken een waarde van 1 toe om de DMA-transmissie van kanaal 0 te starten.

  (4) Wachten tot de DMA wordt verzonden:Nadat de DMA van kanaal 0 is verzonden, wordt de interrupt geactiveerd en wordt de interruptvlag van kanaal 0 geactiveerdDMAIRQ.0wordt automatisch ingesteld op 1. Elk teken van de twee strings wordt vervolgens vergeleken en het verificatieresultaat wordt naar de PC gestuurd.

(4) Experimentele resultaten

Open eerst de seriële poort-debugging tool en start vervolgens CC2430 debugging, en het volgende scherm verschijnt:

Je zult vindendestStringDe inhoud is volledig onthuldbronStringgevuld.

Klaar~

3. Conclusie

Deze sectie introduceert het gebruik van DMA, hoewel het heel eenvoudig is, maar ik denk dat je het basisgebruik van DMA hebt begrepen, en je kunt het ook rustig analyseren wanneer je in de toekomst met complexe gebruiksscenario's te maken krijgt.

Hoe goed een desktop ook is, hij zal bevriezen, en op dezelfde manier zal een embedded systeem onvermijdelijk stagneren. In de volgende sectie introduceren we een zeer effectieve methode van systematische reset: waakhonden.






Vorig:Zigbee Journey (6): Verschillende belangrijke CC2430 basisexperimenten - ADC single sampling
Volgend:Zigbee Journey (8): Verschillende belangrijke CC2430 basisexperimenten - waakhonden
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com