【STM32H7教程】第39章 STM32H7的DMAMUX基础知识(重要)
完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第39章 STM32H7的DMAMUX基礎(chǔ)知識(shí)(重要)
本章教程為大家講解DMAMUX(Direct memory access request multiplexer,直接存儲(chǔ)器訪問(wèn)請(qǐng)求復(fù)用器),本章知識(shí)點(diǎn)非常重要,是掌握好DMA1,DMA2和BDMA的關(guān)鍵一步。
39.1 初學(xué)者重要提示
39.2 DMAMUX基礎(chǔ)知識(shí)
39.3 DMAMUX的HAL庫(kù)用法
39.4 源文件stm32h7xx_hal_dma_ex.c
39.5 總結(jié)
39.1 初學(xué)者重要提示
DMAMUX其實(shí)就是DMA控制器前一級(jí)的多路選擇器,有了這個(gè)選擇器就不用再像F1,F(xiàn)4系列那樣每個(gè)通道(數(shù)據(jù)流)要固定選擇指定的外設(shè),有了多路選擇器就可以任意選擇,外設(shè)使用DMA方式時(shí)無(wú)需再選擇指定的DMA通道(數(shù)據(jù)流),任意通道(數(shù)據(jù)流)都可以。
39.2 DMAMUX基礎(chǔ)知識(shí)
當(dāng)前STM32H7有兩路DMAMUX,分別是DMAMUX1和DMAMUX2,其中DMAMUX1負(fù)責(zé)DMA1和DMA2,而DMAMUX2負(fù)責(zé)BDMA。
39.2.1 DMAMUX和DMA的連接關(guān)系
認(rèn)識(shí)一個(gè)外設(shè),最好的方式就是看它的框圖,方便我們快速的了解DMAMUX的基本功能,然后再看手冊(cè)了解細(xì)節(jié)。首先來(lái)看下DMAMUX與DMA之間的連接方式,從整體上把握下,可以更好的理解DMAMUX的作用。
DMAMUX1有16個(gè)輸出通道,前8個(gè)通道分別連接DMA1 Stream0到Stream7,而后8個(gè)通道分別連接DMA2 Stream0到Stream7。上面DMAMUX1的前8路接到DMA1的8路數(shù)據(jù)流通道Stream0到Stream7中。
DMAMUX2有8個(gè)輸出通道,連接BDMA的8個(gè)輸入通道:
39.2.2 DMAMUX的硬件框圖
這個(gè)框圖對(duì)于理解DMAMUX至關(guān)重要。
通過(guò)這個(gè)框圖,我們可以得到如下信息:
DMA requests from peripherals接口
對(duì)于DMAMUX1來(lái)說(shuō),這個(gè)接口支持107個(gè)DMA外設(shè)請(qǐng)求,供DMA1和DMA2的數(shù)據(jù)流使用:
#define DMA_REQUEST_ADC1 9U /*!< DMAMUX1 ADC1 request */ #define DMA_REQUEST_ADC2 10U /*!< DMAMUX1 ADC2 request */ #define DMA_REQUEST_TIM1_CH1 11U /*!< DMAMUX1 TIM1 CH1 request */ #define DMA_REQUEST_TIM1_CH2 12U /*!< DMAMUX1 TIM1 CH2 request */ #define DMA_REQUEST_TIM1_CH3 13U /*!< DMAMUX1 TIM1 CH3 request */ #define DMA_REQUEST_TIM1_CH4 14U /*!< DMAMUX1 TIM1 CH4 request */ #define DMA_REQUEST_TIM1_UP 15U /*!< DMAMUX1 TIM1 UP request */ #define DMA_REQUEST_TIM1_TRIG 16U /*!< DMAMUX1 TIM1 TRIG request */ #define DMA_REQUEST_TIM1_COM 17U /*!< DMAMUX1 TIM1 COM request */ 中間部分省略未寫(xiě) #define DMA_REQUEST_TIM16_CH1 109U /*!< DMAMUX1 TIM16 CH1 request */ #define DMA_REQUEST_TIM16_UP 110U /*!< DMAMUX1 TIM16 UP request */ #define DMA_REQUEST_TIM17_CH1 111U /*!< DMAMUX1 TIM17 CH1 request */ #define DMA_REQUEST_TIM17_UP 112U /*!< DMAMUX1 TIM17 UP request */ #define DMA_REQUEST_SAI3_A 113U /*!< DMAMUX1 SAI3 A request */ #define DMA_REQUEST_SAI3_B 114U /*!< DMAMUX1 SAI3 B request */ #define DMA_REQUEST_ADC3 115U /*!< DMAMUX1 ADC3 request */
對(duì)于DMAMUX2來(lái)說(shuō),這個(gè)接口支持9個(gè)DMA外設(shè)請(qǐng)求,供BDMA通道使用:
#define BDMA_REQUEST_LPUART1_RX 9U /*!< DMAMUX2 LP_UART1_RX request */ #define BDMA_REQUEST_LPUART1_TX 10U /*!< DMAMUX2 LP_UART1_TX request */ #define BDMA_REQUEST_SPI6_RX 11U /*!< DMAMUX2 SPI6 RX request */ #define BDMA_REQUEST_SPI6_TX 12U /*!< DMAMUX2 SPI6 TX request */ #define BDMA_REQUEST_I2C4_RX 13U /*!< DMAMUX2 I2C4 RX request */ #define BDMA_REQUEST_I2C4_TX 14U /*!< DMAMUX2 I2C4 TX request */ #define BDMA_REQUEST_SAI4_A 15U /*!< DMAMUX2 SAI4 A request */ #define BDMA_REQUEST_SAI4_B 16U /*!< DMAMUX2 SAI4 B request */ #define BDMA_REQUEST_ADC3 17U /*!< DMAMUX2 ADC3 request */
這里特別注意一點(diǎn),DMA1,DMA2和BDMA都支持存儲(chǔ)區(qū)到存儲(chǔ)區(qū)的傳輸。
Trigger inputs接口
除了正常的DMA請(qǐng)求可以輸入到DMAMUX里面,通過(guò)設(shè)置觸發(fā)條件也可以生成DMA觸發(fā)請(qǐng)求。這樣就比較靈活了,不支持DMA的外設(shè)也可以通過(guò)Trigger inputs接口觸發(fā)DMA傳輸,比如我們可以將RAM中的數(shù)據(jù)通過(guò)定時(shí)器觸發(fā)直接輸出到GPIO,這樣就可以產(chǎn)生各種脈沖效果。
DMAMUX1支持8種觸發(fā)輸入,供DMA1和DMA2使用:
#define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT 0U #define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT 1U #define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT 2U #define HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT 3U #define HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT 4U #define HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT 5U #define HAL_DMAMUX1_REQ_GEN_EXTI0 6U #define HAL_DMAMUX1_REQ_GEN_TIM12_TRGO 7U
DMAMUX2支持的30種觸發(fā)輸入,供BDMA使用:
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT 0U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT 1U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT 2U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT 3U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT 4U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT 5U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT 6U #define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP 7U #define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP 8U #define HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP 9U #define HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT 10U #define HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP 11U #define HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT 12U #define HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP 13U #define HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP 14U #define HAL_DMAMUX2_REQ_GEN_I2C4_WKUP 15U #define HAL_DMAMUX2_REQ_GEN_SPI6_WKUP 16U #define HAL_DMAMUX2_REQ_GEN_COMP1_OUT 17U #define HAL_DMAMUX2_REQ_GEN_COMP2_OUT 18U #define HAL_DMAMUX2_REQ_GEN_RTC_WKUP 19U #define HAL_DMAMUX2_REQ_GEN_EXTI0 20U #define HAL_DMAMUX2_REQ_GEN_EXTI2 21U #define HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT 22U #define HAL_DMAMUX2_REQ_GEN_SPI6_IT 23U #define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT 24U #define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT 25U #define HAL_DMAMUX2_REQ_GEN_ADC3_IT 26U #define HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT 27U #define HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT 28U #define HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT 29U
Interrupt接口
用于觸發(fā)中斷。
Synchronization inputs接口
同步輸入接口可以用來(lái)控制DMAMUX的輸入端的DMA外設(shè)請(qǐng)求到輸出端的同步控制,其實(shí)就是控制何時(shí)輸出。
DMAMUX1支持的8種同步輸入,供DMA1和DMA2使用:
#define HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT 0U #define HAL_DMAMUX1_SYNC_DMAMUX1_CH1_EVT 1U #define HAL_DMAMUX1_SYNC_DMAMUX1_CH2_EVT 2U #define HAL_DMAMUX1_SYNC_LPTIM1_OUT 3U #define HAL_DMAMUX1_SYNC_LPTIM2_OUT 4U #define HAL_DMAMUX1_SYNC_LPTIM3_OUT 5U #define HAL_DMAMUX1_SYNC_EXTI0 6U #define HAL_DMAMUX1_SYNC_TIM12_TRGO 7U
DMAMUX2支持的16種同步輸入,供BDMA使用:
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH0_EVT 0U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH1_EVT 1U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH2_EVT 2U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH3_EVT 3U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH4_EVT 4U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH5_EVT 5U #define HAL_DMAMUX2_SYNC_LPUART1_RX_WKUP 6U #define HAL_DMAMUX2_SYNC_LPUART1_TX_WKUP 7U #define HAL_DMAMUX2_SYNC_LPTIM2_OUT 8U #define HAL_DMAMUX2_SYNC_LPTIM3_OUT 9U #define HAL_DMAMUX2_SYNC_I2C4_WKUP 10U #define HAL_DMAMUX2_SYNC_SPI6_WKUP 11U #define HAL_DMAMUX2_SYNC_COMP1_OUT 12U #define HAL_DMAMUX2_SYNC_RTC_WKUP 13U #define HAL_DMAMUX2_SYNC_EXTI0 14U #define HAL_DMAMUX2_SYNC_EXTI2 15U
DMA Channels event接口
DMAMUX的事件輸出。
DMA requests to DMA controllers接口
DMAMUX的輸出,發(fā)往DMA1,DMA2或者BDMA。
39.2.3 請(qǐng)求發(fā)生器(Request Generator)
請(qǐng)求觸發(fā)器最大的優(yōu)勢(shì)就是可以讓不支持DMA傳輸?shù)耐庠O(shè)也可以通過(guò)Trigger inputs接口觸發(fā)DMA傳輸,比如我們可以將RAM中的數(shù)據(jù)通過(guò)定時(shí)器觸發(fā)直接輸出到GPIO,這樣就可以產(chǎn)生各種脈沖效果,這樣就比較靈活了。
這里我們?cè)龠M(jìn)一步的認(rèn)識(shí)下請(qǐng)求發(fā)生器,通過(guò)下面框圖可以看出請(qǐng)求發(fā)生器有n個(gè)通道,并且每個(gè)通道都支持t個(gè)觸發(fā)。這里有一個(gè)關(guān)鍵知識(shí)點(diǎn),所有這些通道可以選擇同一個(gè)觸發(fā)源。
了解了這些之后,我們要對(duì)它的工作過(guò)程有一個(gè)簡(jiǎn)單的認(rèn)識(shí),看下面的時(shí)序圖:
dmamux_req_gen信號(hào)請(qǐng)求發(fā)生器生成的DMA請(qǐng)求。
dmamux_req_out信號(hào)是DMAMUX的輸出,供DMA1,DMA2或者BDMA使用。
Request generator counter這個(gè)計(jì)數(shù)器比較重要,它的意思是一次dmamux_trg觸發(fā)信號(hào),可以連續(xù)執(zhí)行的DMA請(qǐng)求,最大32次。這里是以DMA可以執(zhí)行的最快速度進(jìn)行響應(yīng)的。每執(zhí)行一次,計(jì)數(shù)器減1,減到0后自動(dòng)加載用戶(hù)設(shè)置的最大次數(shù),等待下次觸發(fā),依次進(jìn)行。如果計(jì)數(shù)器還沒(méi)有減到0就再次觸發(fā),請(qǐng)求發(fā)生器的中斷狀態(tài)寄存器DMAMUX_RGSR的標(biāo)志將被置位,如果使能了中斷,將會(huì)被觸發(fā)。
dmamux_trg信號(hào)是觸發(fā)源。
39.2.4 同步觸發(fā)和請(qǐng)求復(fù)用器(Request multiplexer)
同步輸入接口可以用來(lái)控制DMAMUX的輸入端的DMA外設(shè)請(qǐng)求到輸出端的同步控制,其實(shí)就是控制何時(shí)輸出。
這里我們?cè)龠M(jìn)一步的認(rèn)識(shí)下請(qǐng)求復(fù)用器,從下面的框圖中可以看出請(qǐng)求發(fā)生器有m個(gè)通道,并且每個(gè)通道都支持n+p+2個(gè)DMA請(qǐng)求,但是每個(gè)通道不可以選擇相同的DMA請(qǐng)求。
特別注意紅色方框的地方,請(qǐng)求發(fā)生器的n個(gè)DMA請(qǐng)求和p個(gè)DMA外設(shè)請(qǐng)求全都匯集于此,可供這里的多路選擇器選擇。
了解了這些之后,我們要對(duì)它的工作過(guò)程有一個(gè)簡(jiǎn)單的認(rèn)識(shí),看下面的時(shí)序圖:
下面連續(xù)同步三次的效果,每次產(chǎn)生4次DMA請(qǐng)求:
dmamux_reqx信號(hào)是請(qǐng)求復(fù)用器的輸入端。
dmamux_syncx是同步觸發(fā)信號(hào)。
dmamux_req_outx信號(hào)是DMAMUX的輸出,供DMA1,DMA2或者BDMA使用。
DMA request counter這個(gè)計(jì)數(shù)器比較重要,他的意思是一次dmamux_syncx觸發(fā)信號(hào),可以連續(xù)執(zhí)行的DMA請(qǐng)求,最大32次。這里是以DMA請(qǐng)求可以執(zhí)行的最快速度進(jìn)行響應(yīng)的。每執(zhí)行一次,計(jì)數(shù)器減1,減到0后自動(dòng)加載用戶(hù)設(shè)置的最大次數(shù),等待下次觸發(fā),依次進(jìn)行。如果計(jì)數(shù)器還沒(méi)有減到0就再次觸發(fā),請(qǐng)求發(fā)生器的中斷狀態(tài)寄存器DMAMUX_CSR的標(biāo)志將被置位,如果使能了中斷,將會(huì)被觸發(fā)。
dmamux_evt信號(hào)是輸出事件。
39.2.5 正常的DMA請(qǐng)求方式
除了前面說(shuō)的請(qǐng)求發(fā)生器產(chǎn)生的DMA請(qǐng)求和同步觸發(fā)產(chǎn)生的DMA請(qǐng)求,關(guān)閉了這兩種方式后也可以通過(guò)DMAMUX正常發(fā)出DMA請(qǐng)求的,這種情況和之前使用F1和F4系列是一樣的。
39.3 DMAMUX的HAL庫(kù)用法
DMAMUX的HAL庫(kù)用法其實(shí)就是幾個(gè)結(jié)構(gòu)體變量成員的配置和使用,然后配置GPIO、時(shí)鐘,并根據(jù)需要配置NVIC、中斷和DMA。下面我們逐一展開(kāi)為大家做個(gè)說(shuō)明。
39.3.1 請(qǐng)求發(fā)生器結(jié)構(gòu)體HAL_DMA_MuxRequestGeneratorConfigTypeDef
HAL_DMA_MuxRequestGeneratorConfigTypeDef的定義如下:
typedef struct
{
uint32_t SignalID; /*!< Specifies the ID of the signal used for DMAMUX request generator
This parameter can be a value of @ref DMAEx_MUX_SignalGeneratorID_selection */
uint32_t Polarity; /*!< Specifies the polarity of the signal on which the request is generated.
This parameter can be a value of @ref DMAEx_MUX_RequestGeneneratorPolarity_selection */
uint32_t RequestNumber; /*!< Specifies the number of DMA request that will be generated after a signal event.
This parameters can be in the range 1 to 32 */
}HAL_DMA_MuxRequestGeneratorConfigTypeDef;
下面將這三個(gè)結(jié)構(gòu)體成員一 一為大家做個(gè)說(shuō)明。
SingnalID
請(qǐng)求發(fā)生器的觸發(fā)源ID選擇,DMAMUX1可以選擇的觸發(fā)源ID如下:
#define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT 0U #define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT 1U #define HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT 2U #define HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT 3U #define HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT 4U #define HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT 5U #define HAL_DMAMUX1_REQ_GEN_EXTI0 6U #define HAL_DMAMUX1_REQ_GEN_TIM12_TRGO 7U
DMAMUX2可以選擇的觸發(fā)源ID如下:
#define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT 0U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT 1U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT 2U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT 3U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT 4U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT 5U #define HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT 6U #define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP 7U #define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP 8U #define HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP 9U #define HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT 10U #define HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP 11U #define HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT 12U #define HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP 13U #define HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP 14U #define HAL_DMAMUX2_REQ_GEN_I2C4_WKUP 15U #define HAL_DMAMUX2_REQ_GEN_SPI6_WKUP 16U #define HAL_DMAMUX2_REQ_GEN_COMP1_OUT 17U #define HAL_DMAMUX2_REQ_GEN_COMP2_OUT 18U #define HAL_DMAMUX2_REQ_GEN_RTC_WKUP 19U #define HAL_DMAMUX2_REQ_GEN_EXTI0 20U #define HAL_DMAMUX2_REQ_GEN_EXTI2 21U #define HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT 22U #define HAL_DMAMUX2_REQ_GEN_SPI6_IT 23U #define HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT 24U #define HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT 25U #define HAL_DMAMUX2_REQ_GEN_ADC3_IT 26U #define HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT 27U #define HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT 28U #define HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT 29U
Polarity
觸發(fā)信號(hào)的極性設(shè)置,可以是上升沿觸發(fā)、下降沿觸發(fā)或者雙沿觸發(fā)。
#define HAL_DMAMUX_REQ_GEN_NO_EVENT 0x00000000U #define HAL_DMAMUX_REQ_GEN_RISING DMAMUX_RGxCR_GPOL_0 #define HAL_DMAMUX_REQ_GEN_FALLING DMAMUX_RGxCR_GPOL_1 #define HAL_DMAMUX_REQ_GEN_RISING_FALLING DMAMUX_RGxCR_GPOL
RequestNumber
每次觸發(fā)信號(hào)后,可以執(zhí)行的DMA請(qǐng)求次數(shù),這個(gè)在本章的2.3小節(jié)已經(jīng)進(jìn)行了詳細(xì)說(shuō)明。
39.3.2 同步觸發(fā)結(jié)構(gòu)體HAL_DMA_MuxSyncConfigTypeDef
HAL_DMA_MuxSyncConfigTypeDef的定義如下::
typedef struct
{
uint32_t SyncSignalID;
uint32_t SyncPolarity;
FunctionalState SyncEnable;
FunctionalState EventEnable;
uint32_t RequestNumber;
}HAL_DMA_MuxSyncConfigTypeDef;
下面將這五個(gè)結(jié)構(gòu)體成員一 一為大家做個(gè)說(shuō)明。
SyncSingnalID
同步觸發(fā)源的ID選擇,DMAMUX1可以選擇的觸發(fā)源ID如下:
#define HAL_DMAMUX1_SYNC_DMAMUX1_CH0_EVT 0U #define HAL_DMAMUX1_SYNC_DMAMUX1_CH1_EVT 1U #define HAL_DMAMUX1_SYNC_DMAMUX1_CH2_EVT 2U #define HAL_DMAMUX1_SYNC_LPTIM1_OUT 3U #define HAL_DMAMUX1_SYNC_LP TIM2_OUT 4U #define HAL_DMAMUX1_SYNC_LPTIM3_OUT 5U #define HAL_DMAMUX1_SYNC_EXTI0 6U #define HAL_DMAMUX1_SYNC_TIM12_TRGO 7U
DMAMUX2可以選擇的觸發(fā)源ID如下:
#define HAL_DMAMUX2_SYNC_DMAMUX2_CH0_EVT 0U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH1_EVT 1U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH2_EVT 2U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH3_EVT 3U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH4_EVT 4U #define HAL_DMAMUX2_SYNC_DMAMUX2_CH5_EVT 5U #define HAL_DMAMUX2_SYNC_LPUART1_RX_WKUP 6U #define HAL_DMAMUX2_SYNC_LPUART1_TX_WKUP 7U #define HAL_DMAMUX2_SYNC_LPTIM2_OUT 8U #define HAL_DMAMUX2_SYNC_LPTIM3_OUT 9U #define HAL_DMAMUX2_SYNC_I2C4_WKUP 10U #define HAL_DMAMUX2_SYNC_SPI6_WKUP 11U #define HAL_DMAMUX2_SYNC_COMP1_OUT 12U #define HAL_DMAMUX2_SYNC_RTC_WKUP 13U #define HAL_DMAMUX2_SYNC_EXTI0 14U #define HAL_DMAMUX2_SYNC_EXTI2 15U
SyncPolarity
同步觸發(fā)信號(hào)的極性設(shè)置,可以是上升沿觸發(fā)、下降沿觸發(fā)或者雙沿觸發(fā)。
#define HAL_DMAMUX_SYNC_NO_EVENT 0x00000000U #define HAL_DMAMUX_SYNC_RISING DMAMUX_CxCR_SPOL_0 #define HAL_DMAMUX_SYNC_FALLING DMAMUX_CxCR_SPOL_1 #define HAL_DMAMUX_SYNC_RISING_FALLING DMAMUX_CxCR_SPOL
SyncEnable
用于使能同步觸發(fā),參數(shù)可以是ENABLE 或者 DISABLE。
EventEnable
同步觸發(fā)事件輸出使能,當(dāng)參數(shù)RequestNumber的數(shù)值減到0的時(shí)候才會(huì)輸出。
RequestNumber
每次同步觸發(fā)信號(hào)后,可以執(zhí)行的DMA請(qǐng)求次數(shù),這個(gè)在本章的2.4小節(jié)已經(jīng)進(jìn)行了詳細(xì)說(shuō)明。
39.3.3 DMAMUX的狀態(tài)標(biāo)志清除問(wèn)題
DMAMUX有兩個(gè)中斷,一個(gè)是請(qǐng)求復(fù)用器通道發(fā)生同步事件溢出,另一個(gè)是請(qǐng)求發(fā)生器通道發(fā)生觸發(fā)事件溢出。
當(dāng)用戶(hù)調(diào)用了函數(shù)HAL_DMA_Start_IT,程序代碼中會(huì)根據(jù)用戶(hù)是否使能了請(qǐng)求復(fù)用器或者請(qǐng)求發(fā)生器通道來(lái)使能這兩個(gè)中斷。
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
/* 省略未寫(xiě) */
if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
{
/* 使能同步溢出中斷 */
hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
}
if(hdma->DMAmuxRequestGen != 0U)
{
/* 使能請(qǐng)求發(fā)生器的溢出中斷 */
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
}
/* 省略未寫(xiě) */
}
這兩個(gè)中斷產(chǎn)生的中斷標(biāo)志是在函數(shù)HAL_DMAEx_MUX_IRQHandler里面做的清除,如果大家不使用HAL庫(kù)提供的這個(gè)中斷處理函數(shù),就需要自己編寫(xiě)代碼清除。
void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
{
/* 檢測(cè)DMAMUX同步溢出 */
if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
{
/* 禁止同步溢出中斷 */
hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
/* 清除DMAMUX同步溢出標(biāo)志 */
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
if(hdma->XferErrorCallback != NULL)
{
/* 回調(diào)函數(shù) */
hdma->XferErrorCallback(hdma);
}
}
if(hdma->DMAmuxRequestGen != 0)
{
/* 檢測(cè)請(qǐng)求發(fā)生器溢出 */
if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
{
/* 禁止請(qǐng)求發(fā)生器溢出中斷 */
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
/* 清除DMAMUX請(qǐng)求發(fā)生器溢出標(biāo)志 */
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
/* 更新錯(cuò)誤代碼標(biāo)識(shí) */
hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
if(hdma->XferErrorCallback != NULL)
{
/* 回調(diào)函數(shù) */
hdma->XferErrorCallback(hdma);
}
}
}
}
39.3.4 DMAMUX初始化流程總結(jié)
DMAMUX沒(méi)有單獨(dú)的初始化流程,要結(jié)合第40章和42章的函數(shù)一起使用。
39.4 源文件stm32h7xx_hal_dma_ex.c
DMAMUX用到如下四個(gè)說(shuō)明,這里把這四個(gè)函數(shù)的使用為大家做個(gè)說(shuō)明:
HAL_DMAEx_ConfigMuxSync
HAL_DMAEx_ConfigMuxRequestGenerator
HAL_DMAEx_EnableMuxRequestGenerator
HAL_DMAEx_DisableMuxRequestGenerator
39.4.1 函數(shù)HAL_DMAEx_ConfigMuxSync
函數(shù)原型:
HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
{
uint32_t syncSignalID = 0;
uint32_t syncPolarity = 0;
/* 檢測(cè)參數(shù) */
assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
/* 檢測(cè)是否使能了同步觸發(fā) */
if(pSyncConfig->SyncEnable == ENABLE)
{
assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig->SyncPolarity));
if(IS_D2_DMA_INSTANCE(hdma) != 0U)
{
assert_param(IS_D2_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
}
else
{
assert_param(IS_D3_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
}
syncSignalID = pSyncConfig->SyncSignalID;
syncPolarity = pSyncConfig->SyncPolarity;
}
/* 檢測(cè)DMA是否處于就緒態(tài) */
if(hdma->State == HAL_DMA_STATE_READY)
{
/* 上鎖 */
__HAL_LOCK(hdma);
/* 應(yīng)用新的配置前禁止同步和產(chǎn)生同步事件 */
CLEAR_BIT(hdma->DMAmuxChannel->CCR,(DMAMUX_CxCR_SE | DMAMUX_CxCR_EGE));
/* 配置新的參數(shù),同時(shí)DMAMUX_CxCR_DMAREQ_ID 位保持不變 */
MODIFY_REG( hdma->DMAmuxChannel->CCR,
(~DMAMUX_CxCR_DMAREQ_ID) ,
(syncSignalID << POSITION_VAL(DMAMUX_CxCR_SYNC_ID)) |
((pSyncConfig->RequestNumber - 1U) << POSITION_VAL(DMAMUX_CxCR_NBREQ)) |
syncPolarity | (pSyncConfig->SyncEnable << DMAMUX_POSITION_CxCR_SE) |
(pSyncConfig->EventEnable << DMAMUX_POSITION_CxCR_EGE));
/* 開(kāi)鎖 */
__HAL_UNLOCK(hdma);
return HAL_OK;
}
else
{
/* 設(shè)置錯(cuò)誤標(biāo)志 */
hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
/* 返回狀態(tài)HAL_ERROR */
return HAL_ERROR;
}
}
函數(shù)描述:
此函數(shù)用于配置DMAMUX的同步觸發(fā),可以用來(lái)控制DMAMUX的輸入端的DMA外設(shè)請(qǐng)求到輸出端的同步控制,其實(shí)就是控制何時(shí)輸出。
函數(shù)參數(shù):
第1個(gè)參數(shù)是DMA_HandleTypeDef類(lèi)型結(jié)構(gòu)體指針變量,用于配置DMA的初始化參數(shù)。
第2個(gè)參數(shù)是HAL_DMA_MuxSyncConfigTypeDef類(lèi)型結(jié)構(gòu)體變量,參數(shù)成員的含義在本章的3.2小節(jié)有講解說(shuō)明。
返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時(shí)間溢出。
注意事項(xiàng):
第1個(gè)參數(shù)的結(jié)構(gòu)體成員介紹在第40章進(jìn)行了講解。
調(diào)用此函數(shù)前要先調(diào)用函數(shù)HAL_DMA_Init配置好DMA。
使用舉例:
此函數(shù)的舉例可以看此貼:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=88925 。
39.4.2 函數(shù)HAL_DMAEx_ConfigMuxRequestGenerator
函數(shù)原型:
HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
{
HAL_StatusTypeDef status = HAL_OK;
/* 檢查參數(shù) */
assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
if(IS_D2_DMA_INSTANCE(hdma) != 0U)
{
assert_param(IS_D2_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
}
else
{
assert_param(IS_D3_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
}
assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
/* 如果DMA配置中未使用DMAMUX的請(qǐng)求發(fā)生器,返回HAL_ERROR */
if(hdma->DMAmuxRequestGen == 0U)
{
/* 設(shè)置參數(shù)錯(cuò)誤 */
hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
/* 設(shè)置錯(cuò)誤狀態(tài) */
status = HAL_ERROR;
}
/* 必須保證請(qǐng)求發(fā)生器是關(guān)閉的才可以配置 */
else if((hdma->State == HAL_DMA_STATE_READY) && ((hdma->DMAmuxRequestGen->RGCR & DMAMUX_RGxCR_GE) == 0))
{
/* 上鎖 */
__HAL_LOCK(hdma);
/* 設(shè)置新參數(shù) */
hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID |
((pRequestGeneratorConfig->RequestNumber - 1U) << POSITION_VAL(DMAMUX_RGxCR_NBREQ))|
pRequestGeneratorConfig->Polarity;
/* 解鎖 */
__HAL_UNLOCK(hdma);
return HAL_OK;
}
else
{
/* 設(shè)置錯(cuò)誤標(biāo)志 */
hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
/* 設(shè)置錯(cuò)誤狀態(tài) */
status = HAL_ERROR;
}
return status;
}
函數(shù)描述:
此函數(shù)用于配置DMAMUX的發(fā)生器。請(qǐng)求觸發(fā)器最大的優(yōu)勢(shì)就是可以讓不支持DMA傳輸?shù)耐庠O(shè)也可以通過(guò)Trigger inputs接口觸發(fā)DMA傳輸,比如我們可以將RAM中的數(shù)據(jù)通過(guò)定時(shí)器觸發(fā)直接輸出到GPIO,就可以產(chǎn)生各種脈沖效果,這樣就比較靈活了。
函數(shù)參數(shù):
第1個(gè)參數(shù)是DMA_HandleTypeDef類(lèi)型結(jié)構(gòu)體指針變量,用于配置DMA的初始化參數(shù)。
第2個(gè)參數(shù)是HAL_DMA_MuxRequestGeneratorConfigTypeDef f類(lèi)型結(jié)構(gòu)體變量,參數(shù)成員的含義在本章的3.1小節(jié)有講解說(shuō)明。
返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時(shí)間溢出。
注意事項(xiàng):
第1個(gè)參數(shù)的結(jié)構(gòu)體成員介紹在第40章進(jìn)行了講解。
調(diào)用此函數(shù)前要先調(diào)用函數(shù)HAL_DMA_Init配置好DMA。
使用舉例:
HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams ={0}
dmamux_ReqGenParams.SignalID = HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT; /* 請(qǐng)求觸發(fā)器選擇LPTIM2_OUT */
dmamux_ReqGenParams.Polarity = HAL_DMAMUX_REQ_GEN_RISING_FALLING; /* LPTIM2輸出的上升沿和下降沿均可觸發(fā) */
dmamux_ReqGenParams.RequestNumber = 1; /* 觸發(fā)后,傳輸進(jìn)行1次DMA傳輸 */
HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams); /* 配置DMAMUX */
HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle); /* 使能DMAMUX請(qǐng)求發(fā)生器 */
39.4.3 函數(shù)HAL_DMAEx_EnableMuxRequestGenerator
函數(shù)原型:
HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
{
/* 檢測(cè)參數(shù) */
assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
/* 如果DMA配置中使用了DMAMUX的請(qǐng)求發(fā)生器,則將其使能并返回HAL_OK */
if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
{
/* 使能請(qǐng)求發(fā)生器 */
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
函數(shù)描述:
調(diào)用函數(shù)HAL_DMAEx_ConfigMuxRequestGenerator配置了請(qǐng)求發(fā)生器后,就可以調(diào)用此函數(shù)使能請(qǐng)求發(fā)生器。跟禁止函數(shù)HAL_DMAEx_DisableMuxRequestGenerator是一對(duì)。
函數(shù)參數(shù):
第1個(gè)參數(shù)是DMA_HandleTypeDef類(lèi)型結(jié)構(gòu)體指針變量。
返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時(shí)間溢出。
使用舉例:
HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams ={0}
dmamux_ReqGenParams.SignalID = HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT; /* 請(qǐng)求觸發(fā)器選擇LPTIM2_OUT */
dmamux_ReqGenParams.Polarity = HAL_DMAMUX_REQ_GEN_RISING_FALLING; /* LPTIM2輸出的上升沿和下降沿均可觸發(fā) */
dmamux_ReqGenParams.RequestNumber = 1; /* 觸發(fā)后,傳輸進(jìn)行1次DMA傳輸 */
HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams); /* 配置DMAMUX */
HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle); /* 使能DMAMUX請(qǐng)求發(fā)生器 */
39.4.4 函數(shù)HAL_DMAEx_DisableMuxRequestGenerator
函數(shù)原型:
HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
{
/* 檢查參數(shù) */
assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance));
/* 如果DMA配置中使用了DMAMUX的請(qǐng)求發(fā)生器,則將其禁止并返回HAL_OK */
if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0U))
{
/* 禁止請(qǐng)求發(fā)生器 */
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
函數(shù)描述:
此函數(shù)用于禁止請(qǐng)求發(fā)生器,跟使能函數(shù)HAL_DMAEx_EnableMuxRequestGenerator是一對(duì),
函數(shù)參數(shù):
第1個(gè)參數(shù)是DMA_HandleTypeDef類(lèi)型結(jié)構(gòu)體指針變量。
使用舉例:
此函數(shù)跟前面的HAL_DMAEx_EnableMuxRequestGenerator是一對(duì),使用時(shí)直接調(diào)用即可。
39.5 總結(jié)
本章節(jié)就為大家講解這么多,DMXMUX用到的地方比較多,這幾個(gè)常用的函數(shù)要熟練掌握。
總結(jié)
以上是生活随笔為你收集整理的【STM32H7教程】第39章 STM32H7的DMAMUX基础知识(重要)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 让ERP downloaded prod
- 下一篇: 1.零基础如何学习Web安全渗透测试?[