Dieser Artikel ist ein Spiegelartikel der maschinellen Übersetzung, bitte klicken Sie hier, um zum Originalartikel zu springen.

Ansehen: 8951|Antwort: 0

Zigbee Journey (7): Mehrere wichtige CC2430-Grundexperimente – DMA-Übertragung

[Link kopieren]
Veröffentlicht am 30.10.2014 23:22:16 | | | |
1. Verbindung der oberen und unteren Ebenen

Im vorherigen Abschnitt haben wir über den Einsatz von ADCs gesprochen und den On-Chip-Temperatursensor getestet. In tatsächlichen Projekten ist die Anzahl der Sensoren oft groß und es wird eine große Menge an Konvertierungsdaten verarbeitet. Das Verschieben dieser Daten belastet die CPU erheblich. Um die CPU freizusetzen und ihr Energie für andere Aufgaben zu geben, kann DMA (Direct Memory Access) sehr nützlich sein~

Die folgende Einführung ist ein Auszug aus dem Zigbee Technology Practice Tutorial:

DMA ist eine Abkürzung für direkten Speicherzugriff, was "direkter Speicherzugriff" bedeutet. Dies ist ein Hochgeschwindigkeits-Datenübertragungsmodus, bei dem Peripheriegeräte wie ADC/UART/RF-Transceiver und Speicher Daten direkt unter der Steuerung des "DMA-Controllers" austauschen können, ohne dass die CPU nur wenig Eingriff benötigt. Neben der geringen Verarbeitung zu Beginn und Ende der Datenübertragung kann die CPU während der Übertragung auch andere Aufgaben übernehmen. So arbeiten CPU und Dateninteraktionen meist parallel. Dadurch kann die Gesamteffizienz des Systems erheblich verbessert werden.

Wie du in der Einführung sehen kannst, kann DMA in vielen Szenarien verwendet werden. Dieses Experiment beinhaltet nur die einfachste DMA-Übertragung und zielt darauf ab, die allgemeine Nutzung von DMA zu demonstrieren. Was die Anwendung von DMA in anderen Szenarien betrifft, so wird sie in Zukunft in umfassenden Experimenten umgesetzt.

2. DMA-Übertragungsexperiment(1) Einführung in das Experiment

Array-CharakteresourceStringDer Inhalt wird per DMA auf das Charakterarray übertragendestString, das Konvertierungsergebnis wird auf dem PC über den seriellen Anschluss angezeigt.

(2) Programmflussdiagramm

(3) Experimenteller Quellcode und Analyse/*
    Experimentelle Beschreibung: Der Inhalt des Zeichenarrays sourceString wird über DMA auf das Zeichenarray destString übertragen, und das Konvertierungsergebnis wird auf dem PC über den seriellen Anschluss angezeigt.
*/

#include

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

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

