娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年05月01日(星期四)

2018年05月01日 | stm32.cube(九)——HAL.DMA

發布者:rho27 來源: eefocus關鍵字:stm32  cube  HAL  DMA 手機看文章 掃描二維碼
隨時隨地手機看文章

一、前言

DMA會在不同的寄存器/ram/存儲設備之間建立通道,自動傳輸數據,以達到解放CPU的目的。

比如你想用DAC模塊去輸出一段特定的波形,就要讓CPU將預設的數值不斷寫入DAC的寄存器。這時CPU被DAC任務長期占用,系統處理其他任務和響應其他事件的能力被大幅降低。

在實際應用里,經常有一些繁重的讀寫操作。這些操作不需要經過計算,卻依然占用了大量的CPU資源,遇到這種情況就要考慮使用DMA了。

開發板上的stm芯片上共有7個dma通道,它可以建立7個DMA連接。但是DMA控制器只有一個,所以同時只能有一個DMA連接被相應。

二、DMA的初始化

針對每一個DMA頻道,都要初始化它的控制寄存器,來看一下DMA的init結構體的原型:

/** 

  * @brief  DMA Configuration Structure definition  

  */

typedef struct

{

  uint32_t Direction;                 /*!< Specifies if the data will be transferred from memory to peripheral, 

                                           from memory to memory or from peripheral to memory.

                                           This parameter can be a value of @ref DMA_Data_transfer_direction */


  uint32_t PeriphInc;                 /*!< Specifies whether the Peripheral address register should be incremented or not.

                                           This parameter can be a value of @ref DMA_Peripheral_incremented_mode */


  uint32_t MemInc;                    /*!< Specifies whether the memory address register should be incremented or not.

                                           This parameter can be a value of @ref DMA_Memory_incremented_mode */


  uint32_t PeriphDataAlignment;       /*!< Specifies the Peripheral data width.

                                           This parameter can be a value of @ref DMA_Peripheral_data_size */


  uint32_t MemDataAlignment;          /*!< Specifies the Memory data width.

                                           This parameter can be a value of @ref DMA_Memory_data_size */


  uint32_t Mode;                      /*!< Specifies the operation mode of the DMAy Channelx.

                                           This parameter can be a value of @ref DMA_mode

                                           @note The circular buffer mode cannot be used if the memory-to-memory

                                                 data transfer is configured on the selected Channel */ 


  uint32_t Priority;                   /*!< Specifies the software priority for the DMAy Channelx.

                                            This parameter can be a value of @ref DMA_Priority_level */


} DMA_InitTypeDef;

  • Direction的值表示通道類型,外設到ram、ram到外設、ram到ram。

  • PeriphInc和MemInc表示外設和ram地址要不要遞增。像上述的DAC例子,ram的地址一定是遞增的,而外設寄存器的地址則無需遞增。

  • PeriphDataAlignment和MemDataAlignment表示外設和ram的字節寬度,有一個字節,半字和全字。這將決定上面的增量模式里,一次讀取數據的大小。

  • Mode有兩種,普通和循環。普通模式下一次DMA請求處理完成后就不再傳輸數據。

  • Priority是DMA頻道的優先級,一共4個,如果優先級相同,頻道號小的通道率先被響應。

這些屬性被設置完畢后,在Init函數里會將它寫入控制寄存器。


  /* Get the CR register value */

  tmp = hdma->Instance->CCR;


  /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */

  tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  | \

                      DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   | \

                      DMA_CCR_DIR));


  /* Prepare the DMA Channel configuration */

  tmp |=  hdma->Init.Direction        |

          hdma->Init.PeriphInc           | hdma->Init.MemInc           |

          hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |

          hdma->Init.Mode                | hdma->Init.Priority;


  /* Write to DMA Channel CR register */

  hdma->Instance->CCR = tmp;  


三、DMA通道的建立

在初始化完畢后,只需要將源地址、起始地址、傳輸總長寫入寄存器,再使能該頻道即可。

HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);

HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);

這個DMA_HandleTypeDef *hdma是用C實現面向對象設計的一個典型的例子。當我們創建一個DMA頻道時,必須要先建立一個DMA_HandleTypeDef類型的結構體變量,這個行為實際上就是創建了一個DMA類的實例。

typedef struct __DMA_HandleTypeDef

