日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

正点原子探索者原理图_正点原子【STM32-F407探索者】第二十六章 DAC 实验

發布時間:2025/4/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 正点原子探索者原理图_正点原子【STM32-F407探索者】第二十六章 DAC 实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1)資料下載:點擊資料即可下載

2)對正點原子Linux感興趣的同學可以加群討論:935446741

3)關注正點原子公眾號,獲取最新資料更新

http://weixin.qq.com/r/hEhUTLbEdesKrfIv9x2W (二維碼自動識別)

上幾章,我們介紹了 STM32F4 的 ADC 使用,本章我們將向大家介紹 STM32F4 的 DAC

功能。在本章中,我們將利用按鍵(或 USMART)控制 STM32F4 內部 DAC1 來輸出電壓,

通過 ADC1 的通道 5 采集 DAC 的輸出電壓,在 LCD 模塊上面顯示 ADC 獲取到的電壓值以

及 DAC 的設定輸出電壓值等信息。本章將分為如下幾個部分:

26.1 STM32F4 DAC 簡介

26.2 硬件設計

26.3 軟件設計

26.4 下載驗證

26.1 STM32F4 DAC 簡介

STM32F4 的 DAC 模塊(數字/模擬轉換模塊)是 12 位數字輸入,電壓輸出型的 DAC。DAC

可以配置為 8 位或 12 位模式,也可以與 DMA 控制器配合使用。DAC 工作在 12 位模式時,

數據可以設置成左對齊或右對齊。DAC 模塊有 2 個輸出通道,每個通道都有單獨的轉換器。

在雙 DAC 模式下,2 個通道可以獨立地進行轉換,也可以同時進行轉換并同步地更新 2 個

通道的輸出。DAC 可以通過引腳輸入參考電壓 Vref+(通 ADC 共用)以獲得更精確的轉換

結果。

STM32F4 的 DAC 模塊主要特點有:

① 2 個 DAC 轉換器:每個轉換器對應 1 個輸出通道

② 8 位或者 12 位單調輸出

③ 12 位模式下數據左對齊或者右對齊

④ 同步更新功能

⑤ 噪聲波形生成

⑥ 三角波形生成

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

⑧ 每個通道都有 DMA 功能

單個 DAC 通道的框圖如圖 26.1.1 所示:

圖 26.1.1 DAC 通道模塊框圖

圖中 VDDA 和 VSSA 為 DAC 模塊模擬部分的供電,而 Vref+則是 DAC 模塊的參考電

壓。DAC_OUTx 就是 DAC 的輸出通道了(對應 PA4 或者 PA5 引腳)。

從圖 26.1.1 可以看出,DAC 輸出是受 DORx 寄存器直接控制的,但是我們不能直接往

DORx 寄存器寫入數據,而是通過 DHRx 間接的傳給 DORx 寄存器,實現對 DAC 輸出的控

制。前面我們提到,STM32F4 的 DAC 支持 8/12 位模式,

8 位模式的時候是固定的右對齊的,

而 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 通道 1,采用 12 位右對齊格式,所以采用第③種情況。

如果沒有選中硬件觸發(寄存器 DAC_CR1 的 TENx 位置’0’

),存入寄存器 DAC_DHRx

的數據會在一個 APB1 時鐘周期后自動傳至寄存器 DAC_DORx。如果選中硬件觸發(寄存器

DAC_CR1 的 TENx 位置’1’),數據傳輸在觸發發生以后 3 個 APB1 時鐘周期后完成。 一

旦數據從 DAC_DHRx 寄存器裝入 DAC_DORx 寄存器,在經過時間

之后,輸出即有效,這段時間的長短依電源電壓和模擬輸出負載的不同會有所變化。我們可以從

STM32F407ZGT6 的數據手冊查到

的典型值為 3us,最大是 6us。所以 DAC 的轉

換速度最快是 333K 左右。

本章我們將不使用硬件觸發(TEN=0),其轉換的時間框圖如圖 26.1.2 所示:

圖 26.1.2 TEN=0 時 DAC 模塊轉換時間框圖

DAC_CR 的低 16 位用于控制通道 1,而高 16 位用于控制通道 2,我們這里僅列出比較

重要的最低 8 位的詳細描述,如圖 26.1.4 所示:

圖 26.1.4 寄存器 DAC_CR 低八位詳細描述

首先,我們來看 DAC 通道 1 使能位(EN1),該位用來控制 DAC 通道 1 使能的,本章我

們就是用的 DAC 通道 1,所以該位設置為 1。

再看關閉 DAC 通道 1 輸出緩存控制位(BOFF1),這里 STM32F4 的 DAC 輸出緩存做

