STM32之DAC君

      如花說得好:呃呃呃、是俗話說得好:有了ADC,怎可少了DAC、、我以爲奇怪、今天我開頭就直奔主題了、我想了想,總結了一句話:孫悟空縱然有七十二變、不管是變成貓也好,變成狗也罷、始終仍是會變回他自己、因此我怎麼的拐彎抹角,仍是會回到DAC、、這不、前面幾句廢話,仍是回到了講DAC上來了、、好吧、今天就直接一點吧,換個風格的開頭、算法

      先來張好比花漂亮的照片、你們請盡情欣賞:由於其夠美麗了、因此我就不展示我美麗而銷魂的塗鴉了、編程

     鑑賞過以後、咱們來看看STM32之DAC的Resume(簡歷簡介):緩存

   ● 2個DAC轉換器:每一個轉換器對應1個輸出通道數據結構

   ● 8位或者12位單調輸出函數

   ● 12位模式下數據左對齊或者右對齊學習

   ● 同步更新功能ui

   ● 噪聲波形生成spa

   ● 三角波形生成3d

   ● 雙DAC通道同時或者分別轉換code

   ● 每一個通道都有DMA功能

   ● 外部觸發轉換

   ● 輸入參考電壓VREF+

   哇、、哇、、哇、、好多特徵呀、、還記得上篇博客中ADC也有不少功能嗎?在這裏,我以爲,由於其功能多、因此其複雜、、這也沒什麼奇怪的哈、、

   那咱們今天要幹嗎呢?DAC顧名思義,輸入量是D,也就是D、、而輸出量是A、也顧名思義、固然、對於聰明的大家來講D A表明哪一個英文單詞和普通話意思是知道的、

    由上圖能夠清晰的看出,DAC的輸出是受DORX寄存器直接控制的,而用戶的寫的數據是寫在DHRX寄存器裏的、說明咱們不能直接操控DORX,而要經過DORX間接操做DORX,從而實現對DAC的輸出、

    今天咱們是採用DAC的通道1,採用12位的右對齊方式,對於對齊方式,你們翻開中文參考手冊能夠看到:

       ● 單DAC通道x,有3種狀況:

       ─ 8位數據右對齊:用戶須將數據寫入寄存器DAC_DHR8Rx[7:0]位(實際是存入寄存器DHRx[11:4]位)

       ─ 12位數據左對齊:用戶須將數據寫入寄存器DAC_DHR12Lx[15:4]位(實際是存入寄存器DHRx[11:0]位)

       ─ 12位數據右對齊:用戶須將數據寫入寄存器DAC_DHR12Rx[11:0]位(實際是存入寄存器DHRx[11:0]位)

       根據對DAC_DHRyyyx寄存器的操做,通過相應的移位後,寫入的數據被轉存到DHRx寄存器中(DHRx是內部的數據保存寄存器x)。隨後,DHRx寄存器的內容或被自動地傳送到DORx寄存器,或經過軟件觸發或外部事件觸發被傳送到DORx寄存器。(這段話也就是對上張圖片的描述)

       接下來咱們看看

      一、輸入輸出使能:

      通道使能控制:EN1@DAC_CR

      一旦通道使能,輸出引腳PA.4就被自動連到模擬轉換器的輸出

      使能通道以前,PA.4要配置成模擬模式AIN

   
      該使能信號只使能了模擬部分,數字接口部分由DACEN@RCC_APB1ENR控制WAKEUP
      通過t WAKEUP時間後DAC通道準備就緒
      DAC通道上的引腳輸出模擬電壓 = VREF+ * (DOR / 4095)
      輸出通道上集成可配置的輸出緩衝,以減少自身的輸出阻抗
      使能控制:BOFF1@DAC_CR

     二、輸出通道上的緩衝:

      通道內嵌輸出緩衝以增長驅動能力     

      外部負載較大時,無需增長外部放大器

      可以使能或禁止該緩衝

      外部有大負載,且緩衝禁止時,輸出電壓可能達不到預期

      介紹兩張圖片:你們能夠對比對比下,在這就不細講了、

     

     三、DAC的轉換過程:

    用戶寫入DAC_DHRx的值,自動或者在外部觸發條件下通過一段時間後,傳輸到DAC_DORx;再通過一段固定時間tSETTLING,在外部引腳輸出轉換後的模擬信號(電壓)。

        (1)對DAC_DHRx的寫操做
      (2)數據從DHRx到DORx的搬移
      (3)輸出電壓信號到外部引腳

      咱們來看看寄存器DAC控制寄存器(DAC_CR)

     DMAEN1:DAC通道1 DMA使能 (DAC channel1 DMA enable),咱們不使用DMA,故設置爲0

     MAMP1[3:0]:DAC通道1屏蔽/幅值選擇器 (DAC channel1 mask/amplitude selector)咱們沒有用到 故這幾位也設置爲0

     WAVE1[1:0]:DAC通道1噪聲/三角波生成使能 (DAC channel1 noise/triangle wave generation enable)咱們也沒用到 故也設置爲0

     TEN1:DAC通道1觸發使能 (DAC channel1 trigger enable)咱們不用觸發,因此設置爲0

     TSEL1[2:0]:DAC通道1觸發選擇 (DAC channel1 trigger selection)注意:該位只能在TEN1= 1(DAC通道1觸發使能)時設置。咱們TEN1設爲0,因此這幾位就不用設置,默認爲0

     BOFF1:關閉DAC通道1輸出緩存 (DAC channel1 output buffer disable)咱們關閉輸出緩衝 故設置爲1

     EN1:DAC通道1使能 (DAC channel1 enable)咱們要使能DAC通道、故設置爲1

    至此,咱們已經設置了以上寄存器,咱們就能夠操做DAC了,可是咱們並非經過寄存器操做的、在這裏擺出寄存器的設置,是爲了你們有一個更好的瞭解,那咱們打開"stm32f10x_dac.h"

     能夠看到:

