====== 13. DMA ====== ===== Cíle cvičení ===== - Seznámit se s konfigurací přímého přístupu do paměti (Direct Memory Access - DMA), který bude ukládat data z AD převodníku do paměti bez zásahu programu ===== Co je třeba si připravit ===== ===== Podklady pro cvičení ===== {{ :courses:b2m37mam:labs:stm32f401re.pdf | Datasheet STM32F401 }} {{ :courses:b2m37mam:stm32f401_refmanual.pdf | Referenční manuál STM32F401 }} {{ :courses:b2m37mam:nucleo_64_pins.pdf | Datasheet Nucleo F401RE}} [[courses:b2m37mam:tutorials:dev_kits:nucleof401| Podklady pro Nucleo STM32F401]] ===== Projekty ===== ===== Kódy pro cvičení ===== ==== Inicializace DMA s TIM2 ==== uint16_t ADC1_DMA_Result; void initADC1_DMA(void){ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; ADC1->CR2 |= ADC_CR2_ADON; // povoleni ADC ADC1->SQR3 |= 0 << ADC_SQR3_SQ1_Pos; // vyber CH0 do sekvence SQ0 ADC1->SMPR2 |= 7 << ADC_SMPR2_SMP0_Pos; // nastaveni prevodu CH0 na 480 cyklu ADC1->CR2 |= 0x06 << ADC_CR2_EXTSEL_Pos; // zdrojem udalosti je TIM2 TRGO ADC1->CR2 |= 0x01 << ADC_CR2_EXTEN_Pos; // reakce event triggeru na nabeznou hranu RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA->MODER |= GPIO_MODE_ANALOG << GPIO_MODER_MODE0_Pos; // Nastaveni PA0 na analogovy mod // DMA cast nastaveni ADC1->CR2 |= ADC_CR2_DMA; // povoleni ADC pro DMA prenos //ADC1->CR2 |= ADC_CR2_CONT; // povoleni kontinualniho rezimu ADC1->CR2 |= ADC_CR2_DDS; // povoleni dalsich DMA pozadavku RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // povoleni hodin do DMA2 DMA2_Stream0->CR = (0x00 << DMA_SxCR_CHSEL_Pos); // vyber kanalu CH0 jako zdroj DMA pozadavku DMA2_Stream0->CR |= 0x01 << DMA_SxCR_MSIZE_Pos; // nastaveni velikosti dat v pameti bude 16 bitu DMA2_Stream0->CR |= 0x01 << DMA_SxCR_PSIZE_Pos; // nastaveni velikosti dat periferie na 16 bitu DMA2_Stream0->CR |= DMA_SxCR_CIRC; // nastaveni DMA na kruhovy rezim DMA2_Stream0->CR |= (0x00 << DMA_SxCR_DIR_Pos); // nastaveni smeru toku dat P->M DMA2_Stream0->NDTR = 1; // velikost bufferu dat DMA2_Stream0->M0AR = &ADC1_DMA_Result; // adresa pro ulozeni dat z DMA (do pameti) DMA2_Stream0->PAR = &ADC1->DR; // adresa zdroje dat pro DMA (z periferie) DMA2_Stream0->CR |= DMA_SxCR_EN; // spusteni DMA //ADC1->CR2 |= ADC_CR2_SWSTART; // spusteni A/D prevodniku } ==== Inicializace TIM2 ==== void initTIM2forADC(void){ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // povoleni hodin do bloku TIM2 TIM2->PSC = 16000; TIM2->ARR = 1000; TIM2->CR2 |= 0x02 << TIM_CR2_MMS_Pos; // Preteceni jako spoustec TIM2->CR1 |= TIM_CR1_CEN; // povolime casovac TIM2 } ==== Hlaní program ==== int main(void){ initADC1_DMA(); initTIM2forADC(); while (1){ if(DMA2->LISR & DMA_LISR_TCIF0){ DMA2->LIFCR |= DMA_LIFCR_CTCIF0; // zpracovani dat - data jsou ulozena v promenne ADC1_DMA_Result; } } }