我們介紹過了 STM32F1 的模數(shù)轉(zhuǎn)換器 ADC,接下來我們學習下STM32F1 的數(shù)模轉(zhuǎn)換器 DAC。要實現(xiàn)的功能是:通過 K_UP 與K_DOWN 按鍵控制 STM32F1 DAC1 輸出電壓,通過串口將 DAC1 輸出的電壓值打印顯示,D1 指示燈閃爍提示系統(tǒng)運行。學習時可以參考《STM32F10x 中文參考手冊》-12 數(shù)模轉(zhuǎn)換器(DAC)章節(jié),特別是寄存器介紹部分。
STM32F1 DAC簡介
DAC(Digital to analog converter)即數(shù)字模擬轉(zhuǎn)換器,它可以將數(shù)字信號轉(zhuǎn)換為模擬信號。它的功能與 ADC 相反。在常見的數(shù)字信號系統(tǒng)中,大部分傳感器信號被轉(zhuǎn)化成電壓信號,而 ADC 把電壓模擬信號轉(zhuǎn)換成易于計算機存儲、處理的數(shù)字編碼,由計算機處理完成后,再由 DAC 輸出電壓模擬信號,該電壓模擬信號常常用來驅(qū)動某些執(zhí)行器件,使人類易于感知。如音頻信號的采集及還原就是這樣一個過程。
STM32F1 DAC 模塊是 12 位電壓輸出數(shù)模轉(zhuǎn)換器, 它可以配置為 8 位或 12位模式,也可以與 DMA 控制器配合使用。DAC 工作在 12 位模式下,數(shù)據(jù)可以采用左對齊或右對齊。DAC 工作在 8 位模式下,數(shù)據(jù)只有右對齊方式。DAC 有兩個輸出通道,每個通道各有一個轉(zhuǎn)換器。在 DAC 雙通道模式下,每個通道可以單獨進行轉(zhuǎn)換;當兩個通道組合在一起同步執(zhí)行更新操作時, 也可以同時進行轉(zhuǎn)換。
DAC 可通過一個輸入?yún)⒖茧妷阂_ VREF+(與 ADC 共享)來提高轉(zhuǎn)換后的數(shù)據(jù)精度。
STM32F1 DAC 主要特性:
● 2 個 DAC 轉(zhuǎn)換器:每個轉(zhuǎn)換器對應 1 個輸出通道
● 8 位或者 12 位單調(diào)輸出
● 12 位模式下數(shù)據(jù)左對齊或者右對齊
● 同步更新功能
● 噪聲波形生成
● 三角波形生成
● 雙 DAC 通道同時或者分別轉(zhuǎn)換
● 每個通道都有 DMA功能
● 外部觸發(fā)轉(zhuǎn)換
● 輸入?yún)⒖茧妷?VREF+
STM32F1 DAC結(jié)構(gòu)框圖
STM32F1 DAC 擁有這么多功能,是由 DAC 內(nèi)部結(jié)構(gòu)決定。要更好的理解STM32F1 的 DAC,就需要了解它內(nèi)部的結(jié)構(gòu)。如下圖所示:(大家也可以查看《STM32F10x 中文參考手冊》-12 數(shù)模轉(zhuǎn)換器(DAC)-12.3 章節(jié)內(nèi)容)。
我們把 DAC 結(jié)構(gòu)框圖分成5個子模塊,按照順序依次進行簡單介紹。
(1)標號 1:電壓輸入引腳
同ADC 一樣,VDDA 與 VSSA 是 DAC 模塊的供電引腳,而 VREF+是DAC 模塊的參考電壓,開發(fā)板上已經(jīng)將 VREF+連接到 VDDA,所以參考電壓范圍是0-3.3V。
(2)標號 2:DAC 轉(zhuǎn)換
DAC 輸出是受 DORx 寄存器直接控制的,但是我們不能直接往 DORx 寄存器寫入數(shù)據(jù),而是通過 DHRx 間接的傳給 DORx 寄存器,實現(xiàn)對 DAC 輸出的控制。
如果未選擇硬件觸發(fā) ( DAC_CR 寄存器中的 TENx 位復位) , 那么經(jīng)過一個 APB1時鐘周期后,DAC_DHRx 寄存器中存儲的數(shù)據(jù)將自動轉(zhuǎn)移到 DAC_DORx 寄存器。
但是, 如果選擇硬件觸發(fā) (置位 DAC_CR 寄存器中的 TENx 位) 且觸發(fā)條件到來,將在三個 APB1 時鐘周期后進行轉(zhuǎn)移。
當 DAC_DORx 加載了 DAC_DHRx 內(nèi)容時,模擬輸出電壓將在一段時間tSETTLING 后可用,具體時間取決于電源電壓和模擬輸出負載。我們可以從
STM32F103ZET6 的數(shù)據(jù)手冊查到的典型值為 3us,最大是 4us。所以 DAC 的轉(zhuǎn)換速度最快是 250K 左右。
本文我們介紹的是不使用硬件觸發(fā)(TENx=0),其轉(zhuǎn)換時序圖如下圖所示:
DHRx 內(nèi)裝載著我們要輸出的數(shù)據(jù),前面我們提到,STM32F1 的 DAC 支持8/12 位模式,8 位模式的時候數(shù)據(jù)是固定的右對齊的,而 12 位模式數(shù)據(jù)可以設置左對齊/右對齊。對于DAC單通道 x,總共有 3 種情況:
① 8 位右對齊:用戶必須將數(shù)據(jù)加載到 DAC_DHR8Rx [7:0] 位(存儲到DHRx[11:4] 位)。
② 12 位左對齊:用戶必須將數(shù)據(jù)加載到 DAC_DHR12Lx [15:4] 位(存儲到DHRx[11:0] 位)。
③ 12 位右對齊:用戶必須將數(shù)據(jù)加載到 DAC_DHR12Rx [11:0] 位(存儲到DHRx[11:0] 位)。
我們所使用的就是單DAC 通道 1,采用 12 位右對齊方式,所以采用第3種情況。
每個 DAC 通道都具有 DMA 功能。兩個 DMA 通道用于處理 DAC 通道的DMA請求。當 DMAENx 位置 1 時,如果發(fā)生外部觸發(fā)(而不是軟件觸發(fā)),則將產(chǎn)生DAC DMA 請求。DAC_DHRx 寄存器的值隨后轉(zhuǎn)移到 DAC_DORx 寄存器。在雙通道模式下,如果兩個 DMAENx 位均置 1,則將產(chǎn)生兩個 DMA 請求。如果只需要一個 DMA 請求,應僅將相應 DMAENx 位置 1。這樣,應用程序可以在雙通道模式下通過一個 DMA 請求和一個特定 DMA 通道來管理兩個 DAC 通道。
由于DAC DMA 請求沒有緩沖隊列。這樣,如果第二個外部觸發(fā)到達時尚未收到第一個外部觸發(fā)的確認,將不會發(fā)出新的請求,并且 DAC_SR 寄存器中的DAM 通道下溢標志 DMAUDRx將置 1,以報告這一錯誤狀況。DMA 數(shù)據(jù)傳輸隨即禁止,并且不再處理其他 DMA 請求。DAC 通道仍將繼續(xù)轉(zhuǎn)換舊有數(shù)據(jù)。這時軟件應通過寫入“ 1”來將 DMAUDRx 標志清零,將所用 DMA 數(shù)據(jù)流的 DMAEN 位清零,并重新初始化 DMA 和 DAC 通道,以便正確地重新開始 DMA 傳輸。軟件應修改 DAC 觸發(fā) 轉(zhuǎn)換頻率或減輕 DMA 工作負載,以避免再次發(fā)生 DMA 下溢。
最后,可通過使能 DMA 數(shù)據(jù) 傳輸和轉(zhuǎn)換觸發(fā)來繼續(xù)完成 DAC 轉(zhuǎn)換。
對于各 DAC 通道,如果使能 DAC_CR 寄存器中相應的 DMAUDRIEx 位,還將產(chǎn)生中斷。本章我們沒有使用到 DMA,所以將其相應位設置為 0即可。
(3)標號 3:DAC 觸發(fā)選擇
如果 TENx 控制位置 1,可通過外部事件(定時計數(shù)器、外部中斷線)觸發(fā)轉(zhuǎn)換。TSELx[2:0]控制位將決定通過 8 個可能事件中的哪一個來觸發(fā)轉(zhuǎn)換,外部觸發(fā)源如下圖所示:
每當 DAC 接口在所選定時器 TRGO 輸出或所選外部中斷線 9 上檢測到上升沿時,DAC_DHRx 寄存器中存儲的最后一個數(shù)據(jù)即會轉(zhuǎn)移到 DAC_DORx 寄存器中。發(fā)生觸發(fā)后再經(jīng)過三個 APB1 周期,DAC_DORx 寄存器將會得到更新。
如果選擇軟件觸發(fā),一旦 SWTRIG 位置 1, 轉(zhuǎn)換即會開始。DAC_DHRx 寄存器的內(nèi)容只需一個 APB1 時鐘周期即可轉(zhuǎn)移到 DAC_DORx 寄存器,加載完成后,SWTRIG 即由硬件復位。
(4)標號 4:DAC 輸出
DAC_OUTx 就是 DAC 的輸出通道,DAC1_OUT 對應 PA4 引腳,DAC2_OUT對應PA5 引腳。要讓 DAC 通道正常輸出,需將 DAC_CR 寄存器中的相應 ENx 位置 1,這樣就可接通對應 DAC 通道。經(jīng)過一段啟動時間tWAKEUP 后,DAC 通道被真正使能。使能 DAC 通道 x 后,相應 GPIO 引腳( PA4 或 PA5)將自動連接到模擬轉(zhuǎn)換器輸出(DAC_OUTx)。為了避免寄生電流消耗,應首先將 PA4 或 PA5 引腳配置為模擬輸入模式 (AIN)。
當 DAC 的參考電壓為 Vref+的時候, DAC 的輸出電壓是線性的從 0~Vref+,12 位模式下 DAC 輸出電壓與 Vref+以及 DORx 的計算公式如下:
DAC 集成了兩個輸出緩沖器, 可用來降低輸出阻抗并在不增加外部運算放大器的情況下直接驅(qū)動外部負載。通過 DAC_CR 寄存器中的相應 BOFFx 位,可使能或禁止各 DAC 通道輸出緩沖器。STM32F1 的 DAC 輸出緩存做的有些不好,如果使能的話,雖然輸出能力增強了一些,但是輸出沒法到 0,這是個很嚴重的問題。所以通常我們不使用輸出緩存,即設置 BOFFx 位為 1。
DAC 還可以生成噪聲和三角波。生成可變振幅的偽噪聲,可使用 LFSR(線性反饋移位寄存器) 。將 WAVEx[1:0] 置為“ 01” 即可選擇生成噪聲。LFSR 中的預加載值為 0xAAA。在每次發(fā)生觸發(fā)事件后,經(jīng)過三個 APB1 時鐘周期,該寄存器會依照特定的計算算法完成更新。
LFSR 值可以通過 DAC_CR 寄存器中的 MAMPx[3:0] 位來部分或完全屏蔽,在不發(fā)生溢出的情況下, 該值將與 DAC_DHRx 的內(nèi)容相加, 然后存儲到 DAC_DORx寄存器中。如果 LFSR 為 0x0000,將向其注入“ 1”(防鎖定機制)。可以通過復位 WAVEx[1:0] 位來將 LFSR 波形產(chǎn)生功能關閉。要生成噪聲,必須通過將DAC_CR 寄存器中的 TENx 位置 1 來使能 DAC 觸發(fā)。
將 WAVEx[1:0] 置為 “ 10” 即可選擇 DAC 生成三角波。振幅通過 DAC_CR 寄存器中的 MAMPx[3:0] 位進行配置。每次發(fā)生觸發(fā)事件后,經(jīng)過三個 APB1 時鐘周期,內(nèi)部三角波計數(shù)器將會遞增。在不發(fā)生溢出的情況下,該計數(shù)器的值將與DAC_DHRx 寄存器內(nèi)容相加,所得總和將存儲到 DAC_DORx 寄存器中。只要小于MAMPx[3:0] 位定義的最大振幅,三角波計數(shù)器就會一直遞增。一旦達到配置的振幅, 計數(shù)器將遞減至零, 然后再遞增, 以此類推。可以通過復位 WAVEx[1:0] 位來將三角波產(chǎn)生功能關閉。
要生成三角波,必須通過將 DAC_CR 寄存器中的 TENx 位置 1 來使能 DAC觸發(fā)。MAMPx[3:0] 位必須在使能 DAC 之前進行配置,否則將無法更改。本文我們不使用噪聲和三角波功能,所以可以將相應的寄存器位清零。由于篇幅限制,本章并沒有對 DAC 相關寄存器進行介紹,大家可以參考《STM32F10x 中文參考手冊》-12 數(shù)模轉(zhuǎn)換器(DAC)-12.5 章節(jié)內(nèi)容,里面有詳細的講解。如果看不懂的可以暫時放下,因為我們使用的是庫函數(shù)開發(fā)。
STM32F1 DAC配置步驟
接下來我們介紹下如何使用庫函數(shù)對 DAC 進行配置。這個也是在編寫程序中必須要了解的。具體步驟如下:(DAC 相關庫函數(shù)在 stm32f10x_dac.c 和stm32f10x_dac.h 文件中)
(1)使能端口及 DAC時鐘,設置引腳為模擬輸入
DAC 的兩個通道對應的是 PA4、PA5 引腳,這個在芯片數(shù)據(jù)手冊內(nèi)可以查找到,如下圖所示。因此使用 DAC 某個通道輸出的時候需要使能 GPIOA 端口和DAC時鐘(DAC 模塊時鐘是由 APB1 提供),并且還要將對應通道的引腳配置為模擬輸入模式。這里需要特別說明一下,雖然 DAC 引腳設置為輸入,但是如果使能DACx 通道后相應的管腳會自動連接在 DAC 模擬輸出上,在前面介紹框圖時也提到了。
例如要讓 DAC1_OUT輸出,其對應的是 PA4 引腳,所以使能時鐘代碼如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA時鐘 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC時鐘 /*配置 PA4 引腳為模擬輸入模式,代碼如下:*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
(2)初始化 DAC,設置DAC 工作模式
要使用 DAC,必須對其相關參數(shù)進行設置,包括 DAC 通道 1 使能、 DAC 通道 1 輸出緩存關閉、不使用觸發(fā)、不使用波形發(fā)生器等設置,該部分設置通過DAC 初始化函數(shù) DAC_Init完成的:
voidDAC_Init(uint32_tDAC_Channel,DAC_InitTypeDef*DAC_InitStruct);
函數(shù) 中第 一個參 數(shù)是用來 確定哪 個 DAC 通道 ,例 如 DAC 通道 1(DAC_Channel_1);第二個參數(shù)是一個結(jié)構(gòu)體指針變量,結(jié)構(gòu)體類型是
DAC_InitTypeDef,其內(nèi)包含了 DAC 初始化的成員變量。下面我們簡單介紹下它的成員:
typedef struct { uint32_t DAC_Trigger; //DAC 觸發(fā)選擇 uint32_t DAC_WaveGeneration; //DAC 波形發(fā)生 uint32_t DAC_LFSRUnmask_TriangleAmplitude; //屏蔽/幅值選擇器 uint32_t DAC_OutputBuffer; //DAC 輸出緩存 }DAC_InitTypeDef;
DAC_Trigger:設置是否使用觸發(fā)功能。前面介紹框圖時已經(jīng)說了 DAC 具有多個觸發(fā)源,有定時器觸發(fā),外部中斷線 9 觸發(fā),軟件觸發(fā)和不使用觸發(fā)。其配置參數(shù)可在 stm32f10x_dac.h找到,如下:
例如:不使用觸發(fā)功能,所以參數(shù)為 DAC_Trigger_None。
DAC_WaveGeneration:設置是否使用波形發(fā)生。在前面框圖介紹也講過,其配置參數(shù)可在 stm32f10x_dac.h找到,如下:
例如:不使用波形發(fā)生功能,所以參數(shù)為DAC_WaveGeneration_None。
DAC_LFSRUnmask_TriangleAmplitude:設置屏蔽/幅值選擇器。這個變量只在使用波形發(fā)生器的時候才有用,通常我們設置為 0 即可,值為DAC_LFSRUnmask_Bit0。其他配置參數(shù)同樣可在 stm32f10x_dac.h找到。
DAC_OutputBuffer:設置輸出緩存控制位。通常我們不使用輸出緩存功能,所以配置參數(shù)為 DAC_OutputBuffer_Disable。如果使用的話可以配置為使能DAC_OutputBuffer_Enable。
了解結(jié)構(gòu)體成員功能后,就可以進行配置,本章實驗配置代碼如下:
DAC_InitTypeDef DAC_InitStructure; DAC_InitStructure.DAC_Trigger=DAC_Trigger_None;//不使用觸發(fā)功能TEN1=0 DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形發(fā)生 DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值設置 DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1 輸出緩存關閉 BOFF1=1 DAC_Init(DAC_Channel_1,&DAC_InitStructure); //初始化DAC通道1
(3)使能 DAC 的輸出通道
初始化 DAC 后,我們就需要開啟它,使能 DAC 輸出通道的庫函數(shù)為:
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState);
例如:使能 DAC 通道1輸出,那么調(diào)用函數(shù)如下:
DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1
(4)設置 DAC 的輸出值
通過前面 4 個步驟的設置, DAC 就可以開始工作了,如果我們使用 12 位右對齊數(shù)據(jù)格式,我們通過設置 DHR12R1,就可以在 DAC 輸出引腳(PA4)得到不同的電壓值了。設置 DHR12R1 的庫函數(shù)是:
DAC_SetChannel1Data(DAC_Align_12b_R,0);//12位右對齊數(shù)據(jù)格式設置DAC值
第一個參數(shù)是設置數(shù)據(jù)對其方式,可以為 12 位右對齊 DAC_Align_12b_R,12 位左對齊 DAC_Align_12b_L 以及 8 位右對齊 DAC_Align_8b_R 方式。
第二個參數(shù)就是 DAC的輸入值,初始化時我們一般設置輸入值為0。庫函數(shù)中,還提供一個讀取 DAC 對應通道最后一次轉(zhuǎn)換的數(shù)值,函數(shù)是:
uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel);
參數(shù) DAC_Channel 用于選擇讀取的 DAC 通道。可以為 DAC_Channel_1 和DAC_Channel_2。
將以上幾步全部配置好后,我們就可以使用 DAC 對應的通道輸出模擬電壓了。
本實驗使用到硬件資源如下:
(1)D1 指示燈
(2)K_UP 和 K_DOWN按鍵
(3)串口 1
(4)DAC 的通道 1
D1指示燈、K_UP 和 K_DOWN 按鍵、串口 1 電路在前面章節(jié)都介紹過,這里就不多說,至于 DAC 的通道1它屬于 STM32F1 芯片內(nèi)部的資源,對應芯片的PA4引腳。DAC 模塊電路如下圖所示:
如果直接使用 STM32的DAC通道輸出信號給負載,可直接連接 PA4 或者PA5引腳。
我們開發(fā)板上還集成信號放大電路,如下所以:
如果需要輸出較強的信號,可將負載接在 DAC0 上,這個對應開發(fā)板 DAC 模塊的 P23 插針,旁邊有對應的絲印注釋。一定要注意需將 DA_VCC連接5V電源,否則輸出無效。對于 PWM1 可使用 STM32 的定時器來模擬輸出,這個大家可以對應學習。如果參考電壓源有誤差, 那么 DAC 輸出的電壓可能也會存在有一點誤差。
如果需要使用 ADC 來檢測DAC 輸出電壓, 可以使用杜邦線將對應的 DAC輸出通道管腳與 ADC 通道管腳連接。
D1指示燈用來提示系統(tǒng)運行狀態(tài),K_UP 按鍵用來增加 DAC輸入值,K_DOWN按鍵用來減小 DAC 輸入值,輸入值的改變將控制 DAC1_OUT 電壓輸出。通過串口1 將 DAC1_OUT 輸出的電壓值打印出來。
實現(xiàn)的功能是:通過 K_UP 與 K_DOWN 按鍵控制 STM32F1 DAC1 輸出電壓,通過串口將 DAC1輸出的電壓值打印顯示,D1 指示燈閃爍提示系統(tǒng)運行。
程序框架如下:
(1)初始化 DAC 通道1相關參數(shù)
(2)編寫主函數(shù)
前面介紹 DAC 配置步驟時, 就已經(jīng)講解如何初始化 DAC。下面我們打開 “DAC 數(shù)模轉(zhuǎn)換實驗”工程,在 APP 工程組中添加dac.c 文件(里面包含了 DAC 驅(qū)動程序),在 StdPeriph_Driver 工程組中添加stm32f10x_dac.c庫文件。DAC 操作的庫函數(shù)都放在 stm32f10x_dac.c和stm32f10x_dac.h 文件中,所以使用到 DAC 就必須加入 stm32f10x_dac.c文件,同時還要包含對應的頭文件路徑。這里我們分析幾個重要函數(shù),其他部分程序大家可以打開工程查看。
DAC通道 1初始化函數(shù)
要使用 DAC,我們必須先對它進行配置。初始化代碼如下:
/**************************************************************** * 函 數(shù) 名 : DAC1_Init * 函數(shù)功能 : DAC1 初始化函數(shù) * 輸 入 : 無 * 輸 出 : 無 *****************************************************************/ void DAC1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; DAC_InitTypeDef DAC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA時鐘 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);//使能DAC時鐘 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//DAC_1 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模擬量輸入 GPIO_Init(GPIOA,&GPIO_InitStructure); DAC_InitStructure.DAC_Trigger=DAC_Trigger_None;//不使用觸發(fā)功能TEN1=0 DAC_InitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形發(fā)生 DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值設置 DAC_InitStructure.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1 輸出緩存關閉 BOFF1=1 DAC_Init(DAC_Channel_1,&DAC_InitStructure);//初始化DAC通道1 DAC_SetChannel1Data(DAC_Align_12b_R,0);//12位右對齊數(shù)據(jù)格式設置DAC值 DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1 }
在DAC1_Init()函數(shù)中,首先使能 GPIOA 端口和 DAC 時鐘,并配置 PA4為模擬輸入模式。然后初始化 DAC_InitStructure 結(jié)構(gòu)體。最后開啟 DAC_Channel_1。
在初始化函數(shù)中還調(diào)用了 DAC_SetChannel1Data 函數(shù),設置數(shù)據(jù)格式為 12 位右對齊,并且設置 DAC 初始值為 0。這一過程在前面步驟介紹中已經(jīng)提了。如果你會使用DAC 的通道 1,對于DAC的通道 2 是類似的。
主函數(shù)
編寫好 DAC 通道 1 的初始化函數(shù)后, 接下來就可以編寫主函數(shù)了, 代碼如下:
/**************************************************************** * 函 數(shù) 名 : main * 函數(shù)功能 : 主函數(shù) * 輸 入 : 無 * 輸 出 : 無 *****************************************************************/ int main() { u8 i=0; u8 key; int dac_value=0; u16 dacval; float dac_vol; SysTick_Init(72); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中斷優(yōu)先級分組分2組 LED_Init(); USART1_Init(9600); KEY_Init(); DAC1_Init(); while(1) { key=KEY_Scan(0); if(key==KEY_UP) { dac_value+=400; if(dac_value>=4000) { dac_value=4095; } DAC_SetChannel1Data(DAC_Align_12b_R,dac_value); } else if(key==KEY_DOWN) { dac_value-=400; if(dac_value<=0) { dac_value=0; } DAC_SetChannel1Data(DAC_Align_12b_R,dac_value); } i++; if(i%20==0) { led1=!led1; } if(i%50==0) { dacval=DAC_GetDataOutputValue(DAC_Channel_1); dac_vol=(float)dacval*(3.3/4096); printf("輸出DAC 電壓值為:%.2fV ",dac_vol); } delay_ms(10); } }
主函數(shù)實現(xiàn)的功能很簡單,首先調(diào)用之前編寫好的硬件初始化函數(shù),包括SysTick系統(tǒng)時鐘, 中斷分組, LED初始化等。然后調(diào)用我們前面編寫的DAC1_Init函數(shù)。最后進入 while 循環(huán),調(diào)用 KEY_Scan 函數(shù),不斷檢測 K_UP 和 K_DOWN 按鍵是否按下,如果 K_UP 按鍵按下,調(diào)用 DAC_SetChannel1Data 函數(shù)增加 DAC1的輸入值;如果 K_DOWN 按鍵按下,調(diào)用 DAC_SetChannel1Data 函數(shù)減小 DAC1的輸入值。間隔 500ms 調(diào)用 DAC_GetDataOutputValue 函數(shù)讀取 DAC1 最后一次的輸入值, 根據(jù)DAC電壓計算公式即可知道DAC1輸出的電壓大小, 同時通過printf打印出電壓值。D1 指示燈間隔200ms 閃爍,提示系統(tǒng)正常運行。
將工程程序編譯后下載到開發(fā)板內(nèi),可以看到 D1 指示燈不斷閃爍,表示程序正常運行。同時打印 DAC 通道 1(PA4)輸出的電壓值,當按下 K_UP 按鍵輸出電壓增大,當按下 K_DOWN 按鍵輸出電壓減小。如果想在串口調(diào)試助手上看到輸出信息,可以打開“串口調(diào)試助手”,首先勾選下標號 1 DTR 框,然后再取消勾選。這是因為此串口助手啟動時會把系統(tǒng)復位住,通過 DTR 狀態(tài)切換下即可。然后設置好波特率等參數(shù)后,串口助手上即會收到 printf 發(fā)送過來的信息。(串口助手上先勾選下標號1 DTR框,然后再取消勾選)如下圖所示:
實驗說明:可以使用萬用表電壓檔來測量 PA4 引腳的輸出電壓,將測量的電壓值與打印出的電壓值對比下,其實精度還是不錯的。
如果發(fā)現(xiàn) DAC 輸出電壓最高達不到 3.3V,那可能是你的電源并沒有達到標準的 3.3V。我們知道 DAC 輸出電壓的范圍取決于參考電壓 VREF+,參考電壓我們已經(jīng)將它連接在 VDDA 上,即 3.3V,所以如果電源不穩(wěn)定,DAC 輸出的電壓可能也會存在一點誤差。
審核編輯:湯梓紅
-
寄存器
+關注
關注
31文章
5390瀏覽量
121896 -
dac
+關注
關注
43文章
2321瀏覽量
192130 -
STM32
+關注
關注
2276文章
10947瀏覽量
359157 -
數(shù)模轉(zhuǎn)換器
關注
14文章
1027瀏覽量
83549 -
stm32f1
+關注
關注
1文章
57瀏覽量
12291
原文標題:STM32實例-DAC數(shù)模轉(zhuǎn)換實驗
文章出處:【微信號:單片機與嵌入式,微信公眾號:單片機與嵌入式】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦

介紹DAC數(shù)模轉(zhuǎn)換器以及DMA的使用
并行數(shù)模轉(zhuǎn)換實驗
數(shù)模轉(zhuǎn)換DAC0832的應用(含電路和源程序)

DAC0832數(shù)模轉(zhuǎn)換模塊DXP資料.

STM32F4 DAC數(shù)模轉(zhuǎn)換實驗例程

DAC 數(shù)模轉(zhuǎn)換程序

DAC(數(shù)模轉(zhuǎn)換模塊)-STM32F103

STM32學習心得二十七:PWM DAC數(shù)模轉(zhuǎn)換實驗及PWM知識復習

實驗4——STM32的PWM和DAC練習

STM32數(shù)模轉(zhuǎn)換器(DAC)簡析

DAC63204.DAC53204.DAC43204數(shù)模轉(zhuǎn)換器(DAC)數(shù)據(jù)表

評論