久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 關于STM32 DMA重新使能的話題 [打印本頁]

作者: taoran    時間: 2016-11-1 00:05
標題: 關于STM32 DMA重新使能的話題
有人發現當DMA配置為normal模式,一輪傳輸完成后再使能同一DMA數據流時,即使有DMA請求產生,DMA根本不進行數據傳輸。這里不妨以STM32F4為例聊聊該話題。


其實,在非循環模式下配置的DMA數據流傳輸結束后(即要傳輸的數據數目達到零),除非軟件重新對數據流編程并使能該數據流(通過將 DMA_SxCR 寄存器中的 EN 位置 1),否則DMA 會停止傳輸(硬件會將 DMA_SxCR 寄存器中的EN 位清零)并不再響應任何 DMA 請求。也就是說,當一輪DMA傳輸完成后,簡單來一句 __HAL_DMA_ENABLE(hdma)并不能再次重啟DMA傳輸,必須先行對數據流重新進行初始化配置,然后使能該DMA數據流。


不過,要對STM32F4系列內部各DMA數據流進行配置,首先要保證 DMA_SxCR 寄存器中的 EN 位已被清零。一般來講,在進行DMA數據流配置前,先對該EN位進行寫0去禁用該DMA流,然后讀取此位以確認沒有正在進行的數據流傳輸操作。將此位寫 0 可能不會立即生效,因為只有當前所有傳輸都已完成時才會將其寫為 0。當讀取到 EN 位為 0 時,才可以配置DMA數據流。配置完成后,如果是再次配置的話,記得將先前的DMA 傳輸中在狀態寄存器(DMA_LISR 和 DMA_HISR)中置 1 的所有數據流專用位置0, 然后重新使能數據流,即將 DMA_SxCR 寄存器中的 EN位置 1 激活數據流。


OK,這里拿個實際案例看看以加深下印象。


有人用STM32F4芯片做產品,他是基于STM32CUBE庫做應用開發。用DMA做USART通信的數據傳輸,DMA配置為循環模式

他發現HAL_UART_Transmit_DMA()這個函數在做了一次DMA配置后,第二次使用它更新配置時無法生效。比如按下面步驟操作:


1HAL_UART_Transmit_DMA(&huart1,DataBuff, 10);

2HAL_UART_DMAPause(&huart1);                           

3 HAL_UART_Transmit_DMA(&huart1,&DataBuff[5],5); 

4HAL_UART_DMAResume(&huart1);                           

             

開發者的目的是希望先將DataBuff[0]至DataBuff[9]10個數據傳到串口上去。中途調整DMA配置[即第【3】句],然后發送DataBuff[5]至DataBuff[9]的5個數據到串口助手上去。


結果發現經過2次配置后的結果沒變,發送的都是DataBuff[0]至DataBuff[9]的10個數據。為什么呢?不妨一起看看。

上面第【1】句做usart TX的DMA傳輸配置。循環從DataBuf處開始取10個數據送往串口;

接著第【2】句是在DMA完成中斷里進行。暫停USART TX傳輸的DMA請求,并延時2S;

然后第【3】句再做USART TX的DMA配置,循環從&DataBuf【5】處開始取5個數據送往串口;

最后第【4】句重新開啟USART TX的DMA傳輸;


按照上面幾步也貌似條理清晰,有根有據。可結果為什么發現第【3】句的二次配置沒法生效呢?


從前面的描述我們得知,如果需要對某STREAM進行DMA配置的話,首先須DISABLE該STREAM,即先對DMA_SxCR寄存器的EN位清零。而且這個清零并不一定立即生效,必須保證該STREAM當前沒有在進行DMA傳輸。所以,做清零操作后,還要去讀該EN位,直至讀到該位為0后方能對該DMA STREAM 進行再次配置

HAL_UART_Transmit_DMA()函數里有對DMA_SxCR的EN位清零的動作,不過沒有讀取確認的動作。復位后DMA_SxCR寄存器的EN位默認是0毫無疑問,所以復位后第【1】句用HAL_UART_Transmit_DMA()函數配置后生效自然沒問題。


上面的第2】句在DMA完成中斷里進行,暫停UART TX的DMA請求,還延時了2S。本意是想讓DMA停下來,為后面二次配置做準備。但他這里只是暫停了DMA請求,加上這里配置DMA為循環模式,也就是說在進入DMA完成中斷時,DMA又做了下一輪傳輸的準備,其中包括傳輸數據項數目寄存器DMA_SxNDTR的重裝。此時盡管暫停了DMA請求,但該DMA流是處于傳輸未完成狀態。


那么緊跟著的第【3】句對USART TX的DMA二次配置,HAL_UART_Transmit_DMA()函數里雖然有對DMA_SxCR的EN位清零,但由于此時該STREAM處于傳輸未完成狀態,所以無法實現最終清零。


既然無法對EN位清零,相關配置就無法寫入生效。加上該函數沒有對EN位是否為0的未做進一步確認判斷,自然而然地下行到第【4】句重新開啟USART TX的DMA傳輸。最后的結果當然還是按照老配置運行了。【有心的話,可以去STM32F4參考手冊看看數據流 x 配置寄存器 DMA_SxCR,里面多個參數只有在EN位為0時方可進行寫操作

 

好了,就此打住。MCU開發中不少問題往往可能就卡在技術手冊看得不到位。在開發過程中遇到難解問題時,有時細心看看手冊的相關部分,或許會有踏破鐵鞋無覓處,得來全不費工夫的感覺。


作者: luban123    時間: 2018-8-23 13:17
朋友,多謝你這篇帖子,我今天找了一上午DMA使能無效的問題,看過你這篇文章后,醍醐灌頂啊!問題終于解決,多謝!這次問題提醒我,以后得多看看手冊,即便是用庫編程。




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 国产成人一区 | 暖暖成人免费视频 | 一级aaaaaa毛片免费同男同女 | 黄色网址在线免费播放 | 日韩国产中文字幕 | 欧美精品成人一区二区三区四区 | 91免费观看在线 | 成人福利网 | 九色国产| 欧美精品一区三区 | 亚洲欧美一区二区三区在线 | 国产日韩欧美在线 | 久久国产精品一区二区 | 国产精品视频偷伦精品视频 | 精品久久久久久久久久久久久久 | 国产欧美日韩一区 | 国产一区中文 | 岛国午夜 | 国产在线拍偷自揄拍视频 | 国产精品久久久久久婷婷天堂 | 伊人精品一区二区三区 | 欧美精品免费观看二区 | 成人不卡一区二区 | 日韩二三区 | 欧美成人精品一区二区三区 | 久久激情网 | 亚洲精品久久久久久久久久久久久 | 欧美激情视频一区二区三区在线播放 | 成人午夜视频在线观看 | av在线播放网 | 在线观看中文字幕一区二区 | 亚洲欧洲激情 | 中文精品视频 | 亚州精品天堂中文字幕 | 在线免费观看黄视频 | 99re在线播放| 天堂综合网 | 国产午夜精品一区二区三区 | 亚洲国产伊人 | 国产精品久久久久久久久久免费 | 久久免费精彩视频 |