的有些不好,如果使能的話,雖然輸出能力強一點,但是輸出沒法到 0,這是個很嚴重的問

題。所以本章我們不使用輸出緩存。即設置該位為 1。

DAC 通道 1 觸發使能位(TEN1),該位用來控制是否使用觸發,里我們不使用觸發,

所以設置該位為 0。

DAC 通道 1 觸發選擇位(TSEL1[2:0]),這里我們沒用到外部觸發,所以設置這幾個位

為 0 就行了。

DAC 通道 1 噪聲/三角波生成使能位(WAVE1[1:0]),這里我們同樣沒用到波形發生器,

故也設置為 0 即可。

DAC 通道 1 屏蔽/復制選擇器(MAMP[3:0]),這些位僅在使用了波形發生器的時候有

用,本章沒有用到波形發生器,故設置為 0 就可以了。

最后是 DAC 通道 1 DMA 使能位(DMAEN1),本章我們沒有用到 DMA 功能,故還是

設置為 0。

通道 2 的情況和通道 1 一模一樣,這里就不不細說了。在 DAC_CR 設置好之后,DAC

就可以正常工作了,我們僅需要再設置 DAC 的數據保持寄存器的值,就可以在 DAC 輸出

通道得到你想要的電壓了(對應 IO 口設置為模擬輸入)。本章,我們用的是 DAC 通道 1 的

12 位右對齊數據保持寄存器:DAC_DHR12R1,該寄存器各位描述如圖 26.1.5 所示:

圖 26.1.5 寄存器 DAC_DHR12R1 各位描述

該寄存器用來設置 DAC 輸出,通過寫入 12 位數據到該寄存器,就可以在 DAC 輸出通

道 1(PA4)得到我們所要的結果。

通過以上介紹,我們了解了 STM32F4 實現 DAC 輸出的相關設置,本章我們將使用 DAC

模塊的通道 1 來輸出模擬電壓。這里我們用到的庫函數以及相關定義分布在文件

stm32f4xx_dac.c 以及頭文件 stm32f4xx_dac.h 中。實現上面功能的詳細設置步驟如下:

1)開啟 PA 口時鐘,設置 PA4 為模擬輸入。

STM32F407ZGT6 的 DAC 通道 1 是接在 PA4 上的,所以,我們先要使能 GPIOA 的時

鐘,然后設置 PA4 為模擬輸入。

這里需要特別說明一下,雖然 DAC 引腳設置為輸入,但是 STM32F4 內部會連接在 DAC

模擬輸出上,這在我們引腳復用映射章節有講解。程序如下:

__HAL_RCC_DAC_CLK_ENABLE();

//使能 DAC 時鐘

__HAL_RCC_GPIOA_CLK_ENABLE();

//開啟 GPIOA 時鐘

GPIO_Initure.Pin=GPIO_PIN_4; //PA4

GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模擬

GPIO_Initure.Pull=GPIO_NOPULL;

//不帶上下拉

HAL_GPIO_Init(GPIOA,&GPIO_Initure);

對于 DAC 通道與引腳對應關系,這在 STM32F4 的數據手冊引腳表上有列出,如下圖:

圖 26.1.6 DAC 通道引腳對應關系

2)初始化 DAC,設置 DAC 的工作模式。

HAL 庫中提供了一個 DAC 初始化函數 HAL_DAC_Init,該函數聲明如下:

HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac);

該函數并沒有設置任何 DAC 相關寄存器,也就是說沒有對 DAC 進行任何配置,它只

是 HAL 庫提供用來在軟件上初始化 DAC,也就是說,為后面 HAL 庫操作 DAC 做好準備。

它有一個很重要的作用就是在函數內部會調用 DAC 的 MSP 初始化函數 HAL_DAC_MspInit,

該函數聲明如下:

void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac);

一般情況下,步驟 1 中的與 MCU 相關的時鐘使能和 IO 口配置都放在該函數中實現。

HAL 庫提供了一個很重要的 DAC 配置函數 HAL_DAC_ConfigChannel,該函數用來配

置 DAC 通道的觸發類型以及輸出緩沖。該函數聲明如下:

HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac,

DAC_ChannelConfTypeDef* sConfig, uint32_t Channel);

第一個入口參數非常簡單,為 DAC 初始化句柄,和 HAL_DAC_Init 保存一致即可。

第三個入口參數 Channel 用來配置 DAC 通道,比如我們使用 PA4,也就是 DAC 通道 1,

所以配置值為 DAC_CHANNEL_1 即可。

接下來我們看看第二個入口參數 sConfig,該參數是 DAC_ChannelConfTypeDef 結構體

指針類型,結構體 DAC_ChannelConfTypeDef 定義如下:

typedef struct

