STM32CubeMX教程18 DAC - DMA輸出自定義波形

来源:https://www.cnblogs.com/lc-guo/p/17965475
-Advertisement-
Play Games

1、準備材料 開發板(正點原子stm32f407探索者開發板V2.4) STM32CubeMX軟體(Version 6.10.0) 野火DAP模擬器 keil µVision5 IDE(MDK-Arm) ST-LINK/V2驅動 一臺示波器 邏輯分析儀nanoDLA 2、實驗目標 使用STM32Cu ...


1、準備材料

開發板(正點原子stm32f407探索者開發板V2.4

STM32CubeMX軟體(Version 6.10.0

野火DAP模擬器

keil µVision5 IDE(MDK-Arm

ST-LINK/V2驅動

一臺示波器

邏輯分析儀nanoDLA

2、實驗目標

使用STM32CubeMX軟體配置STM32F407開發板的DAC OUT1實現輸出0-3.3V 周期為12.8ms的正弦波形

3、實驗流程

3.0、前提知識

由於STM32F407的兩個DAC輸出通道只能自動生成三角波和雜訊波,因此如果想要輸出其他的波形可以自己手動定義一個周期內DAC要輸出的值,並選擇定時器的更新事件作為DAC輸出的觸發源按順序輸出

這樣按照波形採樣值的順序,在每一個觸發源到來的時候,手動指定DAC將要輸出的值,理論上就可以輸出任何我們想要輸出的波形,比如正弦波,本實驗將以正弦波為例,講解如何通過DAC的DMA輸出正弦波型

當DAC參考電源引腳VREF+接VDDA(3.3V)時,可設置的DAC輸出寄存器值範圍為0~4095,而DAC的輸出範圍為0-3.3V,要輸出的正弦波sin(x)波形幅值範圍為-1~1,因此可以對該波形做一些平移伸縮,將其幅值範圍縮放到DAC設置範圍0~4095內,變換後的正弦波公式為:y=2047*(sin(x)+1)

在該正弦波形的一個周期0-2pi內平均取128個採樣點,然後按照時間先後順序定義在數組中,每當0.1ms觸發源到來的時候,我們就遞歸的從數組中取出一個值將其設置為DAC的輸出值,直到128個採樣點全部設置完畢,然後再反覆從第一個重新設置,這樣就可以大致實現正弦波型

因為需要頻繁的從記憶體取出數據然後寫入DAC外設,因此這裡比較合適的做法是使用DMA的方式進行,通過上述設置的DAC輸出的正弦波形的周期應該為0.1ms*128=12.8ms,正弦波的幅值範圍應該為0-3.3V

3.1、CubeMX相關配置

3.1.0、工程基本配置

打開STM32CubeMX軟體,單擊ACCESS TO MCU SELECTOR選擇開發板MCU(選擇你使用開發板的主控MCU型號),選中MCU型號後單擊頁面右上角Start Project開始工程,具體如下圖所示

開始工程之後在配置主頁面System Core/RCC中配置HSE/LSE晶振,在System Core/SYS中配置Debug模式,具體如下圖所示

詳細工程建立內容讀者可以閱讀“STM32CubeMX教程1 工程建立

3.1.1、時鐘樹配置

系統時鐘使用8MHz外部高速時鐘HSE,HCLK、PCLK1和PCLK2均設置為STM32F407能達到的最高時鐘頻率,具體如下圖所示

3.1.2、外設參數配置

在Pinout & Configuration頁面左邊功能分類欄目Analog中單擊其中DAC

在Mode中勾選OUT1 Configuration

選擇TIM6的外部觸發事件作為DAC OU1輸出的觸發源,不選擇波形生成模式,因為本實驗要生成自定義波形

具體配置如下圖所示

單擊Configuration中的DMA Settings選項卡對DAC的DMA請求進行設置

單擊ADD按鍵增加DMA請求,這裡可選的只有一個DAC1

選擇想要使用的DMA Stream,並設置優先順序,將DMA請求模式設置為迴圈模式,外設地址不增加,記憶體地址遞增,數據寬度選擇字Word

上述配置如下圖所示

3.1.3、外設中斷配置

在Pinout & Configuration頁面左邊System Core/NVIC中勾選DMA1 Stream5 全局中斷,然後選擇合適的中斷優先順序即可

3.2、生成代碼

3.2.0、配置Project Manager頁面

單擊進入Project Manager頁面,在左邊Project分欄中修改工程名稱、工程目錄和工具鏈,然後在Code Generator中勾選“Gnerate peripheral initialization as a pair of 'c/h' files per peripheral”,最後單擊頁面右上角GENERATE CODE生成工程,具體如下圖所示

詳細Project Manager配置內容讀者可以閱讀“STM32CubeMX教程1 工程建立”實驗3.4.3小節

3.2.1、外設初始化調用流程

在生成的工程代碼主函數中新增了MX_DMA_Init()函數,該函數對DAC使用的DMA1時鐘使能,由於啟用了該DMA的中斷,因此還對中斷優先順序及使能進行了配置,如下圖所示

DAC的初始化調用流程與“STM32CubeMX教程16 DAC - 輸出3.3V內任意電壓”實驗一致,只是因為本實驗配置了DMA,因此在HAL_DAC_MspInit()函數中增加了對使用的DAC1 DMA請求的相關配置代碼,如下圖所示

3.2.2、外設中斷調用流程

DMA全局中斷事件回調函數為一個函數指針,當使用HAL_DAC_Start_DMA()函數啟動DAC傳輸時,會將DMA全局中斷事件回調函數指針指向具體的函數,這裡指向了DAC_DMAConvCpltCh1()函數

在DAC_DMAConvCpltCh1()函數中最終調用了DAC OU1 DMA傳輸完成中斷回調函數HAL_DAC_ConvCpltCallbackCh1(),該函數為虛函數,需要用戶重新實現

啟用DMA的外設中斷調用流程可參考“STM32CubeMX教程12 DMA 直接記憶體讀取”實驗3.2.2、外設中斷調用流程小節,上述具體過程如下圖所述

3.2.3、添加其他必要代碼

採集正弦波y=2047*(sin(x)+1)的一個周期2pi內n個採樣點,並將其定義在一個uint32_t 數組中,筆者這裡定義了128個採樣點

為什麼非要正弦波函數為y=2047*(sin(x)+1)?

因為DAC的輸出範圍為0~4095,而sin(x)的輸出範圍為-1~1,因此需要採集的正弦波採樣點最好縮放到0-4095範圍,這樣輸出的波形更好顯示

源代碼如下所示 (註釋1)

/*正弦波數據,12bit,1個周期128個點, 0-4095之間變化*/
const uint32_t userWave[] = 
{
    2047,   2147,	2248,   2347,	2446,	2544,	2641,	2737,
    2830,   2922,	3012,	3099,	3184,	3266,	3346,	3422,
    3494,   3564,	3629,	3691,	3749,	3803,	3852,	3897,
    3938,   3974,	4006,	4033,	4055,	4072,	4084,	4092,
    4094,   4092,	4084,	4072,	4055,	4033,	4006,	3974,
    3938,   3897,	3852,	3803,	3749,	3691,	3629,	3564,
    3494,   3422,	3346,	3266,	3184,	3099,	3012,	2922,
    2830,   2737,	2641,	2544,	2446,	2347,	2248,	2147,
    2047,   1947,	1846,	1747,	1648,	1550,	1453,	1357,
    1264,   1172,	1082,	995 ,	910 ,	828 ,	748 ,	672 ,
    600 ,   530 ,	465 ,	403 ,	345 ,	291 ,	242 ,	197 ,
    156 ,   120 ,	88  ,	61  ,	39  ,	22  ,	10  ,	2   ,
    0   ,   2   ,	10  ,	22  ,	39  ,	61  ,	88  ,	120 ,
    156 ,   197 ,	242 ,	291 ,	345 ,	403 ,   465,	530 ,
    600 ,   672 ,	748 ,	828 ,	910 ,	995 ,	1082,	1172,
    1264,   1357,	1453,   1550,	1648,	1747,	1846,	1947
};

在dac.c中重新實現DAC OU1 DMA傳輸完成中斷回調函數HAL_DAC_ConvCpltCallbackCh1(),源代碼如下

/*DAC OUT1 DMA傳輸完成中斷回調函數*/
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
    /*翻轉RED_LED引腳狀態*/
    HAL_GPIO_TogglePin(RED_LED_GPIO_Port,RED_LED_Pin);
}

在main.c文件主函數main中以DMA方式啟動DAC輸出,源代碼如下

HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,userWave,128,DAC_ALIGN_12B_R);
HAL_TIM_Base_Start(&htim6);

4、常用函數

/*以DMA啟動DAC輸出*/
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length,uint32_t Alignment)
 
