最近使用 NXP i.MX RT1020 的 ADC 功能,發現官方的 SDK 例程中只有兩個例程,polling 和 interrupt,沒有 DMA 的,所以就動手寫了一個 ADC DMA 傳輸的代碼,在這裡分享一下。
(1)配置思路:
(2) 首先我們先導出一個 evkmimxrt1020_adc_12b1msps_sar_polling 的例程
(3) DMA 的配置: 配置 DMAMUX 模塊: 相關宏定義: DMA 有很多通道,那麼每個通道對應的 DMA 請求是什麼呢?這裡 NXP 提供了 DMAMUX 模塊,這個就是可以配置通道對應的 DMA 請求, SDK 中相關枚舉定義如下:
(4)DMA 的初始化如下:
NXP 的 DMA 驅動都是以 handle 的方式來實現的,可以把 handle 理解為一個存儲各種信息的結構體,裡面可以有參數,也可以有函數,一個 handle 就包含了這個通道的所有信息,目的是為了統一管理使用,接下來就逐個介紹相關 API 的功能。
創建一個 handle ,第二參數指定了這是哪個 DMA 通道的 handle;
指定該通道傳輸完成之後的中斷函數:該回調函數由用戶自定義,只需要把函數名給到第二個參數即可;
復位該通道相關參數,方便接下來的配置
這裡的配置實際上就是 DMA 描述符的配置,描述符裡面的信息比較通用,源地址、目的地址等等,注意這裡只是把相關信息賦值給了 transferConfig,但是並沒有實際寫進 DMA 的寄存器當中;
這個函數第一個參數 tcdMemoryPoolptr 的定義如下,可以看到這是定義了一套完整的 TCD 寄存器,方便後續寫寄存器使用;
第 3 個參數 &tcdMemoryPoolptr[0] 則是指定當前傳輸完成一次後,下一次的傳輸描述符,這樣就不需要再次配置,相當於 DMA 會自動重裝載相關信息;
使能 DMA 傳輸完成中斷
前面說了描述符參數存儲在結構體當中並未寫進實際寄存器,這個函數就將描述符的內容寫進了對應的寄存器當中,函數內部如下:
最後就是開始 DMA 傳輸,當有 DMA 請求的時候則會自動開始傳輸
(5)在主循環中,軟體觸發 ADC 採集
參考資料: |