Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 8951|Svar: 0

Zigbee Journey (7): Flera viktiga CC2430 grundläggande experiment - DMA-överföring

[Kopiera länk]
Publicerad på 2014-10-30 23:22:16 | | | |
1. Att koppla ihop de övre och undre nivåerna

I föregående avsnitt pratade vi om användningen av ADC:er och provtog den inbyggda temperatursensorn. I faktiska projekt är antalet sensorer ofta stort och en stor mängd konverteringsdata ska bearbetas. Att flytta dessa data kommer att belasta CPU:n mycket. För att frigöra CPU:n och ge den energi till andra saker kan DMA (Direct Memory Access) vara användbar~

Följande introduktion är ett utdrag ur Zigbee Technology Practice Tutorial:

DMA är en förkortning för direkt minnesåtkomst, vilket är "direkt minnesåtkomst". Detta är ett höghastighetsläge för dataöverföring där kringutrustningsenheter som ADC/UART/RF-transceivrar och minne kan utbyta data direkt under kontroll av "DMA-kontrollern" utan minimal CPU-inblandning. Förutom att göra lite bearbetning i början och slutet av dataöverföringen kan CPU:n utföra annat arbete under överföringen. På så sätt arbetar CPU:n och dessa datainteraktioner parallellt för det mesta. Som ett resultat kan systemets totala effektivitet förbättras avsevärt.

Som du kan se från introduktionen kan DMA användas i många scenarier. Detta experiment involverar endast den enklaste DMA-överföringen och syftar till att demonstrera den allmänna användningen av DMA. När det gäller tillämpningen av DMA i andra scenarier kommer det att implementeras i omfattande experiment i framtiden.

2. DMA-transmissionsexperiment(1) Introduktion till experimentet

Array-karaktärersourceStringInnehållet överförs till karaktärsarrayen via DMAdestString, konverteringsresultatet visas på datorn via serieporten.

(2) Programflödesschema

(3) Experimentell källkod och analys/*
    Experimentell beskrivning: Innehållet i teckenarrayen sourceString överförs till teckenarrayen destString via DMA, och konverteringsresultatet visas på datorn via den seriella porten.
*/

#include

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

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

