上一篇介紹了《STM32ADC詳解》,既然有模擬轉數字的ADC模塊,那麼就必然有數字轉模擬的DAC模塊。顧名思義,該模塊僅具備ADC的補充功能。它將數字二進制值轉換爲模擬電壓輸出。DAC模塊具備多種用途,包括音頻生成,波形生成等。一般在大多數8位微控制器中,此模塊不可用,而且經過脈寬調製(PWM)能夠稍微知足其需求。部分緣由是因爲它們的硬件資源和運行速度相對較低。全部STM32單片機都具備PWM模塊,但大容量STM32也具備DAC模塊。STM32DAC模塊不是很複雜,而且在工做原理方面與ADC模塊類似。git
從STM32F207數據手冊看到,STM32F207具備兩個DAC模塊。github
每一個DAC具備獨立的通道,對應的GPIO分別爲:PA4和PA5。對於GPIO的複用功能(Alternatefunctions)和附加功能(Additionalfunctions),在《STM32ADC詳解》有詳細講解。緩存
除了DAC輸出的管腳,還有其餘相關引腳app
注意:使能DAC 通道x 後,相應GPIO 引腳(PA4 或PA5)將自動鏈接到模擬轉換器輸出(DAC_OUTx)。爲了不寄生電流消耗,應首先將PA4 或PA5 引腳配置爲模擬模式(AIN)。測試
下面的簡化框圖顯示了STM32DAC模塊的主要組件。ui
由框圖能夠看出,DAC受DORx寄存器直接控制的,可是不能直接往DORx寄存器寫入數據,而是經過DHRx間接地傳給DORx寄存器,實現對DAC的輸出控制。spa
不能直接對寄存器DAC_DORx寫入數據,任何輸出到DAC通道x的數據都必須寫入DAC_DHRx寄存器(數據實際寫入DAC_DHR8Rx、DAC_DHR12Lx、DAC_DHR12Rx、DAC_DHR8RD、DAC_DHR12LD、或者DAC_DHR12RD寄存器)。3d
若是沒有選中硬件觸發(寄存器DAC_CR1的TENx位置0),存入寄存器DAC_DHRx的數據會在一個APB1時鐘週期後自動傳至寄存器DAC_DORx;code
若是選中硬件觸發(寄存器DAC_CR1的TENx位置1),數據傳輸在觸發發生之後3個APB1時鐘週期後完成。blog
一旦數據從DAC_DHRx寄存器裝入DAC_DORx寄存器,在通過時間tSETTLING以後,輸出即有效,這段時間的長短依電源電壓和模擬輸出負載的不一樣會有所變化。
DAC控制寄存器(DAC_CR)
DMAEN1:DAC通道1DMA使能(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 generationenable)咱們也沒用到故也設置爲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。
STM32的DAC等效電路以下
該電路中顯示的輸出緩衝器在內部3.3V電源上運行。與大多數運放在單電源(而不是+/-雙電源)上運行同樣,輸出擺幅永遠不會真正達到目標。可是,如電路所示,有兩個內部開關(S1和S2)可經過寄存器控制。將它們都打開將經過兩個串聯的電阻(Ra和Rb)將「DACINT」信號直接鏈接到「DACOUT」引腳。做爲參考,Ra+ Rb約爲15k。
根據選擇的配置模式,數據按照下文所述寫入指定的寄存器:
單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]位)。
通常採用第三種方式:12位數據右對齊比較多。
根據對DAC_DHRyyyx寄存器的操做,通過相應的移位後,寫入的數據被轉存到DHRx寄存器中(DHRx是內部的數據保存寄存器x)。隨後,DHRx寄存器的內容或被自動地傳送到DORx寄存器,或經過軟件觸發或外部事件觸發被傳送到DORx寄存器。
雙DAC通道,有3種狀況:
8位數據右對齊:用戶須將DAC通道1數據寫入寄存器DAC_DHR8RD[7:0]位(實際是存入寄存器DHR1[11:4]位),將DAC通道2數據寫入寄存器DAC_DHR8RD[15:8]位(實際是存入寄存器DHR2[11:4]位);
12位數據左對齊:用戶須將DAC通道1數據寫入寄存器DAC_DHR12LD[15:4]位(實際是存入寄存器DHR1[11:0]位),將DAC通道2數據寫入寄存器DAC_DHR12LD[31:20]位(實際是存入寄存器DHR2[11:0]位);
12位數據右對齊:用戶須將DAC通道1數據寫入寄存器DAC_DHR12RD[11:0]位(實際是存入寄存器DHR1[11:0]位),將DAC通道2數據寫入寄存器DAC_DHR12RD[27:16]位(實際是存入寄存器DHR2[11:0]位)。
當DAC的參考電壓位VREF+的時候,數字輸入通過DAC被線性地轉換爲模擬電壓輸出,其範圍爲0到VREF+。
任一DAC通道引腳上的輸出電壓知足下面的關係:
DAC輸出= VREF x (DOR / 4095)。
注意:此時數據格式:應該選擇12位數據右對齊。
DAC配置
void DAC1_Config(void) { DAC_InitTypeDef DAC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* DMA1 clock and GPIOA clock enable (to be used with DAC) */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* DAC Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* DAC channel2 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 Channel2 */ DAC_Cmd(DAC_Channel_1, ENABLE); }
設置輸出電壓
//設置通道1輸出電壓 //vol:0~3300,表明0~3.3V void Dac1_Set_Vol(uint16_t vol) { double temp=vol; temp/=1000; temp=temp*4096/3.3; DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右對齊數據格式設置DAC值 }
測試用例很簡單,就是反覆輸出1.2V和3.0V電壓
while (1) { GPIO_SetBits(GPIOE,GPIO_Pin_4); //熄滅LED燈 Dac1_Set_Vol(1200); LCD_ShowString(0,0,"DAC OUT 1.2V"); Delay(500); //延時500ms GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈 Dac1_Set_Vol(3000); LCD_ShowString(0,0,"DAC OUT 3.0V"); Delay(500); //延時500ms }
下載驗證
硬件和軟件開源地址:
https://github.com/strongercjd/STM32F207VCT6
點擊查看本文所在的專輯,STM32F207教程
關注公衆號,第一時間收到文章更新