如花說得好:呃呃呃、是俗話說得好:有了ADC,怎可少了DAC、、我覺得奇怪、今天我開頭就直奔主題了、我想了想,總結了一句話:孫悟空縱然有七十二變、無論是變成貓也好,變成狗也罷、始終還是會變回他本身、所以我怎么的拐彎抹角,還是會回到DAC、、這不、前面幾句廢話,還是回到了講DAC上來了、、好吧、今天就直接一點吧,換個風格的開頭、
先來張比如花漂亮的照片、大家請盡情欣賞:因為其夠美麗了、所以我就不展現我美麗而銷魂的塗鴉了、
鑒賞過之后、我們來看看STM32之DAC的Resume(簡歷簡介):
● 2個DAC轉換器:每個轉換器對應1個輸出通道
● 8位或者12位單調輸出
● 12位模式下數據左對齊或者右對齊
● 同步更新功能
● 噪聲波形生成
● 三角波形生成
● 雙DAC通道同時或者分別轉換
● 每個通道都有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寄存器。(這段話也就是對上張圖片的描述)
接下來我們看看
1、輸入輸出使能:
通道使能控制:EN1@DAC_CR
一旦通道使能,輸出引腳PA.4就被自動連到模擬轉換器的輸出
使能通道之前,PA.4要配置成模擬模式AIN

該使能信號只使能了模擬部分,數字接口部分由DACEN@RCC_APB1ENR控制WAKEUP
經過t WAKEUP時間后DAC通道准備就緒
DAC通道上的引腳輸出模擬電壓 = VREF+ * (DOR / 4095)
輸出通道上集成可配置的輸出緩沖,以減小自身的輸出阻抗
使能控制:BOFF1@DAC_CR
2、輸出通道上的緩沖:
通道內嵌輸出緩沖以增加驅動能力
外部負載較大時,無需增加外部放大器
可使能或禁止該緩沖
外部有大負載,且緩沖禁止時,輸出電壓可能達不到預期
介紹兩張圖片:大家可以對比對比下,在這就不細講了、


3、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;
根據以上說明,具體的設置請看代碼、、
那好、、現在我們來看看具體的步驟:
1、使能DAC的時鍾和GPIOA的時鍾,並配置GPIOA
2、設置DAC的工作模式等功能
3、使能DAC通道
4、設置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模塊,寫了這篇博客、看着面前的一大堆書:數據結構,算法導論、通信原理、計算機控制等、、總想讓自己在畢業之前多學習,多學些知識、可以看出、這篇博客的幽默是少了很多、、但我覺得不影響這篇博客的質量、、STM32、、嗯、還是那句; 廣大的互聯網的網友們、大家早上中午晚上好、、希望能幫到你、、騷年們、、一起努力吧、、
PS:小甲魚的視頻不錯、幽默風趣、推薦給大家、、希望大家能學多點自己感興趣的知識哈、、后會有期
