程序使用DMA傳輸,需要使用DMA傳輸完成中斷,程序如下:
void DMA2_Stream7_IRQHandler(void)
{
static u16 cnt = 0 ;
if(DMA_GetITStatus(DMA2_Stream7,DMA_FLAG_TCIF7)==SET) //檢查DMA傳輸完成中斷
{
DMA_ClearITPendingBit(DMA2_Stream7,DMA_FLAG_TCIF7); //Clear the IT flag
}
}
ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)
{
ITStatus bitstatus = RESET;
DMA_TypeDef* DMAy;
uint32_t tmpreg = 0, enablestatus = 0;
/* Check the parameters */
assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
assert_param(IS_DMA_GET_IT(DMA_IT));
/* Determine the DMA to which belongs the stream */
if (DMAy_Streamx < DMA2_Stream0)
{
/* DMAy_Streamx belongs to DMA1 */
DMAy = DMA1;
}
else
{
/* DMAy_Streamx belongs to DMA2 */
DMAy = DMA2;
}
/* Check if the interrupt enable bit is in the CR or FCR register */
if ((DMA_IT & TRANSFER_IT_MASK) != (uint32_t)RESET)
{
/* Get the interrupt enable position mask in CR register */
tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK);
/* Check the enable bit in CR register */
enablestatus = (uint32_t)(DMAy_Streamx->CR & tmpreg);
}else
{
/* Check the enable bit in FCR register */
enablestatus = (uint32_t)(DMAy_Streamx->FCR & DMA_IT_FE);
}
/* Check if the interrupt pending flag is in LISR or HISR */
if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET)
{
/* Get DMAy HISR register value */
tmpreg = DMAy->HISR ;
}
else
{
/* Get DMAy LISR register value */
tmpreg = DMAy->LISR ;
}
/* mask all reserved bits */
tmpreg &= (uint32_t)RESERVED_MASK;
/* Check the status of the specified DMA interrupt */
if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
{
/* DMA_IT is set */
bitstatus = SET;
}
else
{
/* DMA_IT is reset */
bitstatus = RESET;
}
/* Return the DMA_IT status */
return bitstatus;
}```
發現DMA傳輸完成後,if內程序無法進入處理。逐步調試發現其函數 DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)中傳遞的參數DMA_FLAG_TCIF7存在問題,現將問題記錄如下:
函數內其中DMA_IT傳遞的是DMA_IT_TCIF7,如下
DMA_IT: specifies the DMA interrupt source to check.
* This parameter can be one of the following values:
* @arg DMA_IT_TCIFx: Streamx transfer complete interrupt
* @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt
* @arg DMA_IT_TEIFx: Streamx transfer error interrupt
* @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt
* @arg DMA_IT_FEIFx: Streamx FIFO error interrupt
其在stm32F4XX.h文件中的定義如下:
#define DMA_FLAG_FEIF0 ((uint32_t)0x10800001)
#define DMA_FLAG_DMEIF0 ((uint32_t)0x10800004)
#define DMA_FLAG_TEIF0 ((uint32_t)0x10000008)
#define DMA_FLAG_HTIF0 ((uint32_t)0x10000010)
#define DMA_FLAG_TCIF0 ((uint32_t)0x10000020)
#define DMA_FLAG_FEIF1 ((uint32_t)0x10000040)
#define DMA_FLAG_DMEIF1 ((uint32_t)0x10000100)
#define DMA_FLAG_TEIF1 ((uint32_t)0x10000200)
#define DMA_FLAG_HTIF1 ((uint32_t)0x10000400)
#define DMA_FLAG_TCIF1 ((uint32_t)0x10000800)
#define DMA_FLAG_FEIF2 ((uint32_t)0x10010000)
#define DMA_FLAG_DMEIF2 ((uint32_t)0x10040000)
#define DMA_FLAG_TEIF2 ((uint32_t)0x10080000)
#define DMA_FLAG_HTIF2 ((uint32_t)0x10100000)
#define DMA_FLAG_TCIF2 ((uint32_t)0x10200000)
#define DMA_FLAG_FEIF3 ((uint32_t)0x10400000)
#define DMA_FLAG_DMEIF3 ((uint32_t)0x11000000)
#define DMA_FLAG_TEIF3 ((uint32_t)0x12000000)
#define DMA_FLAG_HTIF3 ((uint32_t)0x14000000)
#define DMA_FLAG_TCIF3 ((uint32_t)0x18000000)
#define DMA_FLAG_FEIF4 ((uint32_t)0x20000001)
#define DMA_FLAG_DMEIF4 ((uint32_t)0x20000004)
#define DMA_FLAG_TEIF4 ((uint32_t)0x20000008)
#define DMA_FLAG_HTIF4 ((uint32_t)0x20000010)
#define DMA_FLAG_TCIF4 ((uint32_t)0x20000020)
#define DMA_FLAG_FEIF5 ((uint32_t)0x20000040)
#define DMA_FLAG_DMEIF5 ((uint32_t)0x20000100)
#define DMA_FLAG_TEIF5 ((uint32_t)0x20000200)
#define DMA_FLAG_HTIF5 ((uint32_t)0x20000400)
#define DMA_FLAG_TCIF5 ((uint32_t)0x20000800)
#define DMA_FLAG_FEIF6 ((uint32_t)0x20010000)
#define DMA_FLAG_DMEIF6 ((uint32_t)0x20040000)
#define DMA_FLAG_TEIF6 ((uint32_t)0x20080000)
#define DMA_FLAG_HTIF6 ((uint32_t)0x20100000)
#define DMA_FLAG_TCIF6 ((uint32_t)0x20200000)
#define DMA_FLAG_FEIF7 ((uint32_t)0x20400000)
#define DMA_FLAG_DMEIF7 ((uint32_t)0x21000000)
#define DMA_FLAG_TEIF7 ((uint32_t)0x22000000)
#define DMA_FLAG_HTIF7 ((uint32_t)0x24000000)
#define DMA_FLAG_TCIF7 ((uint32_t)0x28000000)
其中:/* Get the interrupt enable position mask in CR register */
tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK); 中TRANSFER_IT_ENABLE_MASK爲0x001E,主要要獲得當前中斷是否被設置(參加數據手冊),設置在CR寄存器的低4位。
,好決定在語句if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))是否返回。以爲的目的就是是的中斷標識的置位段處於低四位。我使用的是DMA2_Stream7,從頭文件定義可以看出DMA_FLAG_TCIF7>>11後,根本不會得到想要的結果,其他DMA中斷也會一樣。
由於不想修改系統庫文件,所以採用寄存器操作
void DMA2_Stream7_IRQHandler(void)
{
static u16 cnt = 0 ;
if(DMA2->HISR & 0x08000000) //檢查DMA傳輸完成中斷
{
DMA_ClearITPendingBit(DMA2_Stream7,DMA_FLAG_TCIF7); //Clear the IT flag
}
則中斷可以正常處理了。