Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 8951|Odpowiedź: 0

Podróż Zigbee (7): Kilka ważnych podstawowych eksperymentów CC2430 – transmisja DMA

[Skopiuj link]
Opublikowano 30.10.2014 23:22:16 | | | |
1. Połączenie górnego i dolnego poziomu

W poprzedniej części rozmawialiśmy o użyciu ADC i pobieraliśmy próbkę z czujnika temperatury na chipie. W rzeczywistych projektach liczba czujników jest często duża i należy przetworzyć dużą ilość danych konwersji. Przenoszenie tych danych wywiera duże obciążenie na procesor. Aby odciążyć procesor i dać mu energię do innych zadań, przyda się DMA (Direct Memory Access)~

Poniższe wprowadzenie jest fragmentem Zigbee Technology Practice Tutorial:

DMA to skrót od bezpośredniego dostępu do pamięci, czyli "bezpośredni dostęp do pamięci". Jest to tryb transmisji danych o dużej prędkości, w którym urządzenia peryferyjne, takie jak transceivery ADC/UART/RF i pamięć, mogą wymieniać dane bezpośrednio pod kontrolą "kontrolera DMA" bez minimalnej ingerencji CPU. Oprócz wykonania niewielkiego przetwarzania na początku i końcu transferu, procesor może wykonywać inne zadania podczas transferu. W ten sposób CPU i te interakcje z danymi działają równolegle przez większość czasu. W rezultacie ogólna wydajność systemu może zostać znacznie poprawiona.

Jak widać we wstępie, DMA może być stosowana w wielu sytuacjach. Ten eksperyment obejmuje jedynie najprostszą transmisję DMA i ma na celu pokazanie ogólnego zastosowania DMA. Jeśli chodzi o zastosowanie DMA w innych scenariuszach, zostanie ono wdrożone w kompleksowych eksperymentach w przyszłości.

2. Eksperyment transmisji DMA(1) Wprowadzenie do eksperymentu

Znaki tablicysourceStringZawartość jest przesyłana do tablicy znaków za pomocą DMAdestString, wynik konwersji jest wyświetlany na PC przez port szeregowy.

(2) Schemat przepływu programu

(3) Kod źródłowy eksperymentalny i analiza/*
    Opis eksperymentalny: Zawartość array sourceString jest przesyłana do array array destString przez DMA, a wynik konwersji jest wyświetlany na komputerze przez port szeregowy.
*/

#include

#define prowadził1 P1_0         
#define LED2 P1_1         
#define LED3 P1_2         
#define LED4 P1_3

/*用于配置DMA的结构体
-------------------------------------------------------*/
#pragma bitfield=odwrócone
typedef struct
{
  Niepodpisany charSRCADDRH;           //源地址高8位
  Niepodpisany charSRCADDRL;           //源地址低8位
  Niepodpisany charDESTADDRH;         //目的地址高8位
  Niepodpisany charDESTADDRL;         //目的地址低8位
  Niepodpisany charVLEN :3;     //长度域模式选择
  Niepodpisany charLENH :5;     //传输长度高字节
  Niepodpisany charLENL :8;     //传输长度低字节
  Niepodpisany charROZMIAR SŁOWA:1;     //字节(byte)或字(word)传输
  Niepodpisany charTMODE :2;     //传输模式选择
  Niepodpisany charTRYGONOMETRIA:5;     //触发事件选择
  Niepodpisany charSRCINC :2;     //源地址增量:-1/0/1/2
  Niepodpisany charDESTINC:2;     //目的地址增量:-1/0/1/2
  Niepodpisany charIRQMASK :1;     //中断屏蔽
  Niepodpisany charM8 :1;     //7或8bit传输长度,仅在字节传输模式下适用
  Niepodpisany charPRIORYTET:2;     //优先级
}DMA_CFG;
#pragma bitfields=domyślne

/*系统时钟初始化
-------------------------------------------------------*/
pustkaxtal_init(pustka)
{
  SEN &= ~0x04;            //都上电
  podczas gdy(! (SEN &0x40));     //晶体振荡器开启且稳定
  CLKCON &= ~0x47;            Wybierz oscylator kryształowy 32MHz
  SEN |=0x04;
}

/*LED初始化
-------------------------------------------------------*/
pustkaled_init(pustka)
{
  P1SEL =0x00;         P1 to zwykły port I/O
  P1DIR |=0x0F;         P1.0 P1.1 P1.2 P1.3 wyjście
  
  led1 =1;               //关闭所有LED
  led2 =1;
  led3 =1;
  led4 =1;
}

