Using DMA transfers can be used to continuously get or send a piece of information without taking up interruptions or delays, which is useful when communication is frequent or large pieces of information are transmitted.
The above table shows that to use USART1TX/RX we select Channels 4 and 5
1. DMA Transfer mode:
(1) Dma_mode_normal, when the channel is configured as non-cyclic mode, the DMA operation will no longer occur after the transfer is over (that is, the transfer count becomes 0). To start a new DMA transfer, you need 3 steps: When you turn off the DMA channel, re-write the number of transfers in the Dma_cndtrx register, and then turn the DMA back on.
void Dma1_channel5_irqhandler (void)
{///Because different interrupt sources have the same interrupt vector entry, it is necessary to determine the interrupt flag
if (Dma_getflagstatus (dma1_flag_ TC5) ==set)
{
dma_cmd (dma1_channel5,disable);//Turn off DMA channel
Dma_clearflag (DMA1_FLAG_TC5);//clear interrupt flag, otherwise it will be interrupted
Dma_setcurrdatacounter (dma1_channel5,uart_dma_buffsize);//Reset the number of transmissions, and when this number is reached again, it will go into an interrupt
. Dma_cmd (dma1_channel5,enable);//Enable DMA channel
}
}
(2) Dma_mode_circular, in the loop mode, at the end of the last transmission, the contents of the Dma_cndtrx register are automatically reloaded to its initial value, and the internal current peripheral/memory address register is reloaded to Dma_cparx/dma_ Cmarx the initial base address of the register setting.
2 . Connect the peripherals to the DMA
Set the serial 1 transmission to DMA mode:
Usart_dmacmd (USART1, Usart_dmareq_tx, ENABLE);
3, the data transmission
Use non-cyclic mode, with 1 above. (1) In the 3 steps to re-open the DMA, the data in the Uart_tx_buff is ready, then turn on the DMA, you can automatically send the data in the Uart_tx_buff, data transfer completed, into the interrupt Dma1_channel4_irqhandler
4, the data received
Using DMA interrupts to receive data, only receive fixed frame length data, usart receive a certain length of data, will enter the DMA interrupt.
To receive variable-length data, there are 3 ways to do this:
1. Connect the RX foot to the external pin of the clock, and when the serial port is out, you can use this timer to generate a timeout interrupt. This is a high-real-time, 1-byte real-time monitoring.
2. Do not change the hardware, turn on a timer to monitor the DMA receive, if the timeout is interrupted. This real-time is not high, because the time-out must be greater than the time required to receive frames, precision is not control.
3.stm32 SCM Some serial port can monitor whether the bus is idle, if idle is interrupted. It can be used to monitor whether the DMA reception is complete. This is a very real-time approach. When the Usart in a byte after the stop bit time, the bus is idle, set the bus idle flag, then we believe that a frame of data transmission completed, will enter the Usart interrupt processing.
But one thing to note here is that if two frames of data are received next to each other, then this situation should use DMA interrupts. Because the Usart idle interrupt is used, all two frames are sent out to interrupt, so that only one frame of data can be processed, and with the DMA interrupt, the interrupt is reached at the end of the first frame, even if the second frame is followed.
The third method is used in the code.
"Reference"
http://blog.csdn.net/jdh99/article/details/8444474
Http://blog.chinaunix.net/uid-21658993-id-3030728.html