CubeIDE Note 06: Lesson 4. ADC Setting And Application for LL Library

Hsueh-Ju Wu 吳學儒
STM32CubeIDE
Published in
15 min readJun 14, 2021

教學

如何使用 CubeIDE 設定 ADC 基本應用

環境

本文使用
OS: Windows x64
STM32CubeIDE Version: 1.6.1
開發板: NUCLEO-F334R8(STM32F334R8)
Low-Layer (LL) Library

教學文章列表

參考資料

UM2570. Description of STM32G4 HAL and low-layer drivers

https://www.st.com/resource/en/user_manual/dm00610707-description-of-stm32g4-hal-and-lowlayer-drivers--stmicroelectronics.pdf

RM0364. STM32F334xx advanced Arm®-based 32-bit MCUs

https://www.st.com/resource/en/reference_manual/dm00093941-stm32f334xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

Datasheet. STM32F334x4 STM32F334x6 STM32F334x8

https://www.st.com/resource/en/user_manual/dm00108524--discovery-kit-for-stm32f3-series-with-stm32f334c8-mcu-stmicroelectronics.pdf

ADC — 成大資工 wiki

http://wiki.csie.ncku.edu.tw/embedded/ADC

【STM32】ADC的基本原理、暫存器(超基礎、詳細版)

https://www.itread01.com/content/1546678455.html

STM32 ADC詳細篇(基於HAL庫)

https://iter01.com/589275.html

Section 1. 基本題

設定HRTIM之Timer Master為ADC觸發源,頻率100kHz
將ADC1_IN1(PA0)腳位設定為一般通道,輸入0~3V電壓,
且利用Live Expression,即時監測A/D暫存器所讀取之數值,
並以PA4腳位測試ADC轉換時間。

提示
使用 Timer Master中斷與 ADC中斷測量 ADC轉換時間

Section 1.1 ADC介紹

STM32F334具有兩顆ADC,最大解析度皆為12bit(10, 8, 6可設定)
ADC1 有11個 External channels,3個Internal channels
ADC2 有14個 External channels,3個Internal channels
分為Fast channels (5.1 Ms/s)與Slow channels(4.8 Ms/s)
每個通道可設定Single-ended 或 differential inputs,
每個ADC可針對單通道轉換或整個通道序列轉換,
可設定連續轉換或單次觸發轉換,
每個ADC都有三個analog watch dog,
支援2V~3.6V電壓,詳情請參閱RM0364手冊

RM0364. p. 215

V_REFINT: 實際電壓不一定是 3.3V,透過測量來校準值 。

RM0364. p. 215

在 DISCO板子上面,V_REF+ = VDDA = VDD = 2.95V (3V)
在 NUCLEO-F334R8 上面量到 3.42V

ADC1 Channels ( RM0364. p. 218 )
ADC2 Channels ( RM0364. p. 218 )

ADC channel 6~9為 ADC1 與 ADC2 共用

ADC都在APB2上面,Clock來自APB2,頻率為

ADC Clock = APB2 Clock / Analog Prescalar

A. Regular channels 與 Injected channels

每個 channel 都能設為 Regular(一般)或 Injected(注入),
Regular 在啟動後會依序進行轉換,
而 Injected 表示會等待外部訊號觸發轉換,
觸發後以 Injected 的轉換為優先處理,可中斷Regular channel。

B. 暫存器介紹

Regular channel 中的轉換順序由三個暫存器控制:SQR1、SQR2、SQR3。 SQR暫存器控制著轉換通道的數目和轉換順序,只要在對應的暫存器位置SQRx中寫入相應的通道號碼,這個通道就是第x個轉換。Injected channel也是同理。

通常取樣時間越長,得到的值越精確

轉換時間 = 採樣時間 + 12.5 clock cycles

C. 轉換時序與中斷介紹

EOC 即 End of Conversion (為 Regular Group 結束轉換時產生之中斷)

當 ScanConvMode Disable 時(也就是 Regular Group 只有一個channel),每次轉換結束都會產生 EOC 中斷。

