Wiki
Clone wikiMilandr / Непрерывная выдача DAC + DMA
Конфиг переферии
ЦАП
#!c RST_CLK_PCLKcmd(RST_CLK_PCLK_DAC, ENABLE); DAC_DeInit(); DAC_Init(DAC_SYNC_MODE_Independent, DAC1_AVCC, DAC2_AVCC); DAC2_Cmd(ENABLE);
Таймер для тактирования ДМА
#!c /* TIMER2 Configuration ------------------------------------------------- DAC out 2400hz */ RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER2, ENABLE); TIMER_DeInit(MDR_TIMER2); // Deinitializes the TIMERx peripheral registers to their default reset values. TIMER_CntStructInit(&TIMER_CntInitStructure); // Fills each TIMER_CntInitStruct member with its default value. TIMER_CntInitStructure.TIMER_Prescaler = 0; TIMER_CntInitStructure.TIMER_Period = 80000000/2400/512-1; TIMER_CntInit(MDR_TIMER2, &TIMER_CntInitStructure); // Initializes the TIMERx Counter peripheral according to the specified parameters in the TIMER_CntInitStruct. TIMER_BRGInit(MDR_TIMER2,TIMER_HCLKdiv1); /* Enable TIMER1 clock */ TIMER_Cmd(MDR_TIMER2, ENABLE); // Enables or disables the specified TIMER peripheral. TIMER_DMACmd(MDR_TIMER2, TIMER_STATUS_CNT_ARR, ENABLE);
ДМА для передачи из памяти в ЦАП
#!c /* DMA Timer2 */ /* Set Primary Control Data */ DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&SinusArray[0]); DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)&(MDR_DAC->DAC2_DATA); DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword; DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncNo; DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong; DMA_PriCtrlStr.DMA_CycleSize = 256; DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1; DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged; DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged; /* Set Alternate Control Data */ DMA_AltCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&SinusArray[256]); DMA_AltCtrlStr.DMA_DestBaseAddr = (uint32_t)&(MDR_DAC->DAC2_DATA); DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword; DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncNo; DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong; DMA_AltCtrlStr.DMA_CycleSize = 256; DMA_AltCtrlStr.DMA_NumContinuous = DMA_Transfers_1; DMA_AltCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged; DMA_AltCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged; /* Set Channel Structure */ DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr; DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr; DMA_InitStr.DMA_Priority = DMA_Priority_Default; DMA_InitStr.DMA_UseBurst = DMA_BurstClear; DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY; DMA_Init(DMA_Channel_TIM2, &DMA_InitStr); // Initializes the DMA Channel according to the specified parameters in the DMA_InitStruct. DMA_Cmd(DMA_Channel_TIM2, ENABLE); // Enables or disables the specified DMA Channel.
Прерывания
#!c void DMA_IRQHandler(void) { if (!(DMA_ControlTable[DMA_Channel_TIM2].DMA_Control & 0x3)) // DMA_Channel_TIM2 PRIMARY { /* CHNL_PRI_ALT_SET = 1 Используется альтернативная конфигурация (получены значения с основной конфигурации) */ /* Обновляются значения в основной конфигурации */ if (((MDR_DMA->CHNL_PRI_ALT_SET >> DMA_Channel_TIM2) & 1) == 1) { DMA_ControlTable[DMA_Channel_TIM2].DMA_Control |= ((256 - 1) << 4) | DMA_Mode_PingPong; } DMA_Cmd(DMA_Channel_TIM2, ENABLE); } if (!(DMA_ControlTable[DMA_Channel_TIM2+32].DMA_Control & 0x3)) // DMA_Channel_TIM2 ALTERNATIVE { /* CHNL_PRI_ALT_SET = 0 Используется основная конфигурация (получены значения с альтернативной конфигурации) */ /* Обновляются значения в альтернативной конфигурации */ if (((MDR_DMA->CHNL_PRI_ALT_SET >> DMA_Channel_TIM2) & 1) == 0) { DMA_ControlTable[DMA_Channel_TIM2+32].DMA_Control |= ((256 - 1) << 4) | DMA_Mode_PingPong; } DMA_Cmd(DMA_Channel_TIM2, ENABLE); } }
Updated