/*系统时钟初始化
-------------------------------------------------------*/
Leerextal_init(Leere)
{
  SCHLAF &= ~0x04;            //都上电
  während(! (SCHLAF &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Wählen Sie einen 32-MHz-Kristalloszillator
  SCHLAF |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
Leereled_init(Leere)
{
  P1SEL =0x00;         P1 ist der normale I/O-Port
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3 Ausgang
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
LeereUart0Init(Unsigniert charStopBits,Unsigniert charParität)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Wählen Sie UART0 als erste optionale Position, also RXD bis P0.2 und TXD bis P0.3
   
   U0CSR =0xC0;                    Stellen Sie den UART-Modus ein und aktivieren Sie den Akzeptor.
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Parität;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
Leere  Uart0Send(Unsigniert charDaten)
{
  während(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = Daten;
}

/*UART0发送字符串
-------------------------------------------------------*/
LeereUart0SendString(Unsigniert char*s)
{
  während(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
Leeremain(Leere)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  Unsigniert charsourceString[]="Ich bin der Quell-String!";      //源字符串
  Unsigniert chardestString[Sizeof(sourceString)] ="Ich bin der DestString!";  //目的字符串
  
  charIch;
  charerror=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(Unsigniert char)((Unsigniert Int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(Unsigniert char)((Unsigniert Int)&sourceString);
   
  dmaConfig.DESTADDRH=(Unsigniert char)((Unsigniert Int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(Unsigniert char)((Unsigniert Int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(Unsigniert char)((Unsigniert Int)Sizeof(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(Unsigniert char)((Unsigniert Int)Sizeof(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Kein Auslöser (kann als manuelles Auslösen verstanden werden)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(Unsigniert char)((Unsigniert Int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(Unsigniert char)((Unsigniert Int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  während(! (DMAIRQ&0x01));               //等待传输结束
  
  für(i=0; Ich <Sizeof(sourceString); i++)   //校验传输的正确性
  {
    wenn(sourceString)!=destString)
      error++;
  }
  
  wenn(error==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Richtig!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  oder
    Uart0SendString("Fehler!");

  während(1);
}

Der grundlegende Prozess der Nutzung von DMA ist:DMA konfigurierenKonfiguration aktivierenStarte den DMA-Transfer → Warte, bis der DMA-Transfer abgeschlossen ist.Die folgenden sind jeweils:

  (1) DMA konfigurieren: Zunächst muss DMA konfiguriert werden, aber die Konfiguration von DMA ist besonders: Anstatt direkt Werte einigen SFRs zuzuweisen, definiert sie eine Struktur extern, weist ihr Werte zu und weist dann die höchsten 8 Bits der ersten Adresse dieser Struktur zuDMA0CFGH, was ihm eine niedrigere 8 Ziffern verleihtDMA0CFGL。 (Für detaillierte Anweisungen zur Konfigurationsstruktur siehe bitte das chinesische Handbuch CC2430)

CC2430 Tipps
Es gibt zwei Punkte, die zur Definition von Konfigurationsstrukturen im obigen Quellcode klargestellt werden müssen:
(1) Bitdomäne
Bei der Definition dieser Struktur werden viele Doppelkollone (:) verwendet, gefolgt von einer Zahl, die als "Bitfeld" bezeichnet wird:
Bitdomäne bedeutet, dass Informationen beim Speichern kein ganzes Byte einnehmen müssen, sondern nur wenige oder ein Binärbit einnehmen. Zum Beispiel gibt es beim Speichern einer Schaltgröße nur zwei Zustände, 0 und 1, und man kann ein Einbit-Binärsystem verwenden. Um Speicherplatz zu sparen und die Verarbeitung zu erleichtern, bietet C eine Datenstruktur namens "Bitfeld" oder "Bitfeld". Das sogenannte "Bitfeld" teilt die Binärdateien in einem Byte in mehrere verschiedene Bereiche und beschreibt die Anzahl der Bits in jedem Bereich. Jede Domain hat einen Domainnamen, der Operationen nach Domainnamen im Programm ermöglicht. Dies ermöglicht es, mehrere verschiedene Objekte in einem Byte-Binärbitfeld darzustellen.
(2) Abstrakte gemeinsame Funktionen
Aufmerksame Leser werden feststellen, dass die Zuweisung eines Wertes an eine Struktur oft das Zuweisen eines 16-Bit-unsignierten Int-Typwerts an zwei 8-Bit-unsignierte Char-Typwerte beinhaltet, wie folgt:
dmaConfig.SRCADDRH=(Unsigniert char)((Unsigniert Int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(Unsigniert char)((Unsigniert Int)&sourceString);

Für diese Art häufig verwendeter Funktion können wir sie ebenso gut als allgemeine Funktion abstrahieren, wie folgt:
#define SET_WORD(destH,destL,Wort)
    tun{
       destH=(Unsigniert char)((Unsigniert Int)Wort >>8);     
       destL=(Unsigniert char)((Unsigniert Int)Wort);
    }während(0)

In Zukunft, wann immer Sie eine ähnliche Aufteilungsoperation durchführen müssen, können Sie sie direkt aufrufen, wie folgt:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Konfiguration aktivieren: Zuerst die erste Adresse der Struktur&dmaConfigDie hochen/niedrigen 8 Bits werden jeweils SFR zugewiesenDMA0CFGHundDMA0CFGL(wobei 0 die Konfiguration für Kanal 0 darstellt, CC2430 5 DMA-Kanäle enthält, hier wird Kanal 0 verwendet). JaDMAARM.0Weisen Sie den Wert 1 zu, um die Konfiguration von Kanal 0 zu aktivieren, sodass Kanal 0 im Arbeitsmodus ist.

  (3) DMA-Übertragung aktivieren:RechtsDMAREQ.0Weisen Sie einen Wert 1 zu, um die DMA-Übertragung von Kanal 0 zu starten.

  (4) Warten auf die Übertragung der DMA:Nachdem die DMA von Kanal 0 übertragen wurde, wird der Interrupt ausgelöst und das Interrupt-Flag von Kanal 0 ausgelöstDMAIRQ.0wird automatisch auf 1 gesetzt. Jedes Zeichen der beiden Zeichenketten wird dann verglichen, und das Verifikationsergebnis wird an den PC gesendet.

(4) Versuchsergebnisse

Öffnen Sie zuerst das Debugging-Tool für serielle Ports und starten Sie dann das Debugging von CC2430, und folgender Bildschirm erscheint:

Du wirst findendestStringDer Inhalt wurde vollständig enthülltsourceStringgefüllt.

Fertig~

3. Fazit

Dieser Abschnitt führt die Verwendung von DMA ein, obwohl sie sehr einfach ist, aber ich denke, Sie haben die grundlegende Verwendung von DMA verstanden und können sie auch ruhig analysieren, wenn Sie in Zukunft auf komplexe Anwendungsszenarien stoßen.

Egal wie gut ein Desktop ist, er wird einfrieren, und ebenso wird ein eingebettetes System zwangsläufig stagnieren. Im nächsten Abschnitt stellen wir eine sehr effektive Methode des systematischen Zurücksetzens vor: Wachhunde.






Vorhergehend:Zigbee Journey (6): Mehrere wichtige CC2430-Basisexperimente – ADC-Einzelsampling
Nächster:Zigbee Journey (8): Mehrere wichtige CC2430-Grundexperimente – Wachhunde
Verzichtserklärung:
Alle von Code Farmer Network veröffentlichten Software, Programmiermaterialien oder Artikel dienen ausschließlich Lern- und Forschungszwecken; Die oben genannten Inhalte dürfen nicht für kommerzielle oder illegale Zwecke verwendet werden, andernfalls tragen die Nutzer alle Konsequenzen. Die Informationen auf dieser Seite stammen aus dem Internet, und Urheberrechtsstreitigkeiten haben nichts mit dieser Seite zu tun. Sie müssen die oben genannten Inhalte innerhalb von 24 Stunden nach dem Download vollständig von Ihrem Computer löschen. Wenn Ihnen das Programm gefällt, unterstützen Sie bitte echte Software, kaufen Sie die Registrierung und erhalten Sie bessere echte Dienstleistungen. Falls es eine Verletzung gibt, kontaktieren Sie uns bitte per E-Mail.

Mail To:help@itsvse.com