typedef struct
{
  uint32_t DAC_Trigger;                      /*!< Specifies the external trigger for the selected DAC channel.設置是否使用觸發功能
                                                  This parameter can be a value of @ref DAC_trigger_selection */

  uint32_t DAC_WaveGeneration;               /*!< Specifies whether DAC channel noise waves or triangle waves設置是否使用波形發生
                                                  are generated, or whether no wave is generated.
                                                  This parameter can be a value of @ref DAC_wave_generation */

  uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or設置屏蔽/幅值選擇器
                                                  the maximum amplitude triangle generation for the DAC channel. 
                                                  This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */

  uint32_t DAC_OutputBuffer;                 /*!< Specifies whether the DAC channel output buffer is enabled or disabled.設置輸出緩存控制位

 }DAC_InitTypeDef;

     根據以上說明,具體的設置請看代碼、、

   那好、、如今咱們來看看具體的步驟:

  一、使能DAC的時鐘和GPIOA的時鐘,並配置GPIOA

  二、設置DAC的工做模式等功能

  三、使能DAC通道

  四、設置DAC的輸出值 

void Dac1_Init(void)
{
   DAC_InitTypeDef  DAC_InitStructure;
     GPIO_InitTypeDef GPIO_InitStructure;

    /* Enable peripheral clocks ------------------------------------------------*/
  /* GPIOA Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* DAC Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    
  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically 
     connected to the DAC converter. In order to avoid parasitic consumption, 
     the GPIO pin should be configured in analog */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4);
     /* DAC channel1 Configuration */
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
    
  /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is 
     automatically connected to the DAC converter. */
  DAC_Cmd(DAC_Channel_1, ENABLE);
    
      /* Set DAC Channel1 DHR12L register *初始化/
  DAC_SetChannel1Data(DAC_Align_12b_R, 0);

}
//設置DAC通道的值咱們能夠經過按鍵 例如
if(按鍵按下)
{
delay_ms(10);

DAC_SetChannel1Data(DAC_Align_12b_R, a += 200);
 if(a>4000)
{
a = 0;
}
}
,或者由ADC轉換後的值,給DAC採集
adcx=DAC_GetDataOutputValue(DAC_Channel_1);//經過此函數咱們能夠讀取設置DAC通道里的值也就是DOR裏的數(0~4095)
DAC通道上的引腳輸出模擬電壓 = VREF+ * (DOR / 4095)//根據此公式就能夠計算出模擬輸出電壓、、
此模擬電壓又能夠被ADC採集,從而輸出(0~4095),你能夠把二者結合起來,經過必定的編程,經過串口發送到窗口,看你設置的值和經ADC轉換的值(0~4095)是否相等

PS:此步驟也能夠在官方的例程裏找到步驟哈、

       在聽完小甲魚的數據結構與算法後、整理了一下昨天學的DAC模塊,寫了這篇博客、看着面前的一大堆書:數據結構,算法導論、通訊原理、計算機控制等、、總想讓本身在畢業以前多學習,多學些知識、能夠看出、這篇博客的幽默是少了不少、、但我以爲不影響這篇博客的質量、、STM3二、、嗯、仍是那句;                                         廣大的互聯網的網友們、你們早上中午晚上好、、但願能幫到你、、騷年們、、一塊兒努力吧、、

    PS:小甲魚的視頻不錯、幽默風趣、推薦給你們、、但願你們能學多點本身感興趣的知識哈、、後會有期

相關文章
相關標籤/搜索