{

uint32_t DAC_Trigger;

// DAC 觸發類型

uint32_t DAC_OutputBuffer; //輸出緩沖

}DAC_ChannelConfTypeDef;

成員變量DAC_Trigger 用來設置DAC 觸發類型,DAC_OutputBuffer 用來設置輸出緩沖,

這在我們前面都有講解。DAC 初始化配置實例代碼如下:

DAC_HandleTypeDef DAC1_Handler;

DAC_ChannelConfTypeDef DACCH1_Config;

DAC1_Handler.Instance=DAC;

HAL_DAC_Init(&DAC1_Handler); //初始化 DAC

DACCH1_Config.DAC_Trigger=DAC_TRIGGER_NONE; //不使用觸發功能

DACCH1_Config.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE;

HAL_DAC_ConfigChannel(&DAC1_Handler,&DACCH1_Config,DAC_CHANNEL_1);

3)使能 DAC 轉換通道

初始化 DAC 之后,理所當然要使能 DAC 轉換通道,HAL 庫函數是:

HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);

該函數非常簡單,第一個參數是 DAC 句柄,第二個用來設置 DAC 通道。

4)設置 DAC 的輸出值。

通過前面 3 個步驟的設置,DAC 就可以開始工作了,我們使用 12 位右對齊數據格式,,

就可以在 DAC 輸出引腳(PA4)得到不同的電壓值了,HAL 庫函數為:

HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac,

uint32_t Channel, uint32_t Alignment, uint32_t Data);

該函數從入口參數可以看出,它是配置 DAC 的通道輸出值,同時通過第三個入口參數

設置對齊方式。

最后,再提醒一下大家,本例程,我們使用的是 3.3V 的參考電壓, 即 Vref+ 連 接

VDDA。

通過以上幾個步驟的設置,我們就能正常的使用 STM32F4 的 DAC 通道 1 來輸出不同

的模擬電壓了。

26.2 硬件設計

本章用到的硬件資源有:

1) 指示燈 DS0

2) KEY_UP 和 KEY1 按鍵

3) 串口

4) TFTLCD 模塊

5) ADC

6) DAC

本章,我們使用 DAC 通道 1 輸出模擬電壓,然后通過 ADC1 的通道 1 對該輸出電壓進

行讀取,并顯示在 LCD 模塊上面,DAC 的輸出電壓,我們通過按鍵(或 USMART)進行

設置。

我們需要用到 ADC 采集 DAC 的輸出電壓,所以需要在硬件上把他們短接起來。ADC

和 DAC 的連接原理圖如圖 26.2.1 所示:

圖 26.2.1 ADC、DAC 與 STM32F4 連接原理圖

P12 是多功能端口,我們只需要通過跳線帽短接 P14 的 ADC 和 DAC,就可以開始做本

章實驗了。如圖 26.2.2 所示:

圖 26.2.2 硬件連接示意圖

26.3 軟件設計

打開本章實驗工程可以發現,我們相比 ADC 實驗,在庫函數中主要是添加了 dac 支持

的相關文件 stm32f4xx_hal_dac.c 以及包含頭文件 stm32f4xx_hal_dac.h。同時我們在

HARDWARE 分組下面新建了 dac.c 源文件以及包含對應的頭文件 dac.h。這兩個文件用來存

放我們編寫的 ADC 相關函數和定義。打開 dac.c,代碼如下:

DAC_HandleTypeDef DAC1_Handler;//DAC 句柄

//初始化 DAC

void DAC1_Init(void)

{

DAC_ChannelConfTypeDef DACCH1_Config;

DAC1_Handler.Instance=DAC;

HAL_DAC_Init(&DAC1_Handler); //初始化 DAC

DACCH1_Config.DAC_Trigger=DAC_TRIGGER_NONE; //不使用觸發功能

DACCH1_Config.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE;

//DAC1 輸出緩沖關閉

HAL_DAC_ConfigChannel(&DAC1_Handler,&DACCH1_Config,

DAC_CHANNEL_1);//DAC 通道 1 配置

HAL_DAC_Start(&DAC1_Handler,DAC_CHANNEL_1); //開啟 DAC 通道 1

}

//DAC 底層驅動,時鐘配置,引腳 配置

//此函數會被 HAL_DAC_Init()調用

//hdac:DAC 句柄

void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)

{

GPIO_InitTypeDef GPIO_Initure;

__HAL_RCC_DAC_CLK_ENABLE();

//使能 DAC 時鐘

__HAL_RCC_GPIOA_CLK_ENABLE();

//開啟 GPIOA 時鐘

GPIO_Initure.Pin=GPIO_PIN_4;

//PA4

GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模擬

GPIO_Initure.Pull=GPIO_NOPULL;

//不帶上下拉

HAL_GPIO_Init(GPIOA,&GPIO_Initure);

}

