完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第59章 STM32H7的DAC基礎知識和HAL庫API
本章節爲大家講解DAC,實際項目用到DAC的地方比較多,而且H7的DAC性能也比較給力。
59.1 初學者重要提示
59.2 DAC基礎知識
59.3 DAC的HAL庫用法
59.4 源文件stm32h7xx_hal_dac.c
59.5 總結
59.1 初學者重要提示
- 注意STM32H7只有一個DAC,但有兩個獨立的通道,跟F4的略不同,F4是兩個DAC。
- 如果僅使用STM32H7的一個通道,即PA4或者PA5引腳,另一個引腳沒有做任何配置,這個引腳上會有波形效應。
- STM32H7的DAC支持出廠校準和用戶校準模式。特別注意一點,校準是建立在用戶使能了輸出緩衝的情況下才有效。
- STM32H7的DAC支持正常模式和採樣保持模式,其中採樣保持模式用於低功耗狀態使用。
- DAC的輸出除了可以連接PA4或者PA5引腳,也可以連接到片上外設,比如運放,比較器。
59.2 DAC基礎知識
對於STM32H7的DAC瞭解到以下幾點即可:
- STM32H7的DAC只有一個,但有兩個獨立的通道,跟F4的略不同,F4是兩個DAC
- 12位分辨率,雙通道,支持獨立或者同時使用。
- 兩個DAC通道均支持DMA。
- 每路DAC輸出均可與DAC_OUTx輸出引腳斷開連接,而且DAC 輸出可與片上外設連接。
- 支持偏移校準,參考電壓可以使用內部的VREFBUF,也可以使用VREF+引腳外接的電壓基準。
- 支持噪聲波和三角波生成。這兩種方案不夠靈活,所以基本都採用定時器觸發+DMA方式生成任意波形。
59.2.1 DAC硬件框圖
認識一個外設,最好的方式就是看它的框圖,方便我們快速地瞭解DAC的基本功能,然後再看手冊瞭解細節。框圖如下所示:
通過這個框圖,我們可以得到如下信息:
- VDDA
用於ADC、DAC、運放、比較器和電壓基準供電,這部分供電是獨立的。
- VREF+
用於ADC和DAC的基準電壓,當使能了STM32H7內部的電壓基準,將使用內部基準供VREF+,VREF-。如果沒有使能的話,通過外置電壓基準提供。
- VSSA
所有電源和模擬穩壓器的地端。
- dac_ch1_dma
DAC通道1的DMA請求。
- dac_ch2_dma
DAC通道2的DMA請求。
- dac_ch1_trg[0:15]
DAC通道1的輸入觸發。
- dac_ch2_trg[0:15]
DAC通道2的輸入觸發。
- dac_unr_it
DAC輸出的下溢中斷信號。
- dac_pclk
DAC時鐘輸入
- dac_out1
DAC通道1輸出。
- dac_out2
DAC通道2輸出。
- lsi_ck
使用LSI時鐘源,可以讓DAC在停止模式下運行。
59.2.2 DAC數據格式和輸出電壓
DAC的數據寄存器設計比較靈活,每個通道都有一組單獨的寄存器(下面是通道1的寄存器):
- 8位右對齊數據保持寄存器DACx_DHR8R1。
- 12位右對齊數據保持寄存器DACx_DHR12R1。
- 12位左對齊數據保持寄存器DACx_DHR12L1。
除了這種單獨寄存器,爲了降低帶寬,也支持兩個通道公用一個寄存器。
- 8 位右對齊數據保持寄存器DACx_DHR8RD。
- 12 位左對齊數據保持寄存器DACx_DHR12LD。
- 12 位右對齊數據保持寄存器DACx_DHR12RD。
通道1和通道2共用的效果如下:
由於DAC是12bit的DAC,那麼範圍就是0-4095,對應的輸出電壓如下:
DAC Output = Vref *(DOR / 4095),其中Vref是參考電壓,DOR是數據輸出寄存器。
比如需要DAC輸出0.7V,那麼假設VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V。
59.2.3 DAC支持的觸發源
DAC支持軟件觸發和硬件觸發,具體支持的觸發源如下:
#define DAC_TRIGGER_NONE ((uint32_t)0x00000000) #define DAC_TRIGGER_SOFTWARE ((uint32_t)(DAC_CR_TEN1)) #define DAC_TRIGGER_T1_TRGO ((uint32_t)(DAC_CR_TSEL1_0 | DAC_CR_TEN1)) #define DAC_TRIGGER_T2_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TEN1)) #define DAC_TRIGGER_T4_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) #define DAC_TRIGGER_T5_TRGO ((uint32_t)(DAC_CR_TSEL1_2 |DAC_CR_TEN1)) #define DAC_TRIGGER_T6_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) #define DAC_TRIGGER_T7_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1)) #define DAC_TRIGGER_T8_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) #define DAC_TRIGGER_T15_TRGO ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TEN1)) #define DAC_TRIGGER_HR1_TRGO1 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) #define DAC_TRIGGER_HR1_TRGO2 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TEN1)) #define DAC_TRIGGER_LP1_OUT ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) #define DAC_TRIGGER_LP2_OUT ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TEN1)) #define DAC_TRIGGER_EXT_IT9 ((uint32_t)(DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1))
59.2.4 DAC正常模式和採樣保持模式
關於正常模式和採樣保持模式,注意以下幾點:
- 正常模式是平時最常用的方式,比較好理解。而採樣保持模式用於低功耗方式。
- 在採樣保持模式下,DAC內核轉換數據,然後保持電容上的電壓。不轉換時,DAC內核和樣本之間的緩衝器完全關閉,DAC輸出爲三態,因此降低了整體功耗,但每次新轉換前都需要一段穩定期。
- 採樣保持模式可修改內部或者外部參考電壓。
- 採樣保持部分可以用LSI時鐘,也可以運行在幾種低功耗模式下,如RUN模式, SLEEP& STOP模式。
59.2.5 DAC的出廠校準和用戶校準
一般情況下,使用出廠校準即可,芯片上電後自動完成出廠校準。而用戶校準略麻煩,暫不做研究。這裏特別注意一點,校準是建立在用戶使能了輸出緩衝的情況下才有效。
59.3 DAC的HAL庫用法
DAC的HAL庫用法其實就是幾個結構體變量成員的配置和使用,然後配置時鐘,並根據需要配置NVIC、中斷和DMA。下面我們逐一展開爲大家做個說明。
59.3.1 DAC寄存器結構體DAC_TypeDef
DAC相關的寄存器是通過HAL庫中的結構體DAC_TypeDef定義的,在stm32h743xx.h中可以找到它們的具體定義:
typedef struct { __IO uint32_t CR; __IO uint32_t SWTRIGR; __IO uint32_t DHR12R1; __IO uint32_t DHR12L1; __IO uint32_t DHR8R1; __IO uint32_t DHR12R2; __IO uint32_t DHR12L2; __IO uint32_t DHR8R2; __IO uint32_t DHR12RD; __IO uint32_t DHR12LD; __IO uint32_t DHR8RD; __IO uint32_t DOR1; __IO uint32_t DOR2; __IO uint32_t SR; __IO uint32_t CCR; __IO uint32_t MCR; __IO uint32_t SHSR1; __IO uint32_t SHSR2; __IO uint32_t SHHR; __IO uint32_t SHRR; } DAC_TypeDef;
__IO表示volatile, 這是標準C語言中的一個修飾字,表示這個變量是非易失性的,編譯器不要將其優化掉。core_m7.h 文件定義了這個宏:
#define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */
下面我們再看DAC的定義,在stm32h743xx.h文件。
#define PERIPH_BASE ((uint32_t)0x40000000) #define D2_APB1PERIPH_BASE PERIPH_BASE #define DAC1_BASE (D2_APB1PERIPH_BASE + 0x7400) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) <----- 展開這個宏,(DAC_TypeDef *) 0x40007400
我們訪問DAC1的CR寄存器可以採用這種形式:DAC1->CR = 0。
59.3.2 DAC的採樣保持DAC_SampleAndHoldConfTypeDef
此結構體用於DAC的採樣保持參數,具體定義如下:
typedef struct { uint32_t DAC_SampleTime ; uint32_t DAC_HoldTime ; uint32_t DAC_RefreshTime ; } DAC_SampleAndHoldConfTypeDef;
下面將這幾個參數逐一爲大家做個說明:
- uint32_t DAC_SampleTime
此參數用於設置DAC的採樣時間,範圍0 - 1023。
- uint32_t DAC_HoldTime
此參數用於設置DAC的保持時間,範圍0 – 1023。
- uint32_t DAC_RefreshTime
此參數用於設置DAC的刷新時間,範圍0 – 255。
59.3.3 DAC的通道參數結構體DAC_ChannelConfTypeDef
此結構體用於DAC的通道參數配置,具體定義如下:
typedef struct { uint32_t DAC_SampleAndHold; uint32_t DAC_Trigger; uint32_t DAC_OutputBuffer; uint32_t DAC_ConnectOnChipPeripheral ; uint32_t DAC_UserTrimming; uint32_t DAC_TrimmingValue; DAC_SampleAndHoldConfTypeDef DAC_SampleAndHoldConfig; }DAC_ChannelConfTypeDef;
下面將這幾個參數逐一爲大家做個說明:
- uint32_t DAC_SampleAndHold
此參數用於使能採樣保持模式,具體支持的參數如下:
#define DAC_SAMPLEANDHOLD_DISABLE ((uint32_t)0x00000000) #define DAC_SAMPLEANDHOLD_ENABLE ((uint32_t)DAC_MCR_MODE1_2)
- uint32_t DAC_Trigger
此參數用於DAC觸發源的選擇,具體支持的參數如下:
#define DAC_TRIGGER_NONE #define DAC_TRIGGER_SOFTWARE #define DAC_TRIGGER_T1_TRGO #define DAC_TRIGGER_T2_TRGO #define DAC_TRIGGER_T5_TRGO #define DAC_TRIGGER_T6_TRGO #define DAC_TRIGGER_T7_TRGO #define DAC_TRIGGER_T8_TRGO #define DAC_TRIGGER_T15_TRGO #define DAC_TRIGGER_HR1_TRGO1 #define DAC_TRIGGER_HR1_TRGO2 #define DAC_TRIGGER_LP1_OUT #define DAC_TRIGGER_LP2_OUT #define DAC_TRIGGER_EXT_IT9
- uint32_t DAC_OutputBuffer
此參數用於使能或者關閉DAC的輸出緩衝,使能輸出緩衝後,可以增加DAC的驅動能力,具體支持的參數如下:
#define DAC_OUTPUTBUFFER_ENABLE ((uint32_t)0x00000000) #define DAC_OUTPUTBUFFER_DISABLE ((uint32_t)DAC_MCR_MODE1_1)
- uint32_t DAC_ConnectOnChipPeripheral
此參數用於DAC是否連接片上外設(運放,比較器等),具體支持的參數如下:
#define DAC_CHIPCONNECT_DISABLE ((uint32_t)0x00000000) #define DAC_CHIPCONNECT_ENABLE ((uint32_t)DAC_MCR_MODE1_0)
- uint32_t DAC_UserTrimming
此參數用於設置DAC的校準方式,採用出廠模式還是用戶模式,具體支持的參數如下:
#define DAC_TRIMMING_FACTORY ((uint32_t)0x00000000) #define DAC_TRIMMING_USER ((uint32_t)0x00000001)
- uint32_t DAC_TrimmingValue
此參數用於設置用戶校準模式的偏移值,參數範圍1-31。
- DAC_SampleAndHoldConfTypeDef DAC_SampleAndHoldConfig
此參數用於採樣保持具體參數設置,詳解本章3.2小節的說明。
59.3.4 DAC結構體句柄DAC_HandleTypeDef
HAL庫在DAC_TypeDef的基礎上封裝了一個結構體DAC_HandleTypeDef,定義如下:
typedef struct { DAC_TypeDef *Instance; __IO HAL_DAC_StateTypeDef State; HAL_LockTypeDef Lock; DMA_HandleTypeDef *DMA_Handle1; DMA_HandleTypeDef *DMA_Handle2; __IO uint32_t ErrorCode; }DAC_HandleTypeDef;
下面將這幾個參數逐一做個說明。
- DAC_TypeDef *Instance
這個參數是寄存器的例化,方便操作寄存器,詳見本章3.1小節。
- DMA_HandleTypeDef *DMA_Handle1
- DMA_HandleTypeDef *DMA_Handle2
DMA句柄結構體指針變量,用於關聯DAC句柄,方便調用。
- HAL_LockTypeDef Lock
- __IO HAL_DAC_STATETypeDef State
- __IO uint32_t ErrorCode
這三個變量主要供函數內部使用。Lock用於設置鎖狀態,State用於設置DAC狀態,而ErrorCode用於配置代碼錯誤。
59.3.5 DAC初始化流程總結
使用方法由HAL庫提供:
第1步:基本的初始化。
- 函數HAL_DAC_Init初始化。
- 配置DAC_OUT1: PA4, DAC_OUT2: PA5引腳爲模擬模式。
- 函數HAL_DAC_ConfigChannel配置通道參數。
- 函數HAL_DAC_Start() or HAL_DAC_Start_DMA()使能DAC。
第2步:DAC校準。
- 出廠校準比較簡單,芯片上電後自動完成,而用戶校準需要依次調用函數HAL_DACEx_GetTrimOffset,HAL_DACEx_SelfCalibrate和HAL_DACEx_SetUserTrimming。
第3步:查詢模式。
- 函數HAL_DAC_Start() 啓動。
- 函數HAL_DAC_GetValue()可以讀取輸出值。
- 函數HAL_DAC_Stop可以停止DAC。
第4步:DMA方式。
- 函數HAL_DAC_Start_DMA()啓動DMA方式轉換。
- DAC的數據傳輸一半的時候, HAL_DAC_ConvHalfCpltCallbackCh1() 或者 HAL_DACEx_ConvHalfCpltCallbackCh2() 會被調用。
- DAC的數據傳輸完成的時候,HAL_DAC_ConvCpltCallbackCh1() 或者 HAL_DACEx_ConvHalfCpltCallbackCh2() 會被調用。
- 傳輸錯誤時,函數HAL_DAC_ErrorCallbackCh1會被調用。
- DMA下溢錯誤,會調用函數HAL_DAC_DMAUnderrunCallbackCh1()或者HAL_DACEx_DMAUnderrunCallbackCh2()。
- 停止DAC的DMA方式,可以調用函數HAL_DAC_Stop_DMA
59.4 源文件stm32h7xx_hal_dac.c
這裏把我們把如下幾個常用到的函數做個說明:
- HAL_DAC_Init
- HAL_DAC_ConfigChannel
- HAL_DAC_Start_DMA
59.4.1 函數HAL_DAC_Init
函數原型:
HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac) { /* 檢測DAC句柄 */ if(hdac == NULL) { return HAL_ERROR; } assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance)); if(hdac->State == HAL_DAC_STATE_RESET) { hdac->Lock = HAL_UNLOCKED; /* 初始化GPIO,NVIC等 */ HAL_DAC_MspInit(hdac); } /* 設置DAC狀態忙 */ hdac->State = HAL_DAC_STATE_BUSY; /* 設置DAC無錯誤 */ hdac->ErrorCode = HAL_DAC_ERROR_NONE; /* 設置DAC就緒 */ hdac->State = HAL_DAC_STATE_READY; /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數用於初始化DAC。
函數參數:
- 第1個參數是DAC_HandleTypeDef類型結構體指針變量,結構體變量成員的詳細介紹看本章3.4小節。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 函數HAL_DAC_MspInit用於初始化DAC的底層時鐘、NVIC等功能。需要用戶自己在此函數裏面實現具體的功能。由於這個函數是弱定義的,允許用戶在工程其它源文件裏面重新實現此函數。當然,不限制一定要在此函數裏面實現,也可以像早期的標準庫那樣,用戶自己初始化即可,更靈活些。
- 如果形參hdac的結構體成員State沒有做初始狀態,這個地方就是個坑。特別是用戶搞了一個局部變量DAC_HandleTypeDef DacHandle。
對於局部變量來說,這個參數就是一個隨機值,如果是全局變量還好,一般MDK和IAR都會將全部變量初始化爲0,而恰好這個 HAL_DAC_STATE_RESET = 0x00U。
解決辦法有三
方法1:用戶自己初始DAC底層。
方法2:定義DAC_HandleTypeDef DacHandle爲全局變量。
方法3:下面的方法
if(HAL_DAC_DeInit(&DacHandle) != HAL_OK) { Error_Handler(); } if(HAL_DAC_Init(&DacHandle) != HAL_OK) { Error_Handler(); }
使用舉例:
DAC_HandleTypeDef DAC_Handle; DacHandle.Instance = DAC1; if (HAL_DAC_Init(&DacHandle) != HAL_OK) { Error_Handler(__FILE__, __LINE__); }
59.4.2 函數HAL_DAC_ConfigChannel
函數原型:
HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel) { uint32_t tmpreg1 = 0, tmpreg2 = 0; uint32_t tickstart = 0; /* 部分省略,未貼出 */ /* 上鎖 */ __HAL_LOCK(hdac); /* 設置DAC忙 */ hdac->State = HAL_DAC_STATE_BUSY; if(sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE) { /* 通道1設置 */ if (Channel == DAC_CHANNEL_1) { } else /* 通道2設置 */ { } } if(sConfig->DAC_UserTrimming == DAC_TRIMMING_USER) /* 用戶校準配置 */ { } /* 出廠模式無需配置,復位後自動設置 */ /* 獲取DAC MCR數值 */ tmpreg1 = hdac->Instance->MCR; /* 清除DAC_MCR_MODE2_0, DAC_MCR_MODE2_1 和 DAC_MCR_MODE2_2 位 */ tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << Channel); /* 配置DAC通道 */ tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | sConfig->DAC_ConnectOnChipPeripheral); tmpreg1 |= tmpreg2 << Channel; /* 設置MCR數值 */ hdac->Instance->MCR = tmpreg1; /* DAC工作在正常模式 */ CLEAR_BIT (hdac->Instance->CR, DAC_CR_CEN1 << Channel); /* 獲取DAC CR值 */ tmpreg1 = hdac->Instance->CR; tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << Channel); tmpreg2 = (sConfig->DAC_Trigger); tmpreg1 |= tmpreg2 << Channel; /* 寫DAC CR值 */ hdac->Instance->CR = tmpreg1; /* 禁止波形生成 */ hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel); /* 設置DAC就緒 */ hdac->State = HAL_DAC_STATE_READY; /* 解鎖 */ __HAL_UNLOCK(hdac); /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數主要用於配置DAC的通道參數。
函數參數:
- 第1個參數是DAC_HandleTypeDef類型結構體指針變量,結構體變量成員的詳細介紹看本章3.4小節。
- 第2個參數是DAC_ChannelConfTypeDef類型結構體指針變量,用於DAC的通道參數配置,結構體變量成員的詳細介紹看本章3.3小
- 第3個參數用於選擇要配置那個通道,DAC_CHANNEL_1表示配置通道1,DAC_CHANNEL_2表示配置通道2。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
static DAC_ChannelConfTypeDef sConfig; static DAC_HandleTypeDef DacHandle; sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE; /* 關閉採樣保持模式,這個模式主要用於低功耗 */ sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO; /* 採用定時器6觸發 */ sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; /* 使能輸出緩衝 */ sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;/* 不將DAC連接到片上外設 */ sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY; /* 使用出廠校準 */ if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(__FILE__, __LINE__); }
59.4.3 函數HAL_DAC_Start_DMA
函數原型:
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment) { uint32_t tmpreg = 0; /* 部分省略,未貼出 */ /* 檢測參數 Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_ALIGN(Alignment)); /* 上鎖 Process locked */ __HAL_LOCK(hdac); /* 設置DAC忙 Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; /* 配置通道1 */ if(Channel == DAC_CHANNEL_1) { /* DMA傳輸完成回調 */ hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; /* DMA半傳輸完成回調 */ hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; /* DMA傳輸錯誤回調 */ hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; /* 使能DAC DMA */ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1); /* 數據對齊方式設置 */ switch(Alignment) { case DAC_ALIGN_12B_R: tmpreg = (uint32_t)&hdac->Instance->DHR12R1; break; case DAC_ALIGN_12B_L: tmpreg = (uint32_t)&hdac->Instance->DHR12L1; break; case DAC_ALIGN_8B_R: tmpreg = (uint32_t)&hdac->Instance->DHR8R1; break; default: break; } } else { } } /* 使能DMA Stream */ if(Channel == DAC_CHANNEL_1) { /* 使能DAC DMA下溢中斷 */ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); /* 啓動傳輸 */ HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length); } else { __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length); } /* 解鎖 */ __HAL_UNLOCK(hdac); /* 使能DAC通道 */ __HAL_DAC_ENABLE(hdac, Channel); /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數用於啓動DAC的DMA方式
函數參數:
- 第1個參數是DAC_HandleTypeDef類型結構體指針變量,結構體變量成員的詳細介紹看本章3.4小節。
- 第2個參數用於選擇要配置那個通道,DAC_CHANNEL_1表示配置通道1,DAC_CHANNEL_2表示配置通道2。
- 第3個參數是波形數據地址。
- 第4個參數是傳輸的數據長度。
- 第5個參數是數據對齊方式設置。
- DAC_ALIGN_8B_R 表示8bit右對齊。
- DAC_ALIGN_12B_L 表示12bit左對齊。
- DAC_ALIGN_12B_R 表示12bit右對齊。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
static DAC_HandleTypeDef DacHandle; /* 啓動DAC DMA */ if (HAL_DAC_Start_DMA(&DacHandle, DAC_CHANNEL_2, (uint32_t *)g_usWaveBuff, 64, DAC_ALIGN_12B_R) != HAL_OK) { Error_Handler(__FILE__, __LINE__); }
59.5 總結
本章節就爲大家講解這麼多,DAC功能用到的地方還是比較多的,建議熟練使用。