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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 12876|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

關(guān)于STM32 DMA重新使能的話題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:98618 發(fā)表于 2016-11-1 00:05 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
有人發(fā)現(xiàn)當(dāng)DMA配置為normal模式,一輪傳輸完成后再使能同一DMA數(shù)據(jù)流時,即使有DMA請求產(chǎn)生,DMA根本不進(jìn)行數(shù)據(jù)傳輸。這里不妨以STM32F4為例聊聊該話題。


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


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


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


有人用STM32F4芯片做產(chǎn)品,他是基于STM32CUBE庫做應(yīng)用開發(fā)。用DMA做USART通信的數(shù)據(jù)傳輸,DMA配置為循環(huán)模式

他發(fā)現(xiàn)HAL_UART_Transmit_DMA()這個函數(shù)在做了一次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);                           

             

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


結(jié)果發(fā)現(xiàn)經(jīng)過2次配置后的結(jié)果沒變,發(fā)送的都是DataBuff[0]至DataBuff[9]的10個數(shù)據(jù)。為什么呢?不妨一起看看。

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

接著第【2】句是在DMA完成中斷里進(jìn)行。暫停USART TX傳輸?shù)腄MA請求,并延時2S;

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

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


按照上面幾步也貌似條理清晰,有根有據(jù)。可結(jié)果為什么發(fā)現(xiàn)第【3】句的二次配置沒法生效呢?


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

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


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


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


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

 

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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:303001 發(fā)表于 2018-8-23 13:17 | 只看該作者
朋友,多謝你這篇帖子,我今天找了一上午DMA使能無效的問題,看過你這篇文章后,醍醐灌頂啊!問題終于解決,多謝!這次問題提醒我,以后得多看看手冊,即便是用庫編程。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美一区精品 | 国产精品成人av | 国产成人精品网站 | 精品亚洲一区二区三区 | 亚洲理论在线观看电影 | 成人h电影在线观看 | 欧美精品欧美精品系列 | 天天摸天天干 | www..com18午夜观看 | 成人综合久久 | 天天干天天插天天 | 久草中文在线 | 久久精品国产a三级三级三级 | 韩日在线视频 | 中文在线a在线 | 久久国产一区二区三区 | 午夜久久久 | 91大神xh98xh系列全部 | 国产亚洲精品91 | 国产精品欧美精品日韩精品 | 天天躁日日躁狠狠躁白人 | 一级做a爰片久久毛片 | 久久草在线视频 | 色天天综合 | 久久成人一区 | 成人在线播放网站 | 超黄毛片 | 欧美群妇大交群中文字幕 | 国产精品一区在线播放 | 91中文字幕在线观看 | 国产精品欧美一区二区三区不卡 | 国产精品黄视频 | 国产免费一区二区三区免费视频 | 日本中文字幕在线观看 | 久久网国产 | 色偷偷888欧美精品久久久 | 一区二区三区精品视频 | 久久久久久久av | 在线免费观看a级片 | 一级做a | 国产精品久久久久久婷婷天堂 |