宏定義的含義
造成中文手冊誤解的原因:有的把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;