MCU_STM32的HAL库中的宏DMA_FLAG_TCIF0_4/DMA_FLAG_TCIF1_5/DMA_FLAG_TCIF2_6/DMA_FLAG_TCIF3_7
宏定义的含义
造成中文手册误解的原因:有的把stream翻译成中文“通道”,这里我还是直接使用英文比较好;因为表中还有一个单词"channel",这个单词在中文里更容易被翻译成“通道”,但事实上这里只涉及stream。
当然,如果你手册看得比较细,就可以发现,标志位里面明确地提到了stream,而不是channel,如下所示
所以,总的说来,
DMA_FLAG_TCIF0_4就是指DMA的Stream0或Stream4, DMA_FLAG_TCIF1_5就是指DMA的Stream1或Stream5, DMA_FLAG_TCIF2_6就是指DMA的Stream2或Stream6, DMA_FLAG_TCIF3_7就是指DMA的Stream3或Stream7。
例如,在STM32F4xx系列中,使用DMA进行串口发送的时候,
串口1使用 DMA_FLAG_TCIF3_7检查发送状态,DMA_FLAG_TCIF2_6检查接收状态,
串口2使用 DMA_FLAG_TCIF2_6检查发送状态,DMA_FLAG_TCIF1_5检查接收状态,
串口3使用 DMA_FLAG_TCIF3_7检查发送状态,DMA_FLAG_TCIF1_5检查接收状态,
...
可以对照手册中的DMA通道表找到对应的通道号。
使用方法
先参考库中源码的定义:
// Stream的定义 #define DMA1_BASE (AHB1PERIPH_BASE + 0x6000UL) #define DMA1_Stream0_BASE (DMA1_BASE + 0x010UL) #define DMA1_Stream1_BASE (DMA1_BASE + 0x028UL) #define DMA1_Stream2_BASE (DMA1_BASE + 0x040UL) #define DMA1_Stream3_BASE (DMA1_BASE + 0x058UL) #define DMA1_Stream4_BASE (DMA1_BASE + 0x070UL) #define DMA1_Stream5_BASE (DMA1_BASE + 0x088UL) #define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0UL) #define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8UL) #define DMA2_BASE (AHB1PERIPH_BASE + 0x6400UL) #define DMA2_Stream0_BASE (DMA2_BASE + 0x010UL) #define DMA2_Stream1_BASE (DMA2_BASE + 0x028UL) #define DMA2_Stream2_BASE (DMA2_BASE + 0x040UL) #define DMA2_Stream3_BASE (DMA2_BASE + 0x058UL) #define DMA2_Stream4_BASE (DMA2_BASE + 0x070UL) #define DMA2_Stream5_BASE (DMA2_BASE + 0x088UL) #define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0UL) #define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8UL) #define DMA1 ((DMA_TypeDef *) DMA1_BASE) #define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) #define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) #define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) #define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) #define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) #define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) #define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) #define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) #define DMA2 ((DMA_TypeDef *) DMA2_BASE) #define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) #define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) #define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) #define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) #define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) #define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) #define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) #define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE)
以及定义
// 标志位的定义 #define DMA_FLAG_FEIF0_4 0x00000001U #define DMA_FLAG_DMEIF0_4 0x00000004U #define DMA_FLAG_TEIF0_4 0x00000008U #define DMA_FLAG_HTIF0_4 0x00000010U #define DMA_FLAG_TCIF0_4 0x00000020U #define DMA_FLAG_FEIF1_5 0x00000040U #define DMA_FLAG_DMEIF1_5 0x00000100U #define DMA_FLAG_TEIF1_5 0x00000200U #define DMA_FLAG_HTIF1_5 0x00000400U #define DMA_FLAG_TCIF1_5 0x00000800U #define DMA_FLAG_FEIF2_6 0x00010000U #define DMA_FLAG_DMEIF2_6 0x00040000U #define DMA_FLAG_TEIF2_6 0x00080000U #define DMA_FLAG_HTIF2_6 0x00100000U #define DMA_FLAG_TCIF2_6 0x00200000U #define DMA_FLAG_FEIF3_7 0x00400000U #define DMA_FLAG_DMEIF3_7 0x01000000U #define DMA_FLAG_TEIF3_7 0x02000000U #define DMA_FLAG_HTIF3_7 0x04000000U #define DMA_FLAG_TCIF3_7 0x08000000U
举个例子,参考__HAL_DMA_CLEAR_FLAG
宏函数的定义
#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \ (((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA2_Stream3)? (DMA2->HIFCR = (__FLAG__)) :\ ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream7)? (DMA2->LIFCR = (__FLAG__)) :\ ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream3)? (DMA1->HIFCR = (__FLAG__)) : (DMA1->LIFCR = (__FLAG__)))
假设现在对串口1的接收DMA进行控制,
// 定义 hdma_usart1_rx.Instance = DMA2_Stream2; // 操作 __HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx, DMA_FLAG_TCIF2_6);
那么,根据__HAL_DMA_CLEAR_FLAG
的定义, DMA2_Stream2>DMA2_Stream3不成立 DMA2_Stream2>DMA1_Stream7成立,执行 (DMA2->LIFCR = (__FLAG__))
所以,结合起来
__HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx, DMA_FLAG_TCIF2_6);
相当于对DMA2中的寄存器DMA_LIFCR中的第21位进行下面的操作 ,即向其控制位写入1清零DMA2的Stream2中断标志位。
DMA2->LIFCR = 0x00200000U;