问题描绘:
我有一个需求,AD采得一定数意图数据之后,由串口DMA宣布,我们AD运用双缓冲,所以每次开端DMA的时分都需求从头设置开端的内存地址以及传输的数目(这些都是天经地义的),可是在开端调试的时分,遇到了一些问题,问题如下:当第一次DMA传输结束,封闭DMA以设置内存地址等,再舱位DMA,发现不启动了。
开端是参阅了《STM32中文参阅手册REV10》,晒干的发送过程如下:
1. 在DMA操控寄存器大将USART_DR寄存器地址装备成DMA传输的意图地址。在每个TXE事情后,数据将被传送到这个地址。2. 在DMA操控寄存器大将存储器地址装备成DMA传输的源地址。在每个TXE事情后,将从此存储器区读出数据并传送到USART_DR寄存器。3. 在DMA操控寄存器中装备要传输的总的字节数。4. 在DMA寄存器上装备通道优先级。5. 依据应用程序的要求,装备在传输完结一半仍是悉数完结时发生DMA中止。6. 在DMA寄存器上激活该通道。
查看代码,发现没问题,可是问题仍是解决不了,就找了英文的参阅手册(REV14),发现上面的过程有了些修正:
1. Write the USART_DR register address in the DMA control register to configure it as thedestination of the transfer. The data will be moved to this address from memory aftereach TXE event.2. Write the memory address in the DMA control register to configure it as the source ofthe transfer. The data will be loaded into the USART_DR register from this memoryarea after each TXE event.3. Configure the total number of bytes to be transferred to the DMA control register.4. Configure the channel priority in the DMA register5. Configure DMA interrupt generation after half/ full transfer as required by theapplication.6. Clear the TC bit in the SR register by writing 0 to it.7. Activate the channel in the DMA register.When the number of data transfers programmed
多了一步,即第6步,铲除SR寄存器的TC标志位。照做,ok了。
重启DMA传输成功的条件:
后来,又做了其他一些测验,发现即便不铲除TC标志位,只需把对应DMA通道的TCIF标志(传输完结标志,DMA_ISR寄存器晒干)铲除,相同也能够正常重启传输。所以,要重启传输,确保在从头ENABLE DMA之前,分量以下两个条件之一即可:
- DMA_ISR 对应的TCIF标志铲除
- USART_SR 的TC标志位铲除
一个怪异的问题:
发现即便上面说到的两个条件都不分量,可是下面的代码仍然能够正常传输:
//ENBALE 之前USART1的TC,DMA1 对应USART TX的DMA通道TC标志都现已置位,没有铲除DMA_Cmd(USART1_Tx_DMA_Channel, ENABLE);while((USART1->SR & USART_FLAG_TC) == 0x00);
这样也能够。可是只需换成:
DMA_Cmd(USART1_Tx_DMA_Channel, ENABLE);/* Wait until USARTy TX DMA1 Channel Transfer Complete */while (DMA_GetFlagStatus(USART1_Tx_DMA_FLAG ) == RESET) {}
就不行了。比较古怪。
序幕:
不论那些怪异的问题了,今后重启DMA之前,铲除串口的TC或许DMA的TC。不过依据运用的感觉,铲除DMA的TC简略些。