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

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

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

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

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

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

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

實(shí)驗(yàn)4——STM32的PWM和DAC練習(xí)

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

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

評(píng)論