當 ScanConvMode Enable 時,只有當所設定之 Regular Group 之最後一個 channel 完成轉換時才會產生 EOC。

JEOC 為 Injected Group 結束轉換時產生之中斷。

AWD 為 analog watchdog 所產生之中斷。

D. 外部觸發事件

不同模式只能被特定事件觸發

Regular channels 一般通道觸發事件 ( RM0364 p. 231 )
Regular channels 一般通道觸發事件( RM0364 p. 232 )
Injected channels 注入通道觸發事件 ( RM0364 p. 232 )

E. 轉換模式介紹

可參考成大資工wiki用流程圖講得很清楚

http://wiki.csie.ncku.edu.tw/embedded/ADC

筆者自己做出的結論:

Single conversion mode

單次轉換,觸發一次只轉換一個通道

Continuous conversion mode

連續轉換,轉換完成一個通道後立即自動執行下一個通道的轉換,直到序列全部完成轉換停止

Scan mode

掃描模式,觸發後,自動的連續讀取多個通道,且不斷重新開始新的序列

Discontinuous conversion mode

間斷模式,觸發後,可分組分批進行轉換

F. 兩ADC工作模式

Section 1.2 Live Expression介紹

Live Expression是一個可以即時監控運行變數的功能

開啟程式碼優化的話會無法使用此功能

開啟方式要在Debug Configuration裡面先確保有開啟相關設定

然後在 Debug 時在旁邊就可以看到相關的功能卡
輸入想看的變數,就可以即時監控變數值

若 Live Expression 功能卡不見的話
可以透過Window >> Show View >> Live Expression,把它叫出來

Live Expression(不知道甚麼鬼翻譯變:現場表達式)

Section 1.3 CubeMX設定

Step 1. 請先按照此篇教學(選對開發板)做好基礎設定

Step 2. 把需要的IO設定好

基本題用PA0做ADC輸入,PA4做GPIO輸出
我們從 Pinout view 把它設定好即可

PA0 選 ADC1_IN1
PA4 選 GPIO_OUTPUT

Step 3. ADC觸發源 Timer Master 之設定

基本題使用HRTIM的Timer Master模組作為ADC觸發源
我們切換到HRTIM1設定頁

勾選 Master Timer Enable

跟 Lesson 3 一樣,切回去Clock Configuration
可看到HRTIM1時脈設定已啟用

我們把它的選擇線調到 PLLCLK*2
讓 HRTIM1 時脈為 144 MHz

HRTIM 之 Master Timer 頻率設定 100kHz
可參照Lesson 3. 設定介紹

Period 設為 46080 ( = 4.608GHz / 100kHz)
Preload: Enable
Repetition Update: Enable

切換到ADC Triggers Configuration 分頁
根據Section 1.1.D 觸發事件表格
ADC Regular channel 只能使用 ADC Trigger 1, 3 觸發
所以我們這邊使用ADC Trigger 1 來觸發
觸發源選擇 Timer Master 週期更新事件

ADC Trigger Configuration: Enable
Update Trigger Source: Master Timer
Timer Sources Selection: 1 (ADC Trigger on master period)

Step 4. ADC 設定

基本題我們要使用ADC1_IN1
我們切換到ADC1,把Channel IN1 設定為Single-ended (單端輸入)

因為我們只轉換一個通道,基本上使用Single Conversion Mode即可
大部分設定都不用動,維持預設
只要稍微留意一些參數即可 EOC Selection, Sampling Time
我們這邊只修改 Regular Channel 轉換觸發源

External Trigger Conversion Source: HRTimer Trigger Out 1 event

我們可以看到從時脈圖看到ADC Clock為72MHz

Step 5. NVIC 中斷設定

基本題中使用中斷來測量ADC轉換時間
思路大概是這樣

只要測量 PA4 HIGH 的時間就可以知道實際ADC轉換時間了
也可以先用手冊給的估算公式估算一下轉換時間

轉換時間 = 採樣時間 + 12.5 clock cycles

根據我們剛剛的設定,Sampling Time 是 1.5 cycle
ADC clock = 72 MHz,所以 T_cycle = 1 / 72M = 14 (ns / cycle)

