Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 8951|Απάντηση: 0

Ταξίδι με Zigbee (7): Αρκετά σημαντικά βασικά πειράματα CC2430 - μετάδοση DMA

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 30/10/2014 11:22:16 μ.μ. | | | |
1. Σύνδεση του ανώτερου και του κατώτερου επιπέδου

Στην προηγούμενη ενότητα, μιλήσαμε για τη χρήση ADC και δοκιμάσαμε τον αισθητήρα θερμοκρασίας στο τσιπ. Στα πραγματικά έργα, ο αριθμός των αισθητήρων είναι συχνά μεγάλος και πρέπει να υποβληθεί σε επεξεργασία μεγάλος όγκος δεδομένων μετατροπής. Η μετακίνηση αυτών των δεδομένων θα επιβαρύνει πολύ την CPU. Για να ελευθερώσετε την CPU και να της δώσετε την ενέργεια να κάνει άλλα πράγματα, το DMA (Direct Memory Access) μπορεί να σας φανεί χρήσιμο~

Η ακόλουθη εισαγωγή είναι απόσπασμα από το Zigbee Technology Practice Tutorial:

Το DMA είναι μια συντομογραφία για την άμεση πρόσβαση στη μνήμη, η οποία είναι "άμεση πρόσβαση στη μνήμη". Αυτή είναι μια λειτουργία μετάδοσης δεδομένων υψηλής ταχύτητας στην οποία περιφερειακές μονάδες όπως πομποδέκτες ADC/UART/RF και μνήμη μπορούν να ανταλλάσσουν δεδομένα απευθείας υπό τον έλεγχο του "ελεγκτή DMA" χωρίς μικρή παρέμβαση της CPU. Εκτός από μια μικρή επεξεργασία στην αρχή και στο τέλος της μεταφοράς δεδομένων, η CPU μπορεί να κάνει και άλλες εργασίες κατά τη μεταφορά. Με αυτόν τον τρόπο, η CPU και αυτές οι αλληλεπιδράσεις δεδομένων λειτουργούν παράλληλα τις περισσότερες φορές. Ως αποτέλεσμα, η συνολική απόδοση του συστήματος μπορεί να βελτιωθεί σημαντικά.

Όπως μπορείτε να δείτε από την εισαγωγή, το DMA μπορεί να χρησιμοποιηθεί σε πολλά σενάρια. Αυτό το πείραμα περιλαμβάνει μόνο την απλούστερη μετάδοση DMA και στοχεύει να καταδείξει τη γενική χρήση του DMA. Όσον αφορά την εφαρμογή του DMA σε άλλα σενάρια, θα εφαρμοστεί σε ολοκληρωμένα πειράματα στο μέλλον.

2. Πείραμα μετάδοσης DMA(1) Εισαγωγή στο πείραμα

Χαρακτήρες πίνακαπηγήΣυμβολοσειράΤο περιεχόμενο μεταφέρεται στον πίνακα χαρακτήρων μέσω DMAdestString, το αποτέλεσμα μετατροπής εμφανίζεται στον υπολογιστή μέσω της σειριακής θύρας.

(2) Διάγραμμα ροής προγράμματος

(3) Πειραματικός πηγαίος κώδικας και ανάλυση/*
    Πειραματική περιγραφή: Τα περιεχόμενα του πίνακα χαρακτήρων sourceString μεταφέρονται στον πίνακα χαρακτήρων destString μέσω DMA και το αποτέλεσμα μετατροπής εμφανίζεται στον υπολογιστή μέσω της σειριακής θύρας.
*/

#include

#define LED1 P1_0         
#define LED2 P1_1         
#define LED3 P1_2         
#define LED4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitfields=αντεστραμμένο
typedef δομή
{
  ανυπόγραφο κάρβουνοSRCADDRH;           //源地址高8位
  ανυπόγραφο κάρβουνοSRCADDRL;           //源地址低8位
  ανυπόγραφο κάρβουνοDESTADDRH;         //目的地址高8位
  ανυπόγραφο κάρβουνοΝΤΕΣΤΑΝΤΡΛ;         //目的地址低8位
  ανυπόγραφο κάρβουνοΒΛΕΝ:3;     //长度域模式选择
  ανυπόγραφο κάρβουνοΛΕΝΧ :5;     //传输长度高字节
  ανυπόγραφο κάρβουνοΛΕΝΛ :8;     //传输长度低字节
  ανυπόγραφο κάρβουνοΜΈΓΕΘΟΣ ΛΈΞΗΣ:1;     //字节(byte)或字(word)传输
  ανυπόγραφο κάρβουνοTMODE :2;     //传输模式选择
  ανυπόγραφο κάρβουνοΤΡΙΓΩΝΟ :5;     //触发事件选择
  ανυπόγραφο κάρβουνοSRCINC :2;     //源地址增量:-1/0/1/2
  ανυπόγραφο κάρβουνοDESTINC :2;     //目的地址增量:-1/0/1/2
  ανυπόγραφο κάρβουνοIRQMASK :1;     //中断屏蔽
  ανυπόγραφο κάρβουνοΜ8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  ανυπόγραφο κάρβουνοΠΡΟΤΕΡΑΙΟΤΗΤΑ :2;     //优先级
}DMA_CFG;
#pragma bitfields=προεπιλογή