/*UART0通信初始化
-------------------------------------------------------*/
pustkaUart0Init(Niepodpisany charStopBits,Niepodpisany charParytet)
{
   P0SEL |=  0x0C;                  //初始化UART0端口,设置P0.2与P0.3为外部设备IO口
   PERCFG&= ~0x01;                  Wybierz UART0 jako pierwszą opcjonalną pozycję, czyli RXD do P0.2 i TXD do P0.3
   
   U0CSR =0xC0;                    Ustaw tryb UART i włącz akceptor
   
   U0GCR =11;
   U0BAUD =216;                    //设置UART0波特率为115200bps
   
   U0UCR |= StopBits| Równość;        //设置停止位与奇偶校验
}

/*UART0发送数据
-------------------------------------------------------*/
pustka  Uart0Send(Niepodpisany chardane)
{
  podczas gdy(U0CSR&0x01);   //等待UART空闲时发送数据
  U0DBUF = dane;
}

/*UART0发送字符串
-------------------------------------------------------*/
pustkaUart0SendString(Niepodpisany char*s)
{
  podczas gdy(*s !=0)         //依次发送字符串s中的每个字符
    Uart0Send(*s++);
}

/*主函数
-------------------------------------------------------*/
pustkamain(pustka)
{
  DMA_CFG dmaConfig;      //定义配置结构体
  
  Niepodpisany charsourceString[]="Jestem sourceString!";      //源字符串
  Niepodpisany chardestString[sizeof(sourceString)] ="Jestem destString!";  //目的字符串
  
  chari;
  charbłąd=0;
  
  xtal_init();            //系统时钟初始化
  led_init();
  Uart0Init(0x00,0x00);   //UART初始化
  
  Uart0SendString(sourceString);         //传输前的原字符数组
  Uart0SendString(destString);           //传输前的目的字符数组
  
  //配置DMA结构体
  dmaConfig.SRCADDRH=(Niepodpisany char)((Niepodpisany int)&sourceString >>8);     //源地址
  dmaConfig.SRCADDRL=(Niepodpisany char)((Niepodpisany int)&sourceString);
   
  dmaConfig.DESTADDRH=(Niepodpisany char)((Niepodpisany int)&destString >>8);      //目的地址
  dmaConfig.DESTADDRL=(Niepodpisany char)((Niepodpisany int)&destString);
  
  dmaConfig.VLEN=0x00;         //选择LEN作为传送长度
  
  dmaConfig.LENH=(Niepodpisany char)((Niepodpisany int)sizeof(sourceString) >>8);  //传输长度
  dmaConfig.LENL=(Niepodpisany char)((Niepodpisany int)sizeof(sourceString));
  
  dmaConfig.WORDSIZE=0x00;     //选择字节(byte)传送
  
  dmaConfig.TMODE=0x01;        //选择块传送(block)模式
  
  dmaConfig.TRIG=0;            Brak spustu (można to rozumieć jako ręczne uruchamianie)
  
  dmaConfig.SRCINC=0x01;      //源地址增量为1
  
  dmaConfig.DESTINC=0x01;      //目的地址增量为1
  
  dmaConfig.IRQMASK=0;         //DMA中断屏蔽
   
  dmaConfig.M8=0x00;           //选择8位长的字节来传送数据
  
  dmaConfig.PRIORITY=0x02;     //传输优先级为高
  

  DMA0CFGH=(Niepodpisany char)((Niepodpisany int)&dmaConfig >>8);   //将配置结构体的首地址赋予相关SFR
  DMA0CFGL=(Niepodpisany char)((Niepodpisany int)&dmaConfig);
  
  DMAARM=0x01;                 //启用配置
  
  DMAIRQ=0x00;                 //清中断标志
  DMAREQ=0x01;                 //启动DMA传输
  
  podczas gdy(! (DMAIRQ&0x01));               //等待传输结束
  
  dla(i=0; i <sizeof(sourceString); i++)   //校验传输的正确性
  {
    jeśli(sourceString!=destString)
      błąd++;
  }
  
  jeśli(błąd==0)                          //将结果通过串口传输到PC
  {
    Uart0SendString("Zgadza się!");
    Uart0SendString(destString);        //传输后的目的字符数组
  }
  else
    Uart0SendString("Błąd!");

  podczas gdy(1);
}

Podstawowy proces korzystania z DMA to:Konfiguruj DMAWłącz konfiguracjęRozpocznij transfer DMA → Poczekaj na zakończenie transferu DMA.Następujące są odpowiednio:

  (1) Konfiguruj DMA: Przede wszystkim DMA musi być skonfigurowana, ale konfiguracja DMA jest specjalna: zamiast bezpośrednio przypisywać wartości niektórym SFR, definiuje strukturę zewnętrznie, przypisuje jej wartości, a następnie przypisuje wysokie 8 bitów pierwszego adresu tej strukturyDMA0CFGH, co daje mu niższe 8 cyfrDMA0CFGL。 (Szczegółowe instrukcje dotyczące struktury konfiguracji można znaleźć w chińskim podręczniku CC2430)

