Wiki

Clone wiki

Milandr / 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