/*系统时钟初始化
-------------------------------------------------------*/
tomrumxtal_init(tomrum)
{
  SOV &= ~0x04;            //都上电
  medan(! (SÖMN &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Välj en 32MHz kristalloscillator
  SÖMN |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
tomrumled_init(tomrum)
{
  P1SEL =0x00;         P1 är den normala I/O-porten
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3-utgång
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
tomrumUart0Init(osignerad charStopBits,osignerad charParitet)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Välj UART0 som första valbara position, det vill säga RXD till P0.2 och TXD till P0.3
   
   U0CSR =0xC0;                    Ställ in på UART-läge och aktivera acceptorn
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Paritet;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
tomrum  Uart0Send(osignerad chardata)
{
  medan(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = data;
}

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

/*主函数
-------------------------------------------------------*/
tomrumhuvud(tomrum)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  osignerad charsourceString[]="Jag är sourceString!";      //源字符串
  osignerad chardestString[storlek på(sourceString)] ="Jag är destString!";  //目的字符串
  
  chari;
  charfel=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(osignerad char)((osignerad int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(osignerad char)((osignerad int)&sourceString);
   
  dmaConfig.DESTADDRH=(osignerad char)((osignerad int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(osignerad char)((osignerad int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(osignerad char)((osignerad int)storlek på(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(osignerad char)((osignerad int)storlek på(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Ingen trigger (kan förstås som manuell triggering)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(osignerad char)((osignerad int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(osignerad char)((osignerad int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  medan(! (DMAIRQ&0x01));               //等待传输结束
  
  för(i=0; i <storlek på(sourceString); i++)   //校验传输的正确性
  {
    om(sourceString!=destString)
      fel++;
  }
  
  om(fel==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Korrekt!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  annars
    Uart0SendString("Fel!");

  medan(1);
}

Den grundläggande processen för att använda DMA är:Konfigurera DMAAktivera konfigurationStarta DMA-överföringen → Vänta tills DMA-överföringen är klar.Följande är respektive:

  (1) Konfigurera DMA: Först och främst måste DMA konfigureras, men konfigurationen av DMA är speciell: istället för att direkt tilldela värden till vissa SFR:er definierar den en struktur externt, tilldelar värden till den och tilldelar sedan de högsta 8 bitarna i den första adressen till denna strukturDMA0CFGH, vilket ger den lägre 8 siffrorDMA0CFGL。 (För detaljerade instruktioner i konfigurationsstrukturen, se CC2430 kinesiska manualen)

CC2430-tips
Det finns två punkter att klargöra angående definitionen av konfigurationsstrukturer i källkoden ovan:
(1) Bitdomän
När denna struktur definieras används många kolon (:), följt av ett tal som kallas "bitfält":
Bitdomänen innebär att informationen inte behöver uppta en hel byte när den lagras, utan endast upptar några eller en binär bit. Till exempel, när man lagrar en växlande kvantitet finns det bara två tillstånd, 0 och 1, och du kan använda en bitars binär. För att spara lagringsutrymme och göra bearbetningen enklare tillhandahåller C en datastruktur som kallas "bitfält" eller "bitfält". Det så kallade "bitfältet" delar in binärerna i en byte i flera olika regioner och beskriver antalet bitar i varje region. Varje domän har ett domännamn, vilket möjliggör operationer per domännamn i programmet. Detta möjliggör att flera olika objekt kan representeras i ett byte-binärt bitfält.
(2) Abstrakta gemensamma funktioner
Uppmärksamma läsare kommer att upptäcka att tilldelning av ett värde till en struktur ofta innebär att ett 16-bitars osignerat int-typvärde tilldelas två 8-bitars osignerade char-typvärden, enligt följande:
dmaConfig.SRCADDRH=(osignerad char)((osignerad int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(osignerad char)((osignerad int)&sourceString);

För denna typ av ofta använd funktion kan vi lika gärna abstrahera den som en allmän funktion, enligt följande:
#define SET_WORD(destH,destL,ord)
    göra{
       destH=(osignerad char)((osignerad int)ord >>8);     
       destL=(osignerad char)((osignerad int)ord);
    }medan(0)

I framtiden, när du behöver utföra en liknande splittringsoperation, kan du anropa den direkt, enligt följande:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Aktivera konfiguration: Först, den första adressen till strukturen&dmaConfigDe höga/låga 8 bitarna tilldelas respektive SFRDMA0CFGHochDMA0CFGL(där 0 representerar konfigurationen för kanal 0, CC2430 innehåller 5 DMA-kanaler, kanal 0 används här). JaDMAARM.0Tilldela värdet 1 för att aktivera konfigurationen av kanal 0 så att kanal 0 är i arbetsläge.

  (3) Aktivera DMA-överföring:HögerDMAREQ.0Tilldela värdet 1 för att starta DMA-överföringen av kanal 0.

  (4) Vänta på att DMA ska sändas:Efter att DMA för kanal 0 har sänts utlöses avbrottet och avbrottsflaggan för kanal 0 triggasDMAIRQ.0kommer automatiskt att sättas till 1. Varje tecken i de två strängarna jämförs sedan och verifieringsresultatet skickas till PC:n.

(4) Experimentella resultat

Öppna först verktyget för seriell port-felsökning och starta sedan CC2430-felsökningen, och följande skärm visas:

Du kommer att hittadestStringInnehållet har blivit helt avslöjatsourceStringFyllda.

Klart~

3. Slutsats

Detta avsnitt introducerar användningen av DMA, även om det är mycket enkelt, men jag tror att du har förstått den grundläggande användningen av DMA, och du kan också analysera det lugnt när du möter dess komplexa användningsscenarier i framtiden.

Oavsett hur bra ett skrivbord är kommer det att frysa, och på samma sätt kommer ett inbyggt system oundvikligen att stagnera. I nästa avsnitt kommer vi att introducera en mycket effektiv metod för systematisk återställning: vakthundar.






Föregående:Zigbee Journey (6): Flera viktiga CC2430-grundexperiment - ADC enkelprovtagning
Nästa:Zigbee Journey (8): Flera viktiga CC2430 grundläggande experiment – vakthundar
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com