/*停止以DMA啟動的DAC輸出*/
HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
 
/*DAC OUT1 DMA傳輸完成時間中斷回調函數*/
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)

5、燒錄驗證

燒錄程式,單片機上電後,將示波器的探頭掛鉤與DAC OUT1引腳PA4相連接,接地環與開發板上的GND引腳連接,將示波器每格電壓幅值調節為1.00V,將每格子採集時間調節為10ms,然後開啟示波器對DAC OU1輸出的波形採集

因為定時器溢出時間為0.1ms,而DMA傳輸的數據為正弦波一個周期內的128個樣本點,因此生成的正弦波周期為128*0.1ms=12.8ms,這與示波器採集到的正弦波波形周期一致,如下圖所示為示波器採集到的正弦波形

在DAC OUT1 DMA傳輸完成時間中斷回調函數中翻轉了RED_LED(PF9)引腳的狀態,經過上述分析知道,傳輸完成一次所需事件應該為輸出正弦波形的周期,也即12.8ms,因此使用邏輯分析儀器採集PF9引腳的狀態,發現PF9引腳確實12.8ms翻轉一次狀態,邏輯分析儀採集的波形如下圖所示

6、註釋詳解

註釋1:正弦波數組定義來源 DAC輸出正弦波帖子

更多內容請瀏覽 STM32CubeMX+STM32F4系列教程文章彙總貼


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C# 數據類型 C# 中的變數必須是指定的數據類型: int myNum = 5; // 整數(整數) double myDoubleNum = 5.99D; // 浮點數 char myLetter = 'D'; // 字元 bool myBool = true; // 布爾 string myT ...
  • 在發佈完:開源:Taurus.DTC 微服務分散式事務框架,之後想想,好像除了事務外,感覺裡面多了一個任務發佈訂閱的基礎功能,本想既然都有了基礎發佈訂閱功能了,那要不要順帶加上延時發佈功能呢?加上了會不會讓事務組件不純了? 經過一翻深思......於是就有了這個Taurus.DTS 任務組件,而且功... ...
  • 在我們開發Winform界面的時候,有時候會遇到需要對一些欄位進行一些彙總的管理,如果在列表中能夠對錶格列表中的內容進行分組展示,將比較符合我們的預期,本篇隨筆介紹在Winform開發中如何利用DevExpress的GridView實現該功能。 ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他的程式幾天記憶體就要爆一次,不知道咋回事,找不出原因,讓我幫忙看一下,這種問題分析dump是最簡單粗暴了,拿到dump後接下來就是一頓分析。 二:WinDbg 分析 1. 程式為什麼會暴 程式既然會爆,可能是虛擬地址受限,也可能是系統記憶體不足,可以用 ...
  • 實例方法和靜態方法之間有幾個關鍵的區別: 1. 實例方法: 關聯對象: 實例方法是與對象實例相關聯的,必須通過實例來調用。 this 關鍵字: 實例方法中可以使用 this 關鍵字引用當前實例。 訪問實例成員: 實例方法可以直接訪問和修改實例的欄位、屬性和其他成員。 生命周期: 實例方法的生命周期與 ...
  • 一、前言 到這篇文章為止,關於.NET "溫故知新"系列的基礎知識就完結了,從這一系列的系統回顧和再學習,對於.NET core、ASP.NET CORE又有了一個新的認識。 不光是從使用,還包括這些知識點的原理,雖然深入原理談不上,但對於日常使用也夠了,我想的是知其然,知其所以然。 在實際開發過程 ...
  • 旋轉編碼器(rotary encoder)也稱為軸編碼器,是將旋轉的機械位移量轉換為電氣信號,對該信號進行處理後檢測位置速度等信號的感測器。檢測直線機械位移量的感測器稱為線性編碼器[1]。一般裝設在旋轉物體中垂直旋轉軸的一面。 ...
  • Ansible劇本--Playbook Ansible playbook劇本介紹 在ansible中,類似“腳本”的文件被稱作“劇本”,英文稱為playbook,用於配置、部署和管理被控節點 只需要把模塊按照順序編排在playbook劇本中,ansible就會按照劇本一步一步的執行,最終達到我們需要 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...