====== 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]] {{ :courses:b2m37mam:labs:mam_2023-cviceni_13.pdf | Podklady pro 13. cvičení-Skalický}} ===== Projekty ===== ===== Kódy pro cvičení ===== ==== Inicializace DMA s TIM4_CH4 ==== 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 |= ?? << ADC_CR2_EXTSEL_Pos; // zdrojem udalosti je TIM4_CH4 ADC1->CR2 |= ?? << ADC_CR2_EXTEN_Pos; // reakce event triggeru RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA->MODER |= ??; // Nastaveni PA0 na analogovy mod // DMA cast nastaveni RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // povoleni hodin do DMA2 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 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 TIM4 pro ADC ==== void initTIM4(void){ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // povoleni hodin do bloku TIM4 TIM4->PSC = 160; TIM4->ARR = 1000; // povoleni compare mode (output) a vybereme PWM rezim TIM4->CCMR2 |= (0x00 << TIM_CCMR2_CC4S_Pos) | (0x07 << TIM_CCMR2_OC4M_Pos); TIM4->CCR4 = 5; TIM4->CCER |= TIM_CCER_CC4E; TIM4->CR1 |= TIM_CR1_CEN; // spustime casovac TIM4 } ==== Hlaní program ==== int main(void){ initADC1_DMA(); initTIM4(); while (1){ if(DMA2->LISR & DMA_LISR_TCIF0){ DMA2->LIFCR |= DMA_LIFCR_CTCIF0; // zpracovani dat - data jsou ulozena v promenne ADC1_DMA_Result; } } }