Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 8951|Відповідь: 0

Zigbee Journey (7): Кілька важливих базових експериментів CC2430 — передача DMA

[Копіювати посилання]
Опубліковано 30.10.2014 23:22:16 | | | |
1. З'єднання верхнього та нижнього рівнів

У попередньому розділі ми говорили про використання АЦП і аналізували датчик температури на чипі. У реальних проєктах кількість сенсорів часто велика, і потрібно обробляти значну кількість даних конвертації. Переміщення цих даних створить велике навантаження на процесор. Щоб звільнити процесор і дати йому енергію для інших завдань, може стати в пригоді DMA (Direct Memory Access~

Наступний вступ взято з навчального посібника Zigbee Technology Practice:

DMA — це скорочення від прямого доступу до пам'яті, що означає «прямий доступ до пам'яті». Це режим високошвидкісної передачі даних, у якому периферійні пристрої, такі як ADC/UART/RF трансивери та пам'ять, можуть обмінюватися даними безпосередньо під керуванням «DMA-контролера» без мінімального втручання процесора. Окрім невеликої обробки на початку та наприкінці передачі даних, процесор може виконувати й інші завдання під час передачі. Таким чином, CPU та ці дані працюють паралельно більшість часу. Внаслідок цього загальна ефективність системи може бути значно підвищена.

Як видно з вступу, DMA можна використовувати в багатьох ситуаціях. Цей експеримент передбачає лише найпростішу передачу DMA і має на меті продемонструвати загальне використання DMA. Щодо застосування ДМА в інших сценаріях, його буде реалізовано в комплексних експериментах у майбутньому.

2. Експеримент передачі DMA(1) Вступ до експерименту

Символи масивуsourceStringКонтент передається до масиву символів через 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 бітполя=перевернуті
typedef Struct
{
  Без підпису charSRCADDRH;           //源地址高8位
  Без підпису charSRCADDRL;           //源地址低8位
  Без підпису charDESTADDRH;         //目的地址高8位
  Без підпису charDESTADDRL;         //目的地址低8位
  Без підпису charVLEN :3;     //长度域模式选择
  Без підпису charЛЕНХ:5;     //传输长度高字节
  Без підпису charLENL :8;     //传输长度低字节
  Без підпису charРОЗМІР СЛОВА:1;     //字节(byte)或字(word)传输
  Без підпису charTMODE:2;     //传输模式选择
  Без підпису charТРИГ:5;     //触发事件选择
  Без підпису charSRCINC :2;     //源地址增量:-1/0/1/2
  Без підпису charDESTINC :2;     //目的地址增量:-1/0/1/2
  Без підпису charIRQMASK :1;     //中断屏蔽
  Без підпису charM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  Без підпису charПРІОРИТЕТ:2;     //优先级
}DMA_CFG;
#pragma bitfields=за замовчуванням

/*系统时钟初始化
-------------------------------------------------------*/
Порожнечаxtal_init(Порожнеча)
{
  SLEEP &= ~0x04;            //都上电
  поки(! (SLEEP &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Виберіть кристалічний осцилятор на 32 МГц
  СОН |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
Порожнечаled_init(Порожнеча)
{
  P1SEL =0x00;         P1 — це звичайний порт введення/виведення
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3 вихід
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
ПорожнечаUart0Init(Без підпису charStopBits,Без підпису charПаритет)
{
   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发送数据
-------------------------------------------------------*/
Порожнеча  Uart0Send(Без підпису charдані)
{
  поки(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = дані;
}

/*UART0发送字符串
-------------------------------------------------------*/
ПорожнечаUart0SendString(Без підпису char*s)
{
  поки(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
ПорожнечаГоловна(Порожнеча)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  Без підпису charsourceString[]="Я — ДжерелоСтрунка!";      //源字符串
  Без підпису chardestString[розмір(джерелоРядок)] ="Я — найкраща Струна!";  //目的字符串
  
  chari;
  charпомилка=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(Без підпису char)((Без підпису int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(Без підпису char)((Без підпису int)&sourceString);
   
  dmaConfig.DESTADDRH=(Без підпису char)((Без підпису int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(Без підпису char)((Без підпису int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(Без підпису char)((Без підпису int)розмір(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(Без підпису char)((Без підпису int)розмір(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=(Без підпису char)((Без підпису int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(Без підпису char)((Без підпису int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  МАРЕК=0x01;                 //启动DMA传输
  
  поки(! (DMAIRQ&0x01));               //等待传输结束
  
  для(i=0; i <розмір(джерелоString); i++)   //校验传输的正确性
  {
    якщо(джерелоРядок!=destString)
      error++;
  }
  
  якщо(помилка==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Вірно!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  інше
    Uart0SendString(«Помилка!»);

  поки(1);
}

Основний процес використання ДМА такий:Налаштувати DMAУвімкнути налаштуванняПочніть передачу DMA → чекайте, поки завершиться трансфер DMA.Відповідно:

  (1) Налаштувати DMA: По-перше, потрібно налаштувати DMA, але конфігурація DMA є особливою: замість прямого призначення значень деяким SFR, вона визначає структуру зовнішньо, присвоює їй значення, а потім призначає високі 8 бітів першої адреси цієї структуриDMA0CFGH, що дає йому нижчі 8 цифрDMA0CFGL。 (Детальні інструкції щодо конфігурації, будь ласка, зверніться до китайського посібника CC2430)

Поради щодо CC2430
Є два моменти, які слід уточнити щодо визначення конфігураційних структур у наведеному вище вихідному коді:
(1) Бітова область
При визначенні цієї структури використовується багато двокрапок (:), а потім число, яке називається «бітовим полем»:
Домен бітів означає, що інформація не повинна займати повний байт при збереженні, а займає лише кілька або один бінарний біт. Наприклад, при зберіганні перемикаючої величини існує лише два стани — 0 і 1, і можна використовувати однобітний бінарний код. Щоб зекономити місце для зберігання та спростити обробку, C надає структуру даних, яку називають «бітовим полем» або «бітовим полем». Так зване «бітове поле» ділить бінарні файли в байті на кілька різних областей і описує кількість бітів у кожній області. Кожен домен має доменне ім'я, що дозволяє виконувати операції за доменним ім'ям у програмі. Це дозволяє представляти кілька різних об'єктів у бінарному бітовому полі з байтами.
(2) Абстрактні спільні функції
Уважні читачі знайдуть, що призначення значення структурі часто передбачає присвоєння 16-бітного незнакового int-типу двом 8-бітним незнаковим значенням типу символу, а саме:
dmaConfig.SRCADDRH=(Без підпису char)((Без підпису int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(Без підпису char)((Без підпису int)&sourceString);

Для такого типу часто використовуваної функції можна абстрагувати її як загальну функцію, а саме:
#define SET_WORD(destH,destL,word)
    робити{
       destH=(Без підпису char)((Без підпису int)слово >>8);     
       destL=(Без підпису char)((Без підпису int)слово);
    }поки(0)

У майбутньому, коли потрібно виконати подібну операцію розщеплення, ви можете викликати її напряму, наступним чином:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Увімкнути конфігурацію: По-перше, перша адреса споруди&dmaConfigВерхні/низькі 8 біт призначаються 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Контент повністю розкритийsourceStringнаповненим.

Готово~

3. Висновок

Цей розділ знайомить із використанням DMA, хоча це дуже просто, але, думаю, ви зрозуміли основне застосування DMA, і також можете спокійно аналізувати його, коли стикаєтеся зі складними сценаріями використання в майбутньому.

Незалежно від того, наскільки хороший десктоп, він зависає, і так само вбудована система неминуче застоюється. У наступному розділі ми представимо дуже ефективний метод систематичного скидання: watchdogs.






Попередній:Zigbee Journey (6): Кілька важливих базових експериментів CC2430 — ADC single sampleling
Наступний:Zigbee Journey (8): Кілька важливих базових експериментів CC2430 — сторожі
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com