前言
ADC(Analog to Digital Converter)顧名思義是將類比訊號轉換成數位訊號的元件,現今多數 MCU 都會內建 ADC,而這也是相當基本且常用的功能。
在之前的篇章中已經分別介紹 Regular 及 Injected 的單與多通道,之前對於等待 ADC 轉換完成的程式寫法都是單純的 Blocking(阻塞),這次要介紹中斷的寫法,使用中斷對於大量的 ADC 轉換作業會比起 Blocking 更有效率。
正文
首先一樣以 Nucleo-F446RE 做示範。
首先建立一個 PIO 的專案,選擇 Framework 為「libopencm3」,並在 src/
資料夾中新增並開啓 main.c
與 main.h
。
完整程式
分段說明
Include
除了基本的 rcc.h
和 gpio.h
及必要的 adc.h
外,因為我要使用 USART 和 printf()
,所以還會需要 usart.h
、stdio.h
與 errno.h
。
另外就是因為要使用中斷功能,所以 nvic.h
也是必要的。
USART 和 printf()
的詳細用法請看之前的文章。
設定 ADC
要使用 ADC 功能,首先要知道 ADC 的通道在哪些 GPIO 上,並將其設定為類比輸入。
接下來就是要設定 ADC。
adc_disable_scan_mode()
禁能多通道掃描模式,因為本範例只需要讀取一個通道而已。
adc_disable_external_trigger_regular()
禁能外部觸發,我們將使用軟體觸發。
adc_set_single_conversion_mode()
設定成單一轉換模式,不連續轉換。
adc_set_right_aligned()
讓資料的對齊方式為靠右對齊。
adc_set_sample_time_on_all_channels()
設定所有通道的取樣時間,這裡使用 56 個 Cycle。
adc_enable_eoc_interrupt()
啓用 ADC 的轉換完成(EOC)中斷。
nvic_enable_irq()
啓用 NVIC 的 ADC IRQ。
adc_set_regular_sequence()
設定 Regular 的通道序列。這裡只有 Ch0。
ADC ISQ
這是 ADC 的 ISQ。
首先先清除 ADC 的轉換完成位元(EOC)。
使用 adc_read_regular()
讀取 ADC 轉換完成的數值。
都完成後再使用 adc_start_conversion_regular()
開始另一次新的轉換。
主程式
adc_start_conversion_regular()
會觸發 ADC 進行 Regular 組轉換,由於我們要使用中斷,所以不需要用 adc_eoc()
觀察 Injected 組是否轉換完成。一旦 ADC 轉換完成就會到 ADC 的 ISR。
多環境程式(F446RE + F103RB)
由於 STM32F1 的部分函式不同,所以 F103RB 沒辦法直接使用上面的 F446RE 的程式。
由於本例的差異比較大,為了不佔版面這裡就不列出的,完整的程式請看 GitHub repo。
小結
但需要大量進行 ADC 轉換時,如何還是透過 Blocking 的方式讀取 EOC 或 JEOC 位元來等待 ADC 完成轉換的話會非常沒效率,因此本篇簡單介紹了 ADC 的中斷寫法,基本上和以往寫過的中斷一樣,應該不會太難。
參考資料
本文的程式也有放在 GitHub 上。
本文同步發表於 iT 邦幫忙-2022 iThome 鐵人賽。
留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)