{  

  DMA_Channel_TypeDef   *Instance;                                                    /*!< Register base address                  */


  DMA_InitTypeDef       Init;                                                         /*!< DMA communication parameters           */ 


  HAL_LockTypeDef       Lock;                                                         /*!< DMA locking object                     */  


  HAL_DMA_StateTypeDef  State;                                                        /*!< DMA transfer state                     */


  void                  *Parent;                                                      /*!< Parent object state                    */  


  void                  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA transfer complete callback         */


  void                  (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback    */


  void                  (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer error callback            */


  __IO uint32_t         ErrorCode;                                                    /*!< DMA Error code                         */


} DMA_HandleTypeDef;   

這個結構體除了包含有init結構體、鎖、DMA寄存器指針、狀態變量、錯誤變量之外,還包含了一些callback函數的指針。它甚至有一個父類指針,只要將該指針指向一些adc、uart等外設的handle類,就等于完成了繼承。


除了有init和start函數外、HAL里還提供常規的DMA中斷處理函數,等待DMA傳輸,獲取DMA狀態的一些函數,結構上與前面的adc、flash等類似,就不做敘述了。


四、例子


來看一個串口用dma收發的例子。 

首先是寫收發兩個頻道的控制寄存器: 

  /*##-3- Configure the DMA ##################################################*/

  /* Configure the DMA handler for Transmission process */

  hdma_tx.Instance                 = USARTx_TX_DMA_CHANNEL;

  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;

  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;

  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;

  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;

  hdma_tx.Init.Mode                = DMA_NORMAL;

  hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;


  HAL_DMA_Init(&hdma_tx);


  /* Associate the initialized DMA handle to the UART handle */

  __HAL_LINKDMA(huart, hdmatx, hdma_tx);


  /* Configure the DMA handler for reception process */

  hdma_rx.Instance                 = USARTx_RX_DMA_CHANNEL;

  hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;

  hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;

  hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;

  hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

  hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;

  hdma_rx.Init.Mode                = DMA_NORMAL;

  hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;


  HAL_DMA_Init(&hdma_rx);


  /* Associate the initialized DMA handle to the the UART handle */

  __HAL_LINKDMA(huart, hdmarx, hdma_rx);

然后掉用串口的DMA函數這個函數內部會調用DMA_START_IT()函數來進行DMA請求。


  /*##-2- Start the transmission process #####################################*/

  /* User start transmission data through "TxBuffer" buffer */

  if (HAL_UART_Transmit_DMA(&UartHandle, (uint8_t *)aTxBuffer, TXBUFFERSIZE) != HAL_OK)

  {

    /* Transfer error in transmission process */

    Error_Handler();

  }


  /*##-3- Put UART peripheral in reception process ###########################*/

  /* Any data received will be stored in "RxBuffer" buffer : the number max of

     data received is 10 */

  if (HAL_UART_Receive_DMA(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)

  {

    /* Transfer error in reception process */

    Error_Handler();

  }


上面的HAL_LINKDMA宏是用來關聯兩個類的。

#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD_, __DMA_HANDLE_)           \

                        do{                                                  \

                              (__HANDLE__)->__PPP_DMA_FIELD_ = &(__DMA_HANDLE_); \

                              (__DMA_HANDLE_).Parent = (__HANDLE__);             \

                          } while(0)


關鍵字:stm32  cube  HAL  DMA 引用地址:stm32.cube(九)——HAL.DMA

上一篇:S29GL128P norflash 讀寫擦除問題
下一篇:stm32.cube(十)——單HAL模塊的結構

推薦閱讀

開場白: 希望通過這篇文章記錄一下自己在調試NAND flash的經驗。希望對大家有用。 上個月搞了一塊開發板QT210。說實話沒有找到很多的datasheet就開始搞了。最早還是從boot說起,說到這這里不得不提到boot中打印的錯誤信息 ****CRC Error*****。最后還是決定靜心調試看看怎么回事。結果發現資料還是確少,怎么辦?找了以前的omap開發板。(個人...
4月17日的“第五屆國際汽車關鍵技術論壇”上,華為輪值董事長徐直軍發表了“迎接汽車產業與ICT產業的融合”的演講,正式對外公開華為進軍汽車產業的戰略路徑。華為將面向云服務、智能網聯、智能駕駛、智能互聯、智能能源五大領域提供解決方案。越來越多的企業進軍汽車行業,讓我覺得汽車產業的潛力遠遠還沒有被釋放出來。我們縱觀過去二十年的發展,對我們...
4月30日,至純科技發布今年一季度業績報告稱,公司實現營業收入為1.13億元,同比下降2.34%;實現歸屬于上市公司股東的凈利潤為-0.15億元,同比下降229.75%。與此同時,至純科技還發布2019年年度報告稱,公司實現營業收入9.86億元,同比增長46.34%;歸屬于上市公司股東的凈利潤為1.1億元,同比增長239.88%。按產品構成來看,高純工藝集成系統實現營業收入為...
近年來,數字經濟規模不斷擴張,已成為國民經濟的重要組成部分,美、英、德等國的數字經濟GDP占比超過60%,居主導地位。目前,我國正積極推進數字產業化、產業數字化,引導數字經濟和實體經濟深度融合,推動經濟高質量發展。其中,隨著數字經濟向能源領域加速滲透,能源行業加快數字化、網絡化、智能化轉型。作為一種應運而生的新經濟形態,能源數字經濟...

史海拾趣

問答坊 | AI 解惑

LCD驅動 如何去掉閃爍 arm9 2410

我的是2410的芯片,現在要驅動TX18D16VM1CAA的LCD,可是現在已經把分頻值設到最低了還是會抖動,什么原因? 聽人說好像是加電壓什么的,我設置的是24位的TFT模式,怎么操作啊~ …

查看全部問答∨

wince 中 壓縮與非壓縮dll xip dll 與非xip dll

由于嵌入式系統的特定要求,ce必須比桌面系統更有效的使用和節省物理內存,采用有rom文件系統與ram文件系統。可以在rom中存放壓縮的與非壓縮的文件,前者中的可執行文件(dll,exe)必須解壓到ram才可使用,后者如果在支持線性訪問的介質(如nor fl ...…

查看全部問答∨

高分請教:ARM(S3C2440)移植boa問題

   以下是我配置boa的過程: 配置boa: #cd /opt/EmbedSky/boa-0.94.13/src #./configure 說明:本來按照該配置腳本的提示是可以直接設置成交叉編譯的環境的,不過,經過實際試驗后發現 那樣是行不通的,無奈只能用這個笨方法了。 ...…

查看全部問答∨

嵌入式驅動工程師(月薪)

我是應屆畢業生!從大三開始學習嵌入式!都是自己在摸索!參加過嵌入式的競賽!有項目經驗! 個人本身也寫過驅動!簡單的字符設備驅動,flash的驅動!自己也正在看Linux內核!(情景分析+源代碼) 精通C/C++語言!熟悉JAVA(做過項目拿過獎)再者, ...…

查看全部問答∨

感謝acai1123壇友!~

本帖最后由 ddllxxrr 于 2016-1-7 17:13 編輯    本來打算在論壇求一塊TI C2000DSP學習一下,后來 壇友站內信聯系到我,愿意把C2000的板子贈送給我學習,真是感激不盡。    后來QQ一聊才知道原來還是我上屆的學長呀,世界真 ...…

查看全部問答∨

STM32啟動代碼---堆而非棧疑問

Heap_Size       EQU     0x00000200                 AREA    HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem  &nb ...…

查看全部問答∨

【設計工具】《Xilinx 可編程邏輯器件的高級應用與設計技巧》

  Xilinx公司是全球最大的可編程邏輯器件制造商,也是FPGA器件的發明者,特別是在通信技術領域,Xilinx不僅是一個提供通信器件的供應商,還積極地參與通信標準的制定,提供系統集成和系統解決方案等。為了滿足和適應市場的需要,該公司不斷地推出高性能 ...…

查看全部問答∨

mos管開關電路,有問題,求解

各位大俠,這是一個電機驅動電路,RL是負載電機,我用個200K的電阻代替。PWM信號是單片機輸過來的, 頻率是10K,現在我調節PWM的占空比,負載端的電壓穩定在12V。 如果我把三個電容:C1、C2、EC1都去掉,則負載端的電壓是一個隨PWM信號變化的方 ...…

查看全部問答∨

ADC0809數字電壓表顯示問題

設計圖如下, 由于硬件已經實現,無法更改,還望大神多多幫忙。 源代碼如下 //--------------------------------------- // AD0809 by maomaochong // Date: 2011/8/31 // Time: 15:54 // Function: ADDA-ADDC connect to P2.0-P2.2 to cho ...…

查看全部問答∨

求助!新手!stm32f407z的攝像頭OV9655實驗

用的是微雪的STM32F407z的開發板,攝像頭是OV9655,用隨板的示例程序測試只顯示已初始化成功,LCD上并無成像,是怎么回事啊?攝像頭,板子和lcd屏都沒問題! 我是新手,解答請詳細點,在此拜謝各位大神! ps:附主程序 #include "stm32f4xx.h ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 永顺县| 泰州市| 布尔津县| 望谟县| 定边县| 海淀区| 鹤山市| 黄大仙区| 沙雅县| 宁波市| 勐海县| 榆社县| 东光县| 霸州市| 台中县| 陇南市| 正镶白旗| 固阳县| 日喀则市| 阜宁县| 吴川市| 泰来县| 襄城县| 盘锦市| 惠来县| 江安县| 瑞安市| 仙居县| 皮山县| 鸡泽县| 彰化市| 金昌市| 赤水市| 桃园市| 吴川市| 桂林市| 大悟县| 乐陵市| 英超| 恭城| 临猗县|