Тази статия е огледална статия за машинен превод, моля, кликнете тук, за да преминете към оригиналната статия.

Изглед: 8951|Отговор: 0

Zigbee Journey (7): Няколко важни основни експеримента с CC2430 - DMA предаване

[Копирай линк]
Публикувано в 30.10.2014 г. 23:22:16 ч. | | | |
1. Свързване на горния и долния етаж

В предишната секция говорихме за използването на ADC и взехме проби от температурния сензор на чипа. В реални проекти броят на сензорите често е голям и трябва да се обработват големи количества данни за преобразуване. Преместването на тези данни ще натовари много процесора. За да освободите процесора и да му дадете енергия за други задачи, DMA (Директен достъп до паметта) може да бъде полезен~

Следващото въведение е извадено от Zigbee Technology Practice Tutorial:

DMA е съкращение от директен достъп до паметта, което означава "директен достъп до паметта". Това е високоскоростен режим на предаване на данни, при който периферни устройства като ADC/UART/RF трансивъри и памет могат да обменят данни директно под контрола на "DMA контролера" без минимална намеса на процесора. Освен че извършва малко обработка в началото и края на трансфера на данни, процесорът може да извършва и друга работа по време на трансфера. По този начин процесорът и тези взаимодействия с данни работят паралелно през повечето време. В резултат на това общата ефективност на системата може значително да се подобри.

Както се вижда от въведението, DMA може да се използва в много ситуации. Този експеримент включва само най-простото 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 bitfields=обърнати
typedef Struct
{
  без подпис ЧарSRCADDRH;           //源地址高8位
  без подпис ЧарSRCADDRL;           //源地址低8位
  без подпис ЧарDESTADDRH;         //目的地址高8位
  без подпис ЧарDESTADDRL;         //目的地址低8位
  без подпис ЧарVLEN :3;     //长度域模式选择
  без подпис ЧарЛЕНХ:5;     //传输长度高字节
  без подпис ЧарLENL :8;     //传输长度低字节
  без подпис ЧарРАЗМЕР НА ДУМАТА:1;     //字节(byte)或字(word)传输
  без подпис ЧарTMODE:2;     //传输模式选择
  без подпис ЧарТРИГ :5;     //触发事件选择
  без подпис ЧарSRCINC :2;     //源地址增量:-1/0/1/2
  без подпис ЧарDESTINC :2;     //目的地址增量:-1/0/1/2
  без подпис ЧарIRQMASK:1;     //中断屏蔽
  без подпис ЧарM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  без подпис ЧарПРИОРИТЕТ:2;     //优先级
}DMA_CFG;
#pragma bitfields=по подразбиране

/*系统时钟初始化
-------------------------------------------------------*/
Празнотаxtal_init(Празнота)
{
  СЪН &= ~0x04;            //都上电
  докато(! (СЪН &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Изберете кристален осцилатор с честота 32MHz
  СЪН |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
Празнотаled_init(Празнота)
{
  P1SEL =0x00;         P1 е нормалният I/O порт
  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发送数据
-------------------------------------------------------*/
Празнота  Uart0Send(без подпис Чарданни)
{
  докато(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = данни;
}

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

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

  докато(1);
}

Основният процес на използване на DMA е:Конфигуриране на DMAАктивиране на конфигурациятаЗапочнете трансфера на DMA → Изчакайте трансфера за DMA да приключи.Следните са съответно:

  (1) Конфигуриране на DMA: Първо, трябва да се конфигурира DMA, но конфигурацията на DMA е специална: вместо директно да присвоява стойности на някои SFR, тя дефинира структура външно, присвоява ѝ стойности и след това присвоява високите 8 бита от първия адрес на тази структураDMA0CFGH, което му дава по-ниски 8 цифриDMA0CFGL。 (За подробни инструкции относно конфигурационната структура, моля, вижте китайското ръководство CC2430)

Съвети за CC2430
Има две точки, които трябва да се изяснят относно дефиницията на конфигурационните структури в горния изходен код:
(1) Битов домейн
При дефиниране на тази структура се използват много двоеточия (:), последвани от число, наречено "битово поле":
Битовият домейн означава, че информацията не трябва да заема цял байт при съхранение, а заема само няколко или един двоичен бит. Например, при съхранение на превключваща величина има само две състояния – 0 и 1, и можете да използвате еднобитов двоичен файл. За да спести място за съхранение и да улесни обработката, C предоставя структура от данни, наречена "битово поле" или "битово поле". Т.нар. "битово поле" разделя бинарните файлове в байт на няколко различни области и описва броя на битовете във всяка област. Всеки домейн има домейн име, което позволява операции по домейн име в програмата. Това позволява няколко различни обекта да бъдат представени в байтово двоично битово поле.
(2) Абстрахиране на общи функции
Внимателните читатели ще открият, че присвояването на стойност на структура често включва присвояване на 16-битова беззнакова int стойност на две 8-битови незнакови стойности на символ, както следва:
dmaConfig.SRCADDRH=(без подпис Чар)((без подпис int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(без подпис Чар)((без подпис int)&sourceString);

За този тип често използвана функция, можем да я абстрахираме като обща функция, както следва:
#define SET_WORD(destH,destL,word)
    правя{
       destH=(без подпис Чар)((без подпис int)дума >>8);     
       destL=(без подпис Чар)((без подпис int)word);
    }докато(0)

В бъдеще, когато трябва да извършите подобна операция по разделяне, можете да я извикате директно, както следва:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &sourceString);


  (2) Активиране на конфигурацията: Първо, първият адрес на структурата&dmaConfigВисоките/ниските 8 бита се присвояват съответно на SFRDMA0CFGHи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 единично семплиране
Следващ:Zigbee Journey (8): Няколко важни основни експеримента с CC2430 - watchdogs
Отричане:
Целият софтуер, програмни материали или статии, публикувани от Code Farmer Network, са само за учебни и изследователски цели; Горното съдържание не трябва да се използва за търговски или незаконни цели, в противен случай потребителите ще понесат всички последствия. Информацията на този сайт идва от интернет, а споровете за авторски права нямат нищо общо с този сайт. Трябва напълно да изтриете горното съдържание от компютъра си в рамките на 24 часа след изтеглянето. Ако ви харесва програмата, моля, подкрепете оригинален софтуер, купете регистрация и получете по-добри услуги. Ако има нарушение, моля, свържете се с нас по имейл.

Mail To:help@itsvse.com