Cycle_conv = 1.5 + 12.5 = 14 (cycle)
T_conv = 14 cycle * 14 ns / cycle = 196 ns

轉換時間大約會在196 ns 左右

好的,我們可以來設定 NVIC 中斷了

勾選
ADC1 and ADC2 interrupts
HRTIM master global interrupts
即可,其餘不用再做設定

Step 6. 改用LL庫

Step 7. 大膽 Generate Code吧

提供 ioc檔與設定報告供大家參考核對設定

- ioc檔https://drive.google.com/file/d/1aIMNGufgrGj8r0qZGsFcsuHQaNkrwy95/view?usp=sharing

- 設定報告( pdf )
https://drive.google.com/file/d/18ofhHn2YeyVbPZ4Tbkyv3vxyQH6AOqUT/view?usp=sharing

Section 1.4 程式碼撰寫

main.c

這裡宣告一個全域變數用來監看值
區域變數無法即時查看
只能透過Break Point在對應區塊暫停程式才能看到

記得啟用HRTIM的Counter
還有啟用對應的中斷函數
啟用ADC模組與啟動ADC轉換
中間要等待ADC自動校正
最後while中提供讀取ADC值的兩種方式給大家參考

stm32f3xx_it.c

中斷函數裡面全部使用暫存器寫法是為了拚效能
同學可試試看不使用暫存器寫法會出現什麼樣的不同

Section 1.5 實驗結果

運行中將 PA0 接到 3.3V,可看到值很接近 4095

測量 PA4 可看到 ADC 觸發頻率為100kHz,符合題目要求

最後是轉換時間測試
筆者測試結果為196ns,與理論計算結果一致
因為筆者做這題測試還做了一些特殊處理
同學們做出來的不會是這個數字,轉換時間肯定更久
甚至根據中斷函數中使用不同的語法會出現250~980ns的轉換時間

這邊留個作業給大家
為甚麼單純用以上方法測量會會比 196ns 還久?
該如何解決這個問題?
提示: 跟筆者標示粗體的部分相關

解決方案

Section 2. 進階題

將ADC1_IN1(PA0)腳位設定為一般通道,輸入0~3V電壓,
使用HRTIM之Timer A模組,輸出PWM,
設定互補模式且Duty cycle = 50%,Deadtime = 1us,
並使用HRTIM之Timer Master作為ADC觸發源,
且開啟Timer Master中斷函數,並在中斷函數中施作以下判斷式:

A. 若輸入電壓為 0~1V, Frequency of Timer A = 80kHz
B. 若輸入電壓為 1~2V, Frequency of Timer A = 100kHz
C. 若輸入電壓為 2~3V, Frequency of Timer A = 120kHz

而ADC觸發頻率(即Timer Master中斷頻率)隨Timer A頻率變化。

提供更改頻率的函數給大家參考

LL_HRTIM_TIM_SetPeriod (HRTIMx, Timerx, Period);

或暫存器寫法:
HRTIM1->sMasterRegs.MPER = Period; //for Timer Master
HRTIM1->sTimerxRegs[x].PERxR = Period; //for others

本題可開啟半波模式,他會自動計算50% Duty所需比較器值
就不用更新比較器了

只需先 Enable Compare Unit 1
再Enable Half Mode 即可,順序不可顛倒

Section 2.1 程式碼撰寫

按照基本題與Lesson 3.內容做本題設定即可
提供 ioc檔與設定報告供大家參考核對設定

- ioc檔https://drive.google.com/file/d/1aIMNGufgrGj8r0qZGsFcsuHQaNkrwy95/view?usp=sharing

- 設定報告( pdf )
https://drive.google.com/file/d/18ofhHn2YeyVbPZ4Tbkyv3vxyQH6AOqUT/view?usp=sharing

main.c

本題要求寫在中斷函數中
所以int main() 的 while迴圈保持空白

stm32f3xx_it.c

Section 2.2 實驗結果

A. 0V < PA0 < 1V,80kHz

B. 1V < PA0 < 2V,100kHz

C. 2V < PA0 < 3V,120kHz

--

--