STM32CubeMX教程16 DAC - 输出3.3V内任意电压
1、準(zhǔn)備材料
開(kāi)發(fā)板(正點(diǎn)原子stm32f407探索者開(kāi)發(fā)板V2.4)
STM32CubeMX軟件(Version 6.10.0)
keil μVision5 IDE(MDK-Arm)
ST-LINK/V2驅(qū)動(dòng)
野火DAP仿真器
XCOM V2.6串口助手
2、實(shí)驗(yàn)?zāi)繕?biāo)
使用STM32CubeMX軟件配置STM32F407開(kāi)發(fā)板的DAC OUT1實(shí)現(xiàn)輸出0-3.3V任意模擬電壓,然后用ADC1_IN5單通道采集DAC輸出的電壓,并利用USART1輸出信息用于驗(yàn)證
3、實(shí)驗(yàn)流程
3.0、前提知識(shí)
STM32F407有一個(gè)DAC,該DAC擁有兩個(gè)輸出通道OUT1/2,每個(gè)通道均可以輸出0~VREF+范圍內(nèi)電壓、噪聲波或三角波型
DAC集成了兩個(gè)輸出緩沖器,可用來(lái)降低輸出阻抗并在不增加外部運(yùn)算放大器的情況下直接驅(qū)動(dòng)外部負(fù)載,該參數(shù)可以在STM32CubeMX中DAC參數(shù)配置頁(yè)面配置,一般選擇Enable
DAC輸出的觸發(fā)源一共有8個(gè)觸發(fā)源,可以通過(guò)設(shè)置DAC控制寄存器DAC_CR的TSEL[2:0]位來(lái)決定觸發(fā)源,其中外部引腳觸發(fā)源在STM32CubeMX中需要勾選Mode中的External Trigger才可以選擇,具體如下表所示 (注釋1)
DAC的數(shù)字轉(zhuǎn)模擬主要是利用片上的12位電壓輸出數(shù)模轉(zhuǎn)換器來(lái)實(shí)現(xiàn)的,而這個(gè)12位電壓輸出數(shù)模轉(zhuǎn)換器的輸入數(shù)據(jù)為數(shù)據(jù)輸出寄存器DORx中的內(nèi)容,但是用戶(hù)不能直接將數(shù)據(jù)寫(xiě)入數(shù)據(jù)輸出寄存器DORx中,而是需要將數(shù)據(jù)輸入數(shù)據(jù)保持寄存器DHRx中,然后等待觸發(fā)源到來(lái)/一個(gè)時(shí)鐘周期后,數(shù)據(jù)將自動(dòng)從DHRx中轉(zhuǎn)移到DORx中
由于DHRx寄存器位32位寄存器,而我們寫(xiě)入的數(shù)據(jù)為8/12位的,因此存在數(shù)據(jù)對(duì)齊的問(wèn)題,采用不同的對(duì)齊方式需要將數(shù)據(jù)寫(xiě)入對(duì)應(yīng)對(duì)齊方式的數(shù)據(jù)保存寄存器中,如下圖所示為DAC單/雙通道模式下的數(shù)據(jù)對(duì)齊模式,每種模式對(duì)應(yīng)1/2個(gè)寄存器(注釋1)
舉個(gè)例子:
本實(shí)驗(yàn)采取DAC1單通道模式12位右對(duì)齊,因此筆者需要將數(shù)據(jù)寫(xiě)入 DAC_DHR12R1 寄存器中,而該寄存器的偏址從手冊(cè)上可以看到為0x80
我們寫(xiě)入DAC寄存器數(shù)據(jù)時(shí)使用的函數(shù)為HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,DacValue),其中DAC_ALIGN_12B_R值為0,因此最后將DacValue值寫(xiě)入了地址為DAC基址+0x00000008UL偏址的 DAC_DHR12R1 寄存器,上述描述如下圖所示
DAC輸出引腳輸出的電壓值由DACoutput = VREF+ * DOR / 4095公式計(jì)算,通常 VREF+直接與VDDA短接,因此DAC通道輸出的電壓范圍為0-3.3V,如下圖所示為DAC通道框圖 (注釋1)
3.1、CubeMX相關(guān)配置
3.1.0、工程基本配置
打開(kāi)STM32CubeMX軟件,單擊ACCESS TO MCU SELECTOR選擇開(kāi)發(fā)板MCU(選擇你使用開(kāi)發(fā)板的主控MCU型號(hào)),選中MCU型號(hào)后單擊頁(yè)面右上角Start Project開(kāi)始工程,具體如下圖所示
開(kāi)始工程之后在配置主頁(yè)面System Core/RCC中配置HSE/LSE晶振,在System Core/SYS中配置Debug模式,具體如下圖所示
詳細(xì)工程建立內(nèi)容讀者可以閱讀“STM32CubeMX教程1 工程建立”
3.1.1、時(shí)鐘樹(shù)配置
系統(tǒng)時(shí)鐘使用8MHz外部高速時(shí)鐘HSE,HCLK、PCLK1和PCLK2均設(shè)置為STM32F407能達(dá)到的最高時(shí)鐘頻率,具體如下圖所示
3.1.2、外設(shè)參數(shù)配置
本實(shí)驗(yàn)需要需要初始化開(kāi)發(fā)板上KEY2和KEY0用戶(hù)按鍵,具體配置步驟請(qǐng)閱讀“STM32CubeMX教程3 GPIO輸入 - 按鍵響應(yīng)”
本實(shí)驗(yàn)需要需要初始化USART1作為輸出信息渠道,具體配置步驟請(qǐng)閱讀“STM32CubeMX教程9 USART/UART 異步通信”
本實(shí)驗(yàn)需要配置TIM3 100ms更新事件作為ADC1_IN5通道采集觸發(fā)源的ADC采集,因此需要初始化TIM3和ADC1_IN5,具體配置步驟請(qǐng)閱讀“STM32CubeMX教程13 ADC - 單通道轉(zhuǎn)換”,如下圖所示為配置簡(jiǎn)圖
接下來(lái)配置DAC OUT1,在Pinout & Configuration頁(yè)面左邊功能分類(lèi)欄目Analog中單擊其中DAC,在Mode中勾選OUT1 Configuration
在DAC Out1 Settings中使能 Output Buffer , Trigger 選擇默認(rèn)None,這里不需要觸發(fā)源,也就是說(shuō)當(dāng)DAC啟動(dòng)后DAC就會(huì)一直輸出下去而不是在每次一觸發(fā)源來(lái)到的時(shí)候才輸出,具體配置如下圖所示
3.1.3、外設(shè)中斷配置
DAC只有兩個(gè)關(guān)于DMA的下溢事件的中斷源,本實(shí)驗(yàn)尚不設(shè)計(jì)DMA,因此這里無(wú)需開(kāi)啟DAC的任何中斷
但是DAC的輸出電壓需要由ADC1_IN5來(lái)采集,因此這里勾選ADC的全局中斷,并設(shè)置合適的中斷優(yōu)先級(jí),具體配置如下圖所示
3.2、生成代碼
3.2.0、配置Project Manager頁(yè)面
單擊進(jìn)入Project Manager頁(yè)面,在左邊Project分欄中修改工程名稱(chēng)、工程目錄和工具鏈,然后在Code Generator中勾選“Gnerate peripheral initialization as a pair of 'c/h' files per peripheral”,最后單擊頁(yè)面右上角GENERATE CODE生成工程,具體如下圖所示
詳細(xì)Project Manager配置內(nèi)容讀者可以閱讀“STM32CubeMX教程1 工程建立”實(shí)驗(yàn)3.4.3小節(jié)
3.2.1、外設(shè)初始化調(diào)用流程
在生成的工程代碼主函數(shù)中增加了MX_DAC_Init()函數(shù),該函數(shù)對(duì)啟用的DAC觸發(fā)方式、輸出緩存進(jìn)行了配置
然后調(diào)用HAL_DAC_Init()函數(shù)對(duì)DAC進(jìn)行了初始化,并調(diào)用了HAL_DAC_MspInit()函數(shù)
在HAL_DAC_MspInit()函數(shù)中對(duì)DAC OUT1的輸出引腳PA4做了引腳復(fù)用配置,并且使能了DAC的時(shí)鐘,如果配置了中斷,在該函數(shù)中還會(huì)出現(xiàn)中斷優(yōu)先級(jí)及中斷使能相關(guān)代碼
上述DAC初始化調(diào)用流程如下圖所示
3.2.2、外設(shè)中斷調(diào)用流程
本實(shí)驗(yàn)只開(kāi)啟了ADC的全局中斷,ADC全局中斷調(diào)用流程請(qǐng)閱讀“STM32CubeMX教程13 ADC - 單通道轉(zhuǎn)換”4.2.2小節(jié)
3.2.3、添加其他必要代碼
在adc.c中重新實(shí)現(xiàn)ADC采集完畢中斷回調(diào)函數(shù)HAL_ADC_ConvCpltCallback(),與”STM32CubeMX教程13 ADC - 單通道轉(zhuǎn)換”實(shí)驗(yàn)內(nèi)容一致,目的就是獲取ADC1_IN5通道采集值并通過(guò)USART1輸出,具體代碼如下所示
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance == ADC1)
{
uint32_t val=HAL_ADC_GetValue(&hadc1);
uint32_t Volt=(3300*val)>>12;
printf("val:%d, Volt:%d\r\n",val,Volt);
}
}
在主函數(shù)中啟動(dòng)DAC輸出,并設(shè)置默認(rèn)的DAC輸出值,然后啟動(dòng)定時(shí)器和ADC采集,并在主循環(huán)中實(shí)現(xiàn)按下按鍵KEY2將DAC輸出值增加500,按下按鍵KEY0將DAC輸出值減少500,具體代碼如下圖所示
源代碼如下所示
/*主循環(huán)外代碼*/
printf("Reset\r\n");
HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
uint32_t DacValue=1000;
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,DacValue);
HAL_ADC_Start_IT(&hadc1);
HAL_TIM_Base_Start(&htim3);
/*主循環(huán)中代碼*/
/*按鍵KEY2被按下*/
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(50);
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == GPIO_PIN_RESET)
{
printf("---now DacValue is: %d---\r\n", DacValue);
DacValue += 500;
if(DacValue>4095) DacValue=4095;
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,DacValue);
while(!HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin));
}
}
/*按鍵KEY0被按下*/
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(50);
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == GPIO_PIN_RESET)
{
printf("---now DacValue is: %d---\r\n", DacValue);
DacValue -= 500;
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,DacValue);
while(!HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin));
}
}
值得提醒的是本實(shí)驗(yàn)使用DAC1_IN5(PA5)采集DAC OUT1(PA4)輸出值,需要使用跳線帽/杜邦線將PA5和PA4兩個(gè)引腳短接
4、常用函數(shù)
/*DAC軟件啟動(dòng)輸出函數(shù)*/
HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)
/*DAC軟件停止輸出函數(shù)*/
HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel)
/*DAC輸出值設(shè)置*/
HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
5、燒錄驗(yàn)證
燒錄程序,開(kāi)發(fā)板上電后打開(kāi)串口助手,可以看到間隔100ms輸出一次采集到的DAC OU1輸出值,默認(rèn)輸出值為1000,按下KEY2按鍵后輸出值增加500,按下KEY0按鍵后輸出值減少500,可以從串口輸出信息看到采集到的值和我們預(yù)想的效果一致,如下圖所示為整個(gè)過(guò)程串口輸出信息
6、注釋詳解
注釋1:圖片來(lái)源STM32F4xx 中文參考手冊(cè)
更多內(nèi)容請(qǐng)瀏覽 STM32CubeMX+STM32F4系列教程文章匯總貼
總結(jié)
以上是生活随笔為你收集整理的STM32CubeMX教程16 DAC - 输出3.3V内任意电压的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JAVA程序系统测试感受
- 下一篇: 传奇老人褚时健走了,留下无尽的智慧