//設置通道 1 輸出電壓

//vol:0~3300,代表 0~3.3V

void DAC1_Set_Vol(u16 vol)

{

double temp=vol;

temp/=1000;

temp=temp*4096/3.3;

HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,

temp);//12 位右對齊數據格式設置 DAC 值

}

此部分代碼就 2 個函數,Dac1_Init 函數用于初始化 DAC 通道 1。這里基本上是按我們

上面的步驟來初始化的,我們用序號①~⑤已經標示這些步驟。經過這個初始化之后,我們

就可以正常使用 DAC 通道 1 了。第二個函數 Dac1_Set_Vol,用于設置 DAC 通道 1 的輸出

電壓,實際就是將電壓值轉換為 DAC 輸入值。

其他頭文件代碼就比較簡單,這里我們不做過多講解,接下來我們來看看主函數代碼:

int main(void)

{

u16 adcx;

float temp;

u8 t=0;

u16 dacval=0;

u8 key;

HAL_Init();

//初始化 HAL 庫

Stm32_Clock_Init(336,8,2,7);

//設置時鐘,168Mhz

delay_init(168);

//初始化延時函數

uart_init(115200);

//初始化 USART

usmart_dev.init(84);

//初始化 USMART

LED_Init();

//初始化 LED

KEY_Init();

//初始化 KEY

LCD_Init();

//初始化 LCD

MY_ADC_Init(); //初始化 ADC1

DAC1_Init();

//初始化 DAC1

POINT_COLOR=RED;

LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");

LCD_ShowString(30,70,200,16,16,"DAC TEST");

LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(30,110,200,16,16,"2017/4/13");

LCD_ShowString(30,130,200,16,16,"WK_UP:+ KEY1:-");

POINT_COLOR=BLUE;//設置字體為藍色

LCD_ShowString(30,150,200,16,16,"DAC VAL:");

LCD_ShowString(30,170,200,16,16,"DAC VOL:0.000V");

LCD_ShowString(30,190,200,16,16,"ADC VOL:0.000V");

DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值為 0

while(1)

{

t++;

key=KEY_Scan(0);

if(key==WKUP_PRES)

{

if(dacval<4000)dacval+=200;

DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//設置 DAC 值

}else if(key==2)

{

if(dacval>200)dacval-=200;

else dacval=0;

DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//設置 DAC 值

}

if(t==10||key==KEY1_PRES||key==WKUP_PRES)

//WKUP/KEY1 按下了,或者定時時間到了

{

adcx=DAC_GetDataOutputValue(DAC_Channel_1);]

//讀取前面設置 DAC 的值

LCD_ShowxNum(94,150,adcx,4,16,0); //顯示 DAC 寄存器值

temp=(float)adcx*(3.3/4096);

//得到 DAC 電壓值

adcx=temp;

LCD_ShowxNum(94,170,temp,1,16,0);//顯示電壓值整數部分

temp-=adcx;

temp*=1000;

LCD_ShowxNum(110,170,temp,3,16,0X80); //顯示電壓值的小數部分

adcx=Get_Adc_Average(ADC_Channel_5,10); //得到 ADC 轉換值

temp=(float)adcx*(3.3/4096);

//得到 ADC 電壓值

adcx=temp;

LCD_ShowxNum(94,190,temp,1,16,0);

//顯示電壓值整數部分

temp-=adcx;

temp*=1000;

LCD_ShowxNum(110,190,temp,3,16,0X80); //顯示電壓值的小數部分

LED0=!LED0;

t=0;

}

delay_ms(10);

}

}

此部分代碼,我們先對需要用到的模塊進行初始化,然后顯示一些提示信息,本章我們

通過 KEY_UP(WKUP 按鍵)和 KEY1(也就是上下鍵)來實現對 DAC 輸出的幅值控制。

按下 KEY_UP 增加,按 KEY1 減小。同時在 LCD 上面顯示 DHR12R1 寄存器的值、DAC

設計輸出電壓以及 ADC 采集到的 DAC 輸出電壓。

26.4 下載驗證

在代碼編譯成功之后,我們通過下載代碼到 ALIENTEK 探索者 STM32F4 開發板上,

可以看到 LCD 顯示如圖 26.4.1 所示:

圖 26.4.1 DAC 實驗測試圖

同時伴隨 DS0 的不停閃爍,提示程序在運行。此時,我們通過按 KEY_UP 按鍵,可以

看到輸出電壓增大,按 KEY1 則變小。

總結

以上是生活随笔為你收集整理的正点原子探索者原理图_正点原子【STM32-F407探索者】第二十六章 DAC 实验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。