【STM32H7教程】第59章 STM32H7的DAC基礎知識和HAL庫API

完整教程下載地址: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 初學者重要提示

  1.   注意STM32H7只有一個DAC,但有兩個獨立的通道,跟F4的略不同,F4是兩個DAC。
  2.   如果僅使用STM32H7的一個通道,即PA4或者PA5引腳,另一個引腳沒有做任何配置,這個引腳上會有波形效應。
  3.   STM32H7的DAC支持出廠校準和用戶校準模式。特別注意一點,校準是建立在用戶使能了輸出緩衝的情況下才有效。
  4.   STM32H7的DAC支持正常模式和採樣保持模式,其中採樣保持模式用於低功耗狀態使用。
  5.   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表示時間溢出。

注意事項:

  1. 函數HAL_DAC_MspInit用於初始化DAC的底層時鐘、NVIC等功能。需要用戶自己在此函數裏面實現具體的功能。由於這個函數是弱定義的,允許用戶在工程其它源文件裏面重新實現此函數。當然,不限制一定要在此函數裏面實現,也可以像早期的標準庫那樣,用戶自己初始化即可,更靈活些。
  2. 如果形參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功能用到的地方還是比較多的,建議熟練使用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章