/*系统时钟初始化
-------------------------------------------------------*/
άκυροxtal_init(άκυρο)
{
  ΥΠΝΟΣ &= ~0x04;            //都上电
  ενώ(! (ΥΠΝΟΣ &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Επιλέξτε έναν κρυσταλλικό ταλαντωτή 32 MHz
  ΥΠΝΟΣ |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
άκυροled_init(άκυρο)
{
  Ρ1ΣΕΛ =0x00;         Το P1 είναι η κανονική θύρα εισόδου/εξόδου
  P1DIR |=0x0F;         Έξοδος P1.0 P1.1 P1.2 P1.3
  
  LED1 =1;               //关闭所有LED
  LED2 =1;
  LED3 =1;
  LED4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
άκυροUart0Init(ανυπόγραφο κάρβουνοStopBits,ανυπόγραφο κάρβουνοΙσοτιμία)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Επιλέξτε UART0 ως την πρώτη προαιρετική θέση, δηλαδή, RXD σε P0.2 και TXD σε P0.3
   
   U0CSR =0xC0;                    Ρυθμίστε σε λειτουργία UART και ενεργοποιήστε τον αποδέκτη
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Ισοτιμία;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
άκυρο  Uart0Αποστολή(ανυπόγραφο κάρβουνοδεδομένα)
{
  ενώ(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = δεδομένα·
}

/*UART0发送字符串
-------------------------------------------------------*/
άκυροUart0SendString(ανυπόγραφο κάρβουνο*ιθ)
{
  ενώ(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
άκυροmain(άκυρο)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  ανυπόγραφο κάρβουνοsourceString[]=«Είμαι ο sourceString!";      //源字符串
  ανυπόγραφο κάρβουνοdestString[μέγεθος(πηγήString)] =«Είμαι ο destString!";  //目的字符串
  
  κάρβουνοi;
  κάρβουνοσφάλμα=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&sourceString);
   
  dmaConfig.DESTADDRH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)μέγεθος(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)μέγεθος(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Χωρίς σκανδάλη (μπορεί να γίνει κατανοητή ως χειροκίνητη ενεργοποίηση)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  ΔΜΑΡΕΚ=0x01;                 //启动DMA传输
  
  ενώ(! (DMAIRQ&0x01));               //等待传输结束
  
  Για(i=0; i <μέγεθος(πηγήΣυμβολοσειρά); i++)   //校验传输的正确性
  {
    αν(πηγήString!=destString)
      σφάλμα++;
  }
  
  αν(σφάλμα==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Σωστός!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  αλλιώς
    Uart0SendString("Λάθος!");

  ενώ(1);
}

Η βασική διαδικασία χρήσης του DMA είναι:Διαμόρφωση DMAΕνεργοποίηση διαμόρφωσηςΈναρξη μεταφοράς DMA → Περιμένετε να ολοκληρωθεί η μεταφορά DMA.Τα ακόλουθα είναι αντίστοιχα:

  (1) Διαμόρφωση DMA: Πρώτα απ 'όλα, το DMA πρέπει να διαμορφωθεί, αλλά η διαμόρφωση του DMA είναι ιδιαίτερη: αντί να εκχωρεί απευθείας τιμές σε ορισμένα SFR, ορίζει μια δομή εξωτερικά, εκχωρεί τιμές σε αυτήν και στη συνέχεια εκχωρεί τα υψηλά 8 bit της πρώτης διεύθυνσης αυτής της δομήςDMA0CFGH, δίνοντάς του χαμηλότερα 8 ψηφίαDMA0CFGL。 (Για λεπτομερείς οδηγίες σχετικά με τη δομή διαμόρφωσης, ανατρέξτε στο κινεζικό εγχειρίδιο CC2430)

Συμβουλές CC2430
Υπάρχουν δύο σημεία που πρέπει να διευκρινιστούν σχετικά με τον ορισμό των δομών διαμόρφωσης στον παραπάνω πηγαίο κώδικα:
(1) Τομέας bit
Κατά τον ορισμό αυτής της δομής, χρησιμοποιούνται πολλές άνω και κάτω τελείες (:), ακολουθούμενες από έναν αριθμό, ο οποίος ονομάζεται "πεδίο bit":
Ο τομέας bit σημαίνει ότι οι πληροφορίες δεν χρειάζεται να καταλαμβάνουν ένα πλήρες byte όταν αποθηκεύονται, αλλά καταλαμβάνουν μόνο μερικά ή ένα δυαδικό bit. Για παράδειγμα, κατά την αποθήκευση μιας ποσότητας μεταγωγής, υπάρχουν μόνο δύο καταστάσεις, 0 και 1, και μπορείτε να χρησιμοποιήσετε ένα δυαδικό bit. Για εξοικονόμηση χώρου αποθήκευσης και διευκόλυνση της επεξεργασίας, το C παρέχει μια δομή δεδομένων που ονομάζεται "πεδίο bit" ή "πεδίο bit". Το λεγόμενο "πεδίο bit" χωρίζει τα δυαδικά αρχεία σε ένα byte σε πολλές διαφορετικές περιοχές και περιγράφει τον αριθμό των bit σε κάθε περιοχή. Κάθε τομέας έχει ένα όνομα τομέα, επιτρέποντας λειτουργίες ανά όνομα τομέα στο πρόγραμμα. Αυτό επιτρέπει την αναπαράσταση πολλών διαφορετικών αντικειμένων σε ένα δυαδικό πεδίο bit byte.
(2) Αφηρημένες κοινές λειτουργίες
Οι προσεκτικοί αναγνώστες θα διαπιστώσουν ότι η ανάθεση μιας τιμής σε μια δομή συχνά περιλαμβάνει την ανάθεση μιας τιμής τύπου 16-bit χωρίς υπογραφή int σε δύο τιμές τύπου 8-bit χωρίς υπογραφή char, ως εξής:
dmaConfig.SRCADDRH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)&sourceString);

Για αυτόν τον τύπο συνάρτησης που χρησιμοποιείται συχνά, θα μπορούσαμε επίσης να την αφαιρέσουμε ως γενική συνάρτηση, ως εξής:
#define SET_WORD(destH,destL,λέξη)
    κάνω{
       destH=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)λέξη >>8);     
       destL=(ανυπόγραφο κάρβουνο)((ανυπόγραφο Διεθνές)λέξη)·
    }ενώ(0)

Στο μέλλον, όποτε χρειαστεί να εκτελέσετε μια παρόμοια λειτουργία διαχωρισμού, μπορείτε να την καλέσετε απευθείας, ως εξής:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Ενεργοποίηση διαμόρφωσης: Πρώτον, η πρώτη διεύθυνση της δομής&dmaConfigΤα υψηλά/χαμηλά 8 bit εκχωρούνται στο SFR αντίστοιχαDMA0CFGHκαιDMA0CFGL(όπου το 0 αντιπροσωπεύει τη διαμόρφωση για το κανάλι 0, το CC2430 περιέχει 5 κανάλια DMA, το κανάλι 0 χρησιμοποιείται εδώ). ΝαιDMAARM.0Εκχωρήστε μια τιμή 1 για να ενεργοποιήσετε τη διαμόρφωση του καναλιού 0 έτσι ώστε το κανάλι 0 να βρίσκεται σε κατάσταση λειτουργίας.

  (3) Ενεργοποίηση μετάδοσης DMA:ΔεξιάDMAREQ.0Εκχωρήστε μια τιμή 1 για να ξεκινήσει η μετάδοση DMA του καναλιού 0.

  (4) Περιμένετε να μεταδοθεί το DMA:Μετά τη μετάδοση του DMA του καναλιού 0, θα ενεργοποιηθεί η διακοπή και θα ενεργοποιηθεί η σημαία διακοπής του καναλιού 0DMAIRQ.0θα οριστεί αυτόματα σε 1. Στη συνέχεια, κάθε χαρακτήρας των δύο συμβολοσειρών συγκρίνεται και το αποτέλεσμα επαλήθευσης αποστέλλεται στον υπολογιστή.

(4) Πειραματικά αποτελέσματα

Αρχικά, ανοίξτε το εργαλείο εντοπισμού σφαλμάτων σειριακής θύρας και, στη συνέχεια, ξεκινήστε τον εντοπισμό σφαλμάτων CC2430 και θα εμφανιστεί η ακόλουθη οθόνη:

Θα βρείτεdestStringΤο περιεχόμενο έχει αποκαλυφθεί πλήρωςπηγήΣυμβολοσειράσυμπληρώθηκε.

Έγινε~

3. Συμπέρασμα

Αυτή η ενότητα εισάγει τη χρήση του DMA, αν και είναι πολύ απλή, αλλά νομίζω ότι έχετε κατανοήσει τη βασική χρήση του DMA και μπορείτε επίσης να την αναλύσετε ήρεμα όταν αντιμετωπίζετε πολύπλοκα σενάρια χρήσης της στο μέλλον.

Ανεξάρτητα από το πόσο καλή είναι μια επιφάνεια εργασίας, θα παγώσει, και ομοίως, ένα ενσωματωμένο σύστημα αναπόφευκτα θα μείνει στάσιμο. Στην επόμενη ενότητα, θα παρουσιάσουμε μια πολύ αποτελεσματική μέθοδο συστηματικής επαναφοράς: τους φύλακες.






Προηγούμενος:Ταξίδι με Zigbee (6): Αρκετά σημαντικά βασικά πειράματα CC2430 - Μονή δειγματοληψία ADC
Επόμενος:Ταξίδι με Zigbee (8): Αρκετά σημαντικά βασικά πειράματα CC2430 - φύλακες
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com