Skocz do zawartości

Kurs STM32 - #8 - DMA, czyli bezpośredni dostęp do pamięci


Komentator

Pomocna odpowiedź

html_mig_img
W części 6 kursu STM32 poznaliśmy możliwości przetwornika ADC. Uruchamiane przykłady były jednak niedoskonałe.Teraz poznamy nową, efektywną metodę. Zamiast aktywnie czekać na odczyt, wykorzystamy moduł DMA, który będzie robił to w tle.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Link do komentarza
Share on other sites

Mam pytanie, już jakiś czas szukam dokumentacji do tej biblioteki.

Niestety znalazłem tylko dokumentację do wersji 1.1 http://www.st.com/web/en/resource/technical/document/user_manual/DM00023896.pdf . W tym kursie korzystamy z wersji 3.6, bo taka ściąga się automatycznie przy tworzeniu projektu. Czy ST stworzyło dokumentację do wersji trzeciej?

Link do komentarza
Share on other sites

Jeśli pobierzesz bibliotekę niezależnie od OpenSTM32, w archiwum znajdziesz programy przykładowe oraz dokumentację wygenerowaną na podstawie kodu (DoxyGen). Poza tym zostaje czytanie dostępnych książek, wujek google oraz oczywiście kurs na Forbocie.

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257890#

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Witam

Sprawdziłem działanie kodu szybkości kopiowania CPU vs DMA u siebie i nie mogę zrozumieć pewnej rzeczy. Gdy program jest skompilowany w DEBUG czasy pokrywają się z tymi z fotki z artykułu. Natomiast gdy skompiluję jako RELEASE, wówczas sytuacja jest całkiem inna.

Czy jest mi ktoś w stanie to wyjaśnić ?

Na załączonej fotce - 2 pierwsze wpisy - kompilacja DEBUG, kolejne 2 - kompilacja RELEASE

Pozdrawiam

Link do komentarza
Share on other sites

Problem z optymalizatorem jest taki, że może uznać pewne fragmenty programu za niepotrzebne... Prawdopodobnie uznał, że kopiujesz dane, ale ich nie używasz, więc można ten fragment programu usunąć... W przypadku typowych programów pracujących na komputerze stacjonarnym takie optymalizacje mogą oszczędzać sporo czasu procesora. Jednak w przypadku mikrokontrolerów są często źródłem problemów. Właśnie dlatego zmienne modyfikowane w przerwaniach powinny być oznaczane jako volatile. Inaczej optymalizator może uznać, że skoro wartości nie są zmieniane, to można zupełnie usunąć dostęp do nich.

Link do komentarza
Share on other sites

Zad 8.1

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "stm32f10x.h"

#define        BUFFER_SIZE            32

uint8_t        src_buffer[BUFFER_SIZE];
uint8_t        dst_buffer[BUFFER_SIZE];

/*---------------------------------------------------------------*/

void copy_cpu()
{
   int i;
   for (i = 0; i < BUFFER_SIZE;i++)
       dst_buffer[i] = src_buffer[i];
}

void copy_dma()
{
   DMA_Cmd(DMA1_Channel1, ENABLE);
   while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
}

/*---------------------------------------------------------------*/

void send_char(char c)
{
   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   USART_SendData(USART2, c);
}

int __io_putchar(int c)
{
if (c=='\n')
send_char('\r');
send_char(c);
return c;
}

int main(void)
{
   USART_InitTypeDef uart;
   GPIO_InitTypeDef gpio;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

GPIO_StructInit(&gpio);
gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio);


   USART_StructInit(&uart);
   uart.USART_BaudRate = 115200;
   USART_Init(USART2, &uart);

   USART_Cmd(USART2, ENABLE);

   int i;
   DMA_InitTypeDef dma;

   DMA_StructInit(&dma);
   dma.DMA_PeripheralBaseAddr = (uint32_t)src_buffer;
   dma.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
   dma.DMA_MemoryBaseAddr = (uint32_t)dst_buffer;
   dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
   dma.DMA_BufferSize = BUFFER_SIZE;
   dma.DMA_M2M = DMA_M2M_Enable;
   DMA_Init(DMA1_Channel1, &dma);

   // wypelniamy bufor przykladowymi danymi
   for (i = 0; i < BUFFER_SIZE; i++)
       src_buffer[i] = 100 + i;

   //copy_cpu();
   copy_dma();


        printf("Hello World!\n");

        if(strncmp ((const char*)src_buffer, (const char*)dst_buffer, BUFFER_SIZE) == 0)
        {
            printf("ALL OK\n");
        }
        else
        {
            printf("try again\n");
        }

   while(1)
   {

   }
}
  • Pomogłeś! 1
Link do komentarza
Share on other sites

TTakitani, raczej nie (? - może ktoś bardziej doświadczony powie, że tak) 🙂 Osobiście nie miałem nigdy takich problemów, ale robiłem zawsze to po kolei "na logikę". Czyli zanim konfigurowałem GPIO upewniałem się, że peryferia są uruchomione i odpowiednio taktowane itd.

Link do komentarza
Share on other sites

/*http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf*/ //pp.233

typedef uint32_t uint; //this is "the unsigned int" or "the unsigned" variable type ;D

uint t1 = *( uint* )0xE0001004; //DWT_CYCCNT

uint t2 = *( uint* )0xE0001004;

uint elapsedClkTics = t2 - t1; //divide by HSI freq. to obtain elapsed seconds

Link do komentarza
Share on other sites

Mam kłopot z obsługą DMA.

Mianowicie potrzebuję zapisać (szybkie) odczyty z jednego wejścia analogowego do tablicy 256-elementowej. Następnie przetwarzanie danych i kolejne odczyty w nieskończonej pętli.

W kursie jest kopiowanie dwóch tablic, albo zapis odczytu z każdego wejścia analogowego do 1 elementu tablicy. Ale czy można z wielu odczytów zrobić tablicę nie opóźniając kolejnych odczytów? Po serii 256 odczytów może być już "zwykłe" kopiowanie itd.

Konkretnie chodzi mi implementację FFT i zależy mi na szybkich odczytach.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.