Wiki
Clone wikiMilandr / USART DMA
Принцип работы примера
По инициализации счетчика и режима DMA (запись в соответствующий элемент массива DMA_ControlTable[]) и включению канала DMA производится передача массива SendBuff[] по UART. После окончания передачи происходит прерывание и вручную выставляется флаг означающий что передача закончена, также отключаются запросы DMA от UART (иначе программа не выйдет из прерывания из-за особенности контроллера). После этого в основном цикле происходит инициализация счетчика DMA и включение запросов от UART.
#!c void Initialize_DMA (void) { DMA_CtrlDataTypeDef DMA_CtrlDataStructure; // Структура управляющих данных RST_CLK_PCLKcmd((RST_CLK_PCLK_SSP1 | RST_CLK_PCLK_SSP2),ENABLE); /* Disable all interrupt */ NVIC->ICPR[0] = 0xFFFFFFFF; NVIC->ICER[0] = 0xFFFFFFFF; RST_CLK_PCLKcmd(RST_CLK_PCLK_DMA, ENABLE); // enables or disables the RTCHSE clock. DMA_DeInit(); // Deinitializes the DMA registers to their default reset values. /* USART1_TX DMA */ DMA_CtrlDataInitUART.DMA_SourceBaseAddr = (uint32_t) &SendBuff; DMA_CtrlDataInitUART.DMA_DestBaseAddr = (uint32_t) &(MDR_UART1->DR); DMA_CtrlDataInitUART.DMA_SourceIncSize = DMA_SourceIncByte; DMA_CtrlDataInitUART.DMA_DestIncSize = DMA_DestIncNo; DMA_CtrlDataInitUART.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_CtrlDataInitUART.DMA_Mode = DMA_Mode_Stop; DMA_CtrlDataInitUART.DMA_CycleSize = 10; DMA_CtrlDataInitUART.DMA_NumContinuous = DMA_Transfers_16; DMA_StructInit(&DMA_ChannelInitStructure); // Fills each DMA_InitStruct member with its default value. DMA_ChannelInitStructure.DMA_PriCtrlData = &DMA_CtrlDataInitUART; DMA_ChannelInitStructure.DMA_Priority = DMA_Priority_Default; DMA_ChannelInitStructure.DMA_UseBurst = DMA_BurstClear; DMA_ChannelInitStructure.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY; DMA_Init(DMA_Channel_UART1_TX, &DMA_ChannelInitStructure); // Initializes the DMA Channel according to the specified parameters in the DMA_InitStruct. DMA_Cmd(DMA_Channel_UART1_TX, ENABLE); NVIC_EnableIRQ(DMA_IRQn); }
#!c int main(void) { Peripherals_Hardware_Startup(); /* Infinite loop */ while (1) { i++; if (USART_Ready) { USART_Ready = 0; PORT_WriteBit(MDR_PORTA, PORT_Pin_0, (BitAction) (1)); // Включаем светодиод /* Переинициализация управляющей структуры новым значением счетчика запросов и установка режима ДМА */ DMA_ControlTable[DMA_Channel_UART1_TX].DMA_Control |= ((10 - 1) << 4) | DMA_Mode_Basic; /* Включение канала DMA */ DMA_Cmd(DMA_Channel_UART1_TX, ENABLE); /* Включение запросов DMA от UART */ UART_DMACmd(MDR_UART1, UART_DMA_TXE, ENABLE); // Enables or disables the UART DMA interface. } PORT_WriteBit(MDR_PORTA, PORT_Pin_0, (BitAction) (0)); // Выключаем светодиод } }
#!c void DMA_IRQHandler(void) { UART_DMACmd(MDR_UART1, UART_DMA_TXE, DISABLE); // Enables or disables the UART DMA interface. USART_Ready = 1; j++; }
Updated