Porady CC2430
Istnieją dwa punkty, które warto wyjaśnić dotyczące definicji struktur konfiguracyjnych w powyższym kodzie źródłowym:
(1) Dziedzina bitowa
Przy definiowaniu tej struktury używa się wielu dwukropków (:), po których następuje liczba, która nazywana jest "polem bitowym":
Domena bitowa oznacza, że informacje nie muszą zajmować pełnego bajtu podczas przechowywania, lecz jedynie kilka lub jeden bit binarny. Na przykład, podczas przechowywania wielkości przełączającej istnieją tylko dwa stany, 0 i 1, i można użyć binarnego jednego bitu. Aby zaoszczędzić miejsce na dysku i ułatwić przetwarzanie, C udostępnia strukturę danych zwaną "pole bitowe" lub "pole bitowe". Tak zwane "pole bitowe" dzieli binarne w bajcie na kilka różnych regionów i opisuje liczbę bitów w każdym z nich. Każda domena ma nazwę domeny, co pozwala na operacje według nazwy domeny w programie. Pozwala to na reprezentację kilku różnych obiektów w bajtowym binarnym polu bitowym.
(2) Abstrakcyjne funkcje wspólne
Uważni czytelnicy zauważą, że przypisanie wartości strukturze często wiąże się z przypisaniem 16-bitowej wartości typu int bez znaku dwóm 8-bitowym wartościom typu postaci bez znaku, w następujący sposób:
dmaConfig.SRCADDRH=(Niepodpisany char)((Niepodpisany int)&sourceString >>8);     //源地址
dmaConfig.SRCADDRL=(Niepodpisany char)((Niepodpisany int)&sourceString);

Dla tego typu często używanej funkcji można równie dobrze abstrahować ją jako funkcję ogólną, w następujący sposób:
#define SET_WORD(destH, destL, słowo)
    robić{
       destH=(Niepodpisany char)((Niepodpisany int)słowo >>8);     
       destL=(Niepodpisany char)((Niepodpisany int)słowo);
    }podczas gdy(0)

W przyszłości, gdy będziesz musiał wykonać podobną operację dzielenia, możesz ją wywołać bezpośrednio, w następujący sposób:
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL i sourceString);


  (2) Włączenie konfiguracji: Po pierwsze, pierwsze adresowanie struktury&dmaConfigWysokie/niskie 8 bitów przypisuje się odpowiednio SFRDMA0CFGHiDMA0CFGL(gdzie 0 oznacza konfigurację kanału 0, CC2430 zawiera 5 kanałów DMA, kanał 0 jest używany tutaj). TakDMAARM.0Przypisz wartość 1, aby umożliwić konfigurację kanału 0 tak, aby kanał 0 był w trybie pracy.

  (3) Umożliwienie transmisji DMA:PrawyDMAREQ.0Przypisz wartość 1, aby rozpocząć transmisję DMA kanału 0.

  (4) Czekać na przesłanie DMA:Po przesłaniu DMA kanału 0 zostanie wywołane przerwanie, a flaga przerwania kanału 0 zostanie wywołanaDMAIRQ.0zostanie automatycznie ustawione na 1. Następnie każdy znak z dwóch ciągów jest porównywany, a wynik weryfikacji jest przesyłany do komputera PC.

(4) Wyniki eksperymentalne

Najpierw otwórz narzędzie do debugowania portów szeregowych, a następnie rozpocznij debugowanie CC2430, a pojawi się następujący ekran:

ZnajdzieszdestStringTreść została całkowicie ujawnionasourceStringwypełniony.

Gotowe~

3. Podsumowanie

Ta sekcja wprowadza zastosowanie DMA, choć jest bardzo proste, ale myślę, że zrozumiałeś podstawowe zastosowanie DMA i możesz je spokojnie analizować, gdy w przyszłości spotkasz się z jego złożonymi scenariuszami użycia.

Bez względu na to, jak dobry jest komputer stacjonarny, zawiesza się, podobnie system wbudowany nieuchronnie się zatrzymuje. W następnej sekcji przedstawimy bardzo skuteczną metodę systematycznego resetu: watchdogs.






Poprzedni:Podróż Zigbee (6): Kilka ważnych podstawowych eksperymentów CC2430 - pojedyncze próbkowanie ADC
Następny:Podróż Zigbee (8): Kilka ważnych podstawowych eksperymentów CC2430 – watchdogi
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com