類比/數位轉換器 ADC(Analog-to-Digital Converter),是將類比形式的連續訊號轉換成數位形式的離散訊號的裝置,常被用在感測器的偵測結果的轉換上,能將現實世界中的類比量轉換爲機器能夠識別的數位量。有關 STM32 的 ADC 特點如下:
讀取 ADC 的方法有以下幾種:
(1) 輪詢(Polling)
這是 ADC 執行數位/類比轉換比較簡單的方法,輪詢方式是定時進行 A/D 轉換並等待 ADC 完成轉換,CPU 再繼續其他程序。這個方法的缺點是比較耗 CPU 資源。
(2) 中斷(Interrupt)
中斷方法是在進行 ADC 轉換結束時觸發中斷信號,讓 CPU 保留當時的狀態,改去處理中斷服務程式,結束後再回到主程序繼續執行。
(3) DMA 請求(DMA request)
DMA 方法是以高速轉換多個 ADC 通道最有效的方法,可將結果傳輸到內部記憶體,無需 CPU 介入處理,通過 DMA 數據可以快速地移動,節省了 CPU 的資源來做其他操作。
(4) 定時器觸發ADC採樣(Timer triggered ADC sampling)
通過定時器設置時間,按時啟動 ADC 採樣。
先從 STM32 的 ADC 方塊圖來瞭解一下其運作方式,便於之後的程式撰寫:
① ADCx IN0~IN15共 16 個輸入通道
透過這 16 個外部通道可以採集模擬訊號。這 16 個通道對應著不同的 I/O 口,如下圖。其中 ADC1 和 ADC2 都有 16 個外部通道,ADC3 一般有 8 個外部通道,ADC1 多了兩個內部通道:內部溫度傳感器和參考電壓。
② ADC 供電引腳
ADC 供電要求:2.4V 到 3.6V,STM32 開發板的輸入電壓範圍為 0~3.3V,通常直接把 VSSA 和 VREF- 接地,把 VREF+和 VDDA 接 3.3V。
③ ADC 輸入時鐘 ADC_CLK
ADC 輸入時鐘 ADC_CLK 由 APB2 經過分頻產生,最大值是 14MHz。STM32F103 的 SYSCLK 時鐘的其中一條配置路線,可以用 8M 外部晶振,9 倍頻來配置系統時鐘 72 MHz,即 PCLK2(APB2時鐘)為 72M,然而 ADC 最大工作頻率為 14M,所以一般設定分頻因子為 6,這樣 ADC 的輸入時鐘為 72M / 6 = 12M。
④ 通道選擇:規則通道組(Regular Channel)和注入通道組(Injected Channel)
外部的 16 個通道在轉換的時候可分為 2 種通道:
⑤ 資料暫存器
上述兩個通道組轉換完成後的資料就分別存放在以下兩個資料暫存器中:
⑥ 中斷與模擬看門狗事件
當兩種通道(規則和注入)轉換結束後,如果啟用中斷轉換結束標誌位,當轉換一結束就會產生中斷,就可以在中斷函式中讀取規則或注入資料暫存器的值。
這可以用來作為看門狗(Watchdog)監視事件,當被 ADC 轉換的模擬電壓低於低閾值或者高於高閾值時,就會產生中斷,AWD 模擬看門狗狀態位被置 1。閥值則存放在 ADC_HTR 和 ADC_LTR 暫存器的最低 12 個有效位中。
⑦ 觸發源
ADC 支援外部事件觸發轉換,觸發源可以是 TIMx 定時器的 TRGO 訊號輸出,可以用來觸發ADC、DAC、其他定時器等。要開啟 ADC 轉換,可以直接設定 ADC 控制暫存器 ADC_CR2 的 ADON 位元為 1,就能 Enable ADC 轉換。
轉換模式
STM32 的 ADC 各通道的轉換模式有以下幾種:單次轉換模式、連續轉換模式、掃描模式。
校準
ADC 內建一個自我校準模式,校準可大幅減小因內部電容器組的變化而造成的準精度誤差。在校準期間,在每個電容器上都會計算出一個誤差修正碼(數字值),這個修正碼用於消除之後的轉換中電容器產生的誤差。建議在每次上電後就執行一次校準作業。
✈ void ADC_DeInit(ADC_TypeDef *ADCx)
將 ADC 設定為預設值。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ void ADC_Init(DMA_Channel_TypeDef *DMAy_Channelx, DMA_InitTypeDef *DMA_InitStruct)
根據 ADC_InitStruct 中指定的參數初始化外設 ADCx 的暫存器,定義在標準函式庫的 stm32f10x_adc.h 文件中,需先定義並填入一個 DMA_InitTypeDef 類型的結構體。
✈ void ADC_Cmd(ADC_TypeDef *ADCx, FunctionalState NewState)
啟用或停用指定的 ADC 外設。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ void ADC_ResetCalibration(ADC_TypeDef *ADCx)
重設置指定的 ADC 復位校準。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef *ADCx)
取得復位校準的狀態。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 傳回值:最新的 ADC 復位校準狀態,傳回 SET 或 RESET。
✈ void ADC_StartCalibration(ADC_TypeDef *ADCx)
開啟指定的 ADC 校準。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef *ADCx)
取得最新的 ADC 校準狀態。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 傳回值:最新的 ADC 校準狀態,傳回 SET 或 RESET。
✈ void ADC_SoftwareStartConvCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
啟動或停用指定的 ADC 軟體轉換功能。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 引數 NewState 可以是 ENABLE 或 DISABLE。
✈ ADC_GetConversionValue(ADC_TypeDef *ADCx); 回傳最新的 ADCx 轉換結果。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 回傳值:數值轉換的結果。
✈ void ADC_RegularChannelConfig(ADC_TypeDef *ADCx, uint8_t ADC_Channel,uint8_t Rank,uint8_t ADC_SampleTime)
為選定的 ADC 常規通道設定其在序列器中的相應等級及其採樣時間。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 引數 ADC_Channel,ADC 通道,可以設定為 ADC_Channel_0 ~ ADC_Channel_17。
- 引數 Rank 常規組排序器中的排名。可以設定為 1~16。
- 引數 ADC_SampleTime 取樣時間,可以是以下幾個數值:
下一篇:STM32筆記(21):ADC 顯示電壓值在 OLED(下)
- STM32F103 系列最多有 3 個 ADC。
- 採樣精度為 12 位,每個 ADC 最多有 16 個外部通道。
- ADC供電要求:2.4V - 3.6V
- ADC轉換時間:最大轉換速率 1 us。(最大轉換速度爲 1MHz,在ADCCLK = 14M,採樣週期爲 1.5 個 ADC 時鐘下得到)
- 各通道的A/D轉換可以採用單次、連續、掃描或間斷模式執行。
- ADC 轉換的結果可以儲存在 16 位數據暫存器中「靠左對齊」或「靠右對齊」。
- 在擁有 2 個或多個 ADC 模組的晶片中,支援雙 ADC 模式。
- ADC 的輸入時鐘頻率由 PCLK2 分頻產生,不得超過 14MHz。
- 模擬看門狗特性允許應用程式檢測輸入電壓是否超出使用者定義的高/低閥值。
讀取 ADC 的方法有以下幾種:
(1) 輪詢(Polling)
這是 ADC 執行數位/類比轉換比較簡單的方法,輪詢方式是定時進行 A/D 轉換並等待 ADC 完成轉換,CPU 再繼續其他程序。這個方法的缺點是比較耗 CPU 資源。
(2) 中斷(Interrupt)
中斷方法是在進行 ADC 轉換結束時觸發中斷信號,讓 CPU 保留當時的狀態,改去處理中斷服務程式,結束後再回到主程序繼續執行。
(3) DMA 請求(DMA request)
DMA 方法是以高速轉換多個 ADC 通道最有效的方法,可將結果傳輸到內部記憶體,無需 CPU 介入處理,通過 DMA 數據可以快速地移動,節省了 CPU 的資源來做其他操作。
(4) 定時器觸發ADC採樣(Timer triggered ADC sampling)
通過定時器設置時間,按時啟動 ADC 採樣。
先從 STM32 的 ADC 方塊圖來瞭解一下其運作方式,便於之後的程式撰寫:
① ADCx IN0~IN15共 16 個輸入通道
透過這 16 個外部通道可以採集模擬訊號。這 16 個通道對應著不同的 I/O 口,如下圖。其中 ADC1 和 ADC2 都有 16 個外部通道,ADC3 一般有 8 個外部通道,ADC1 多了兩個內部通道:內部溫度傳感器和參考電壓。
通道 | ADC1 | ADC2 | ADC3 |
---|---|---|---|
Channel 0 | PA0 | PA0 | PA0 |
Channel 1 | PA1 | PA1 | PA1 |
Channel 2 | PA2 | PA2 | PA2 |
Channel 3 | PA3 | PA3 | PA3 |
Channel 4 | PA4 | PA4 | PF6 |
Channel 5 | PA5 | PA4 | PF7 |
Channel 6 | PA6 | PA4 | PF8 |
Channel 7 | PA7 | PA4 | PF9 |
Channel 8 | PB0 | PB0 | PF10 |
Channel 9 | PB1 | PB1 | - |
Channel 10 | PC0 | PC0 | PC0 |
Channel 11 | PC1 | PC1 | PC1 |
Channel 12 | PC2 | PC2 | PC2 |
Channel 13 | PC3 | PC3 | PC3 |
Channel 14 | PC4 | PC4 | - |
Channel 15 | PC5 | PC5 | - |
Channel 16 | 溫度傳感器 | - | - |
Channel 17 | 內部參考電壓 | - | - |
② ADC 供電引腳
ADC 供電要求:2.4V 到 3.6V,STM32 開發板的輸入電壓範圍為 0~3.3V,通常直接把 VSSA 和 VREF- 接地,把 VREF+和 VDDA 接 3.3V。
③ ADC 輸入時鐘 ADC_CLK
ADC 輸入時鐘 ADC_CLK 由 APB2 經過分頻產生,最大值是 14MHz。STM32F103 的 SYSCLK 時鐘的其中一條配置路線,可以用 8M 外部晶振,9 倍頻來配置系統時鐘 72 MHz,即 PCLK2(APB2時鐘)為 72M,然而 ADC 最大工作頻率為 14M,所以一般設定分頻因子為 6,這樣 ADC 的輸入時鐘為 72M / 6 = 12M。
④ 通道選擇:規則通道組(Regular Channel)和注入通道組(Injected Channel)
外部的 16 個通道在轉換的時候可分為 2 種通道:
- 規則組通道:由 16 個轉換通道組成。對一組指定的通道,按照指定的順序,逐個轉換這組通道,轉換結束後,再從頭迴圈;這指定的通道組就稱為規則組,規則通道和它們的轉換順序在 ADC_SQRx 暫存器中選擇。
- 注入組通道:由 4 個轉換通道組成。實際應用中,有可能需要臨時中斷規則組的轉換,對某些通道進行轉換,這些需要中斷規則組而進行轉換的通道組,就稱為注入組。
⑤ 資料暫存器
上述兩個通道組轉換完成後的資料就分別存放在以下兩個資料暫存器中:
- 規則資料暫存器:通過 32 位元暫存器 ADC_DR 來存放,規則組通道有 16 路通道,但存放規則資料的暫存器只有 1 個,很容易造成資料被覆蓋。最常用的做法就是開啟 DMA 傳輸,把資料傳輸放到 DMA 記憶體裡,才不會造成資料的覆蓋。
- 注入資料暫存器:注入通道最多有 4 個,配備轉換後的資料暫存器也有 4 個,就不會發生資料覆蓋的問題,每個注入通道轉換的資料都有固定的存放位置。
⑥ 中斷與模擬看門狗事件
當兩種通道(規則和注入)轉換結束後,如果啟用中斷轉換結束標誌位,當轉換一結束就會產生中斷,就可以在中斷函式中讀取規則或注入資料暫存器的值。
這可以用來作為看門狗(Watchdog)監視事件,當被 ADC 轉換的模擬電壓低於低閾值或者高於高閾值時,就會產生中斷,AWD 模擬看門狗狀態位被置 1。閥值則存放在 ADC_HTR 和 ADC_LTR 暫存器的最低 12 個有效位中。
⑦ 觸發源
ADC 支援外部事件觸發轉換,觸發源可以是 TIMx 定時器的 TRGO 訊號輸出,可以用來觸發ADC、DAC、其他定時器等。要開啟 ADC 轉換,可以直接設定 ADC 控制暫存器 ADC_CR2 的 ADON 位元為 1,就能 Enable ADC 轉換。
轉換模式
STM32 的 ADC 各通道的轉換模式有以下幾種:單次轉換模式、連續轉換模式、掃描模式。
-- | 單次轉換模式 | 連續轉換模式 |
---|---|---|
不啟動掃描模式 | ADC 只執行一次轉換,完成後就停止。 | ADC 結束一個轉換後,立即啟動一個新的轉換。 |
啟動掃描模式 | 用來掃描一組模擬通道,完成後就停止。 | 掃描一組模擬通道,完成後就停止, 結束一個轉換後立即啟動一個新的轉換。 |
校準
ADC 內建一個自我校準模式,校準可大幅減小因內部電容器組的變化而造成的準精度誤差。在校準期間,在每個電容器上都會計算出一個誤差修正碼(數字值),這個修正碼用於消除之後的轉換中電容器產生的誤差。建議在每次上電後就執行一次校準作業。
[ADC 常用函式]
以下是要操作 ADC 常用的函式:✈ void ADC_DeInit(ADC_TypeDef *ADCx)
將 ADC 設定為預設值。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ void ADC_Init(DMA_Channel_TypeDef *DMAy_Channelx, DMA_InitTypeDef *DMA_InitStruct)
根據 ADC_InitStruct 中指定的參數初始化外設 ADCx 的暫存器,定義在標準函式庫的 stm32f10x_adc.h 文件中,需先定義並填入一個 DMA_InitTypeDef 類型的結構體。
ADC_InitTypeDef ADC_InitStructure;DMA_InitStructure 這個結構體有以下 6 個引數:
引數名稱 | 說明 |
---|---|
ADC_InitStructure.ADC_Mode = xxx; | 設定 ADC 工作為獨立或雙工模式。xxx 可以是以下幾種模式: ADC_Mode_Independent :獨立工作模式 ADC_Mode_RegInjecSimult :同步規則和同步注入模式 ADC_Mode_RegSimult_AlterTrig :同步規則和交替觸發模式 ADC_Mode_InjecSimult_FastInterl :同步規則和快速交替模式 ADC_Mode_InjecSimult_SlowInterl :同步注入和慢速交替模式 ADC_Mode_InjecSimult :同步注入模式 ADC_Mode_RegSimult :同步規則模式 ADC_Mode_FastInterl :快速交替模式 ADC_Mode_SlowInterl :慢速交替模式 ADC_Mode_AlterTrig :交替觸發模式 |
ADC_InitStructure.ADC_ScanConvMode = xxx; | ADC 轉換工作在掃描多通道或單通道模式,若採集多個通道, 則必須開啟此模式。xxx 可以設定為 ENABLE 或 DISABLE。 |
ADC_InitStructure.ADC_ContinuousConvMode = xxx; | 設定 ADC 是在連續模式還是單次模式下執行轉換。 xxx 可以設定為 ENABLE 或 DISABLE。 |
ADC_InitStructure.ADC_ExternalTrigConv = xxx; | 設定啓動規則轉換的外部事件,是由軟件觸發或外部事件觸發。xxx 可以是: ADC_ExternalTrigConv_T1_CC1 ADC_ExternalTrigConv_None.... 等 |
ADC_InitStructure.ADC_DataAlign = xxx; | ADC 數據靠左或靠右對齊。xxx 可以設定參數有: ADC_DataAlign_Right ADC_DataAlign_Left |
ADC_InitStructure.ADC_NbrOfChannel = n | 順序進行規則轉換的 ADC 通道數,n 可以設定為 1~16。 |
✈ void ADC_Cmd(ADC_TypeDef *ADCx, FunctionalState NewState)
啟用或停用指定的 ADC 外設。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ void ADC_ResetCalibration(ADC_TypeDef *ADCx)
重設置指定的 ADC 復位校準。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef *ADCx)
取得復位校準的狀態。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 傳回值:最新的 ADC 復位校準狀態,傳回 SET 或 RESET。
✈ void ADC_StartCalibration(ADC_TypeDef *ADCx)
開啟指定的 ADC 校準。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
✈ FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef *ADCx)
取得最新的 ADC 校準狀態。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 傳回值:最新的 ADC 校準狀態,傳回 SET 或 RESET。
✈ void ADC_SoftwareStartConvCmd(ADC_TypeDef *ADCx, FunctionalState NewState)
啟動或停用指定的 ADC 軟體轉換功能。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 引數 NewState 可以是 ENABLE 或 DISABLE。
✈ ADC_GetConversionValue(ADC_TypeDef *ADCx); 回傳最新的 ADCx 轉換結果。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 回傳值:數值轉換的結果。
✈ void ADC_RegularChannelConfig(ADC_TypeDef *ADCx, uint8_t ADC_Channel,uint8_t Rank,uint8_t ADC_SampleTime)
為選定的 ADC 常規通道設定其在序列器中的相應等級及其採樣時間。
- 引數 ADCx 選擇 ADC 外設,可以是 1, 2 或 3。
- 引數 ADC_Channel,ADC 通道,可以設定為 ADC_Channel_0 ~ ADC_Channel_17。
- 引數 Rank 常規組排序器中的排名。可以設定為 1~16。
- 引數 ADC_SampleTime 取樣時間,可以是以下幾個數值:
- ADC_SampleTime_1Cycles5: 取樣時間為 1.5 循環。
- ADC_SampleTime_7Cycles5: 取樣時間為 7.5 循環。
- ADC_SampleTime_13Cycles5: 取樣時間為 13.5 循環。
- ADC_SampleTime_28Cycles5: 取樣時間為 28.5 循環。
- ADC_SampleTime_41Cycles5: 取樣時間為 41.5 循環。
- ADC_SampleTime_55Cycles5: 取樣時間為 55.5 循環。
- ADC_SampleTime_71Cycles5: 取樣時間為 71.5 循環。
- ADC_SampleTime_239Cycles5: 取樣時間為 239.5 循環。
下一篇:STM32筆記(21):ADC 顯示電壓值在 OLED(下)
張貼留言