前言:
本系列教程將 對應外設原理,HAL庫與STM32CubeMX結合在一起講解,使您可以更快速的學會各個模塊的使用
所用工具:
1、芯片: STM32F407ZET6/ STM32F103ZET6
2、STM32CubeMx軟件
3、IDE: MDK-Keil軟件
4、STM32F1xx/STM32F4xxHAL庫
知識概括:
通過本篇博客您將學到:
ACD工作原理
STM32CubeMX創建ADC例程
HAL庫定時器ADC函數庫
什麼是ADC
Analog-to-Digital Converter的縮寫。指模/數轉換器或者模擬/數字轉換器。是指將連續變量的模擬信號轉換爲離散的數字信號的器件。
典型的模擬數字轉換器將模擬信號轉換爲表示一定比例電壓值的數字信號。
簡單地說就是將模擬電壓值,轉換成對應的肉眼可讀數值
12位ADC是一種逐次逼近型模擬數字轉換器。它有,3個ADC控制器,多達18個通道,可測量16個外部和2個內部信號源。各通道的A/D轉換可以單次、連續、掃描或間斷模式執行。ADC的結果可以左對齊或右對齊方式存儲在16位數據寄存器中。
12位模擬數字轉換器
就是ADC的數字存儲是12位的 也就是說轉換器通過採集轉換所得到的最大值是4095 “111111111111”=4095 二進制的12位可表示0-4095個數, 對應着所測電壓的實際值,轉換的電壓範圍是0v-3.3v的話,轉換器就會把0v-3.3v平均分成4096份。設轉換器所得到的值爲x,所求電壓值爲y。
同理,可以理解8位精度和10位精度
具體的轉壓範圍下面我們會講
3個ADC控制器
就是說STM32一共有3個ADC ADC1,ADC2,ADC3
18個通道
STM32 的ADC 多達18 個通道,
16個外部通道和2個內部信號源 具體是哪一個IO 口可以從手冊查詢到
STM32F10x系列芯片ADC通道和引腳對應關係 :
16個外部通道:芯片上有16個引腳是可以接到模擬電壓上進行電壓值檢測的
2個內部信號源 : 一個是內部溫度傳感器,一個是內部參考電壓
一共支持23個引腳支持ADC,包括21個外部和2個內部信號源
ADC的轉換模式 (重要,請務必看懂)
1 單次轉換模式:ADC只執行一次轉換;
2 連續轉換模式:轉換結束之後馬上開始新的轉換;
3 掃描模式:ADC掃描被規則通道和注入通道選中的所有通道,在每個組的每個通道上執行單次轉換。在每個轉換結束時,這一組的下一個通道被自動轉換。如果設置了CONT位(開啓了連續 轉換模式),轉換不會在選擇組的最後一個通道上停止,而是再次從選擇組的第一個通道繼續轉換。
4 間斷模式:觸發一次,轉換一個通道,在觸發,在轉換。在所選轉換通道循環,由觸發信號啓動新一輪的轉換,直到轉換完成爲止。
掃描模式簡單的說是一次對所有所選中的通道進行轉換,比如開了ch0,ch1,ch4,ch5。 ch0轉換完以後就會自動轉換通道1,4,5直到轉換完這個過程不能被打斷。如果開啓了連續轉換模式,則會在轉換完ch5之後開始新一輪的轉換。
這就引入了間斷模式,可以說是對掃描模式的一種補充。它可以把0,1,4,5這四個通道進行分組。可以分成0,1一組,4,5一組。也可以每個通道單獨配置爲一組。這樣每一組轉換之前都需要先觸發一次。
ADC單通道:
只進行一次ADC轉換:配置爲“單次轉換模式”,掃描模式關閉。ADC通道轉換一次後,就停止轉換。等待再次使能後纔會重新轉換
進行連續ADC轉換:配置爲“連續轉換模式”,掃描模式關閉。ADC通道轉換一次後,接着進行下一次轉換,不斷連續。
ADC多通道:
只進行一次ADC轉換:配置爲“單次轉換模式”,掃描模式使能。ADC的多個通道,按照配置的順序依次轉換一次後,就停止轉換。等待再次使能後纔會重新轉換
進行連續ADC轉換:配置爲“連續轉換模式”,掃描模式使能。ADC的多個通道,按照配置的順序依次轉換一次後,接着進行下一次轉換,不斷連續。
也就是:多通道必須使能掃描模式
上面轉換模式介紹一部分爲轉自他人
左對齊或右對齊
因爲ADC得到的數據是12位精度的,但是數據存儲在 16 位數據寄存器中,所以ADC的存儲結果可以分爲左對齊或右對齊方式(12位)
ADC的工作框圖
- 圖:stm32f103參考手冊
接下來我們介紹下ADC的工作框圖,讓您有個更直白地瞭解,涉及到寄存器的一些部分不再詳細講解,
1電壓輸入範圍
ADC一般用於採集小電壓,其輸入值不能超過VDDA,即ADC輸入範圍:VREF- ≤ VIN ≤ VREF+。具體的定義見上圖。
一般把VSSA和VREF- 接地, VREF+ 和 VDDA接3V3,那麼ADC的輸入範圍是0~3.3V。
2ADC輸入通道
從ADCx_INT0-ADCx_INT15 對應三個ADC的16個外部通道,進行模擬信號轉換 此外,還有兩個內部通道:溫度檢測或者內部電壓檢測
選擇對應通道之後,便會選擇對應GPIO引腳,相關的引腳定義和描述可在開發板的數據手冊裏找
3注入通道,規則通道
我們看到,在選擇了ADC的相關通道引腳之後,在模擬至數字轉換器中有兩個通道,注入通道,規則通道,
規則通道至多16個,注入通道至多4個
規則通道:
規則通道相當於你正常運行的程序,看它的名字就可以知道,很規矩,就是正常執行程序
注入通道:
注入通道可以打斷規則通道,聽它的名字就知道不安分,如果在規則通道轉換過程中,有注入通道進行轉換,那麼就
要先轉換完注入通道,等注入通道轉換完成後,再回到規則通道的轉換流程
- 圖:正點原子
你可以通過上圖有一個更直觀的認識,可以簡單地把注入通道理解爲中斷形式,可以更好理解
4ADC時鐘
圖中的ADC預分頻器的ADCCLK是ADC模塊的時鐘來源。通常,由時鐘控制器提供的ADCCLK時鐘和PCLK2(APB2時鐘)同步。RCC控制器爲ADC時鐘提供一個專用的可編程預分頻器。 分頻因子由RCC_CFGR的ADCPRE[1:0]配置,可配置2/4/6/8分頻
STM32的ADC最大的轉換速率爲1MHz,也就是說最快轉換時間爲1us,爲了保證ADC轉換結果的準確性,ADC的時鐘最好不超過14M。
T = 採樣時間 + 12.5個週期,其中1週期爲1/ADCCLK
例如,當 ADCCLK=14Mhz 的時候,並設置 1.5 個週期的採樣時間,則得到: Tcovn=1.5+12.5=14 個週期=1us。
5外部觸發轉換
ADC 轉換可以由ADC 控制寄存器2: ADC_CR2 的ADON 這個位來控制,寫1 的時候開始轉換,寫0 的時候停止轉換
當然,除了ADC_CR2寄存器的ADON位控制轉換的開始與停止,還可以支持外部事件觸發轉換(比如定時器捕捉、EXTI線)
包括內部定時器觸發和外部IO觸發。具體的觸發源由ADC_CR2的EXTSEL[2:0]位(規則通道觸發源 )和 JEXTSEL[2:0]位(注入通道觸發源)控制。
同時ADC3的觸發源與ADC1/2的觸發源有所不同,上圖已經給出,
具體查看第五部分框圖即可理解
6中斷
中斷觸發條件有三個,規則通道轉換結束,注入通道轉換結束,或者模擬看門狗狀態位被設置時都能產生中斷,
轉換結束中斷就是正常的ADC完成一次轉換,進入中斷,這個很好理解
模擬看門狗中斷
,當被ADC轉換的模擬電壓值低於低閾值或高於高閾值時,便會產生中斷。閾值的高低值由ADC_LTR和ADC_HTR配置
模擬看門狗,聽他的名字就知道,在ADC的應用中是爲了防止讀取到的電壓值超量程或者低於量程
DMA
同時ADC還支持DMA觸發,規則和注入通道轉換結束後會產生DMA請求,用於將轉換好的數據傳輸到內存。
注意,只有ADC1和ADC3可以產生DMA請求
因爲涉及到DMA傳輸,所以這裏我們不再詳細介紹,之後幾節會更新DMA,一般我們在使用ADC 的時候都會開啓DMA 傳輸。
ADC的主要特徵
STM32F10x ADC特點
- 12位逐次逼近型的模擬數字轉換器。
- 最多帶3個ADC控制器
- 最多支持18個通道,可最多測量16個外部和2個內部信號源。
- 支持單次和連續轉換模式
- 轉換結束,注入轉換結束,和發生模擬看門狗事件時產生中斷。
- 通道0到通道n的自動掃描模式 自動校準
- 採樣間隔可以按通道編程
- 規則通道和注入通道均有外部觸發選項
- 轉換結果支持左對齊或右對齊方式存儲在16位數據寄存器
- ADC轉換時間:最大轉換速率 1us。(最大轉換速度爲1MHz,在ADCCLK=14M,採樣週期爲1.5個ADC時鐘下得到。)
- ADC供電要求:2.4V-3.6V
- ADC輸入範圍:VREF- ≤ VIN ≤ VREF+
STM32F4x ADC特點
注: 上部分來自正點原子
F1與F4區別
F4的ADC支持12位,10位,8位和6位精度,F1只支持12位
F1和F4都具有3個ADC,F1可提供21個輸入通道,F4可以提供24個輸入通道。
F1的ADC最大采樣頻率爲1Msps,2路交替採樣可到2Msps(F1不支持3路交替採樣)。F4的ADC最大采樣頻率爲2.4Msps,3路交替採樣可到7.2Msps。
下面到了CubeMax的創建時間
工程創建
1設置RCC
設置高速外部時鐘HSE 選擇外部時鐘源
設置ADC引腳
因爲只有設置了ADC的引腳,才能夠設置ADC的時鐘分頻
2設置時鐘
我的是 外部晶振爲8MHz
- 1選擇外部時鐘HSE 8MHz
- 2PLL鎖相環倍頻9倍
- 3系統時鐘來源選擇爲PLL
- 4設置APB1分頻器爲 /2
- 5 設置ADC時鐘分頻 ,只能是6/8分頻
如果ADC時鐘頻率大於14MHz則會報錯
32的時鐘樹框圖 如果不懂的話請看《【STM32】系統時鐘RCC詳解(超詳細,超全面)》
ADC配置
這個我們簡單的講解下,如果看懂上方原理講解,看這幾個配置也是很簡單的
ADCs_Common_Settings ADC模式設置
Mode ADC_Mode_Independent
這裏設置爲獨立模式
獨立模式模式下,雙ADC不能同步,每個ADC接口獨立工作。所以如果不需要ADC同步或者只是用了一個ADC的時候,應該設成獨立模式,多個ADC同時使用時會有其他模式,如雙重ADC同步模式,兩個ADC同時採集一個或多個通道,可以提高採樣率
Data Alignment (數據對齊方式): 右對齊/左對齊
這個上方有講解,數據的左右對齊
Scan Conversion Mode( 掃描模式 ) : DISABLE
如果只是用了一個通道的話,DISABLE就可以了(也只能DISABLE),如果使用了多個通道的話,會自動設置爲ENABLE。 就是是否開啓掃描模式
Continuous Conversion Mode(連續轉換模式) ENABLE
設置爲ENABLE,即連續轉換。如果設置爲DISABLE,則是單次轉換。兩者的區別在於連續轉換直到所有的數據轉換完成後才停止轉換,而單次轉換則只轉換一次數據就停止,要再次觸發轉換纔可以進行轉換
Discontinuous Conversion Mode(間斷模式) DISABLE
因爲我們只用到了1個ADC,所以這個直接不使能即可
規則通道設置
Enable Regular Conversions (啓用常規轉換模式) ENABLE
使能 否則無發進行下方配置
Number OF Conversion(轉換通道數) 1
用到幾個通道就設置爲幾
多個通道自動使能掃描模式
Extenal Trigger Conversion Source (外部觸發轉換源)
設定ADC的觸發方式
Regular Conversion launched by software 規則的軟件觸發 調用函數觸發即可
Timer X Capture Compare X event 外部引腳觸發,
Timer X Trigger Out event 定時器通道輸出觸發 需要設置相應的定時器設置
這個具體在上方ADC框圖的5部分有講解
Rank 轉換順序
這個只修改通道採樣時間即可 默認爲1.5個週期
多個通道時會有多個Rank,可以設定每個通道的轉換順序
ADC總轉換時間如下計算:
TCONV = 採樣時間+ 12.5個週期
當ADCCLK=14MHz(最大),採樣時間爲1.5週期(最快)時,TCONV =1.5+12.5=14週期=1μs。
因此,ADC的最小採樣時間1us(ADC時鐘=14MHz,採樣週期爲1.5週期下得到) 這個上方也有講解
注入通道設置
也就是注入通道的設置,和轉換通道沒啥太大區別,這裏不再詳解
WahchDog
Enable Analog WatchDog Mode(使能模擬看門狗中斷)
這個上方有講解,本質也測量值就是超出測量範圍或者低於最低範圍,啓動看門狗
具體的配置看下圖:
ADC轉換結束中斷
ADC的DMA傳輸
GPIO的模式爲模擬模式
同時,如果需要打印到上位機,需要配置下串口,具體請看
STM32】HAL庫 STM32CubeMX教程四—UART串口通信詳解
- 1 設置項目名稱
- 2 設置存儲路徑
- 3 選擇所用IDE
創建工程文件
然後點擊GENERATE CODE 創建工程
配置下載工具
新建的工程所有配置都是默認的 我們需要自行選擇下載方式,勾選上下載後復位運行
例程:
在main.c中加上
/* USER CODE BEGIN 0 */
uint16_t ADC_Value;
/* USER CODE END 0 */
在ADC初始化之後加上AD校準函數
MX_ADC1_Init();
HAL_ADCEx_Calibration_Start(&hadc1); //AD校準
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
while中加上:
HAL_ADC_Start(&hadc1); //啓動ADC轉換
HAL_ADC_PollForConversion(&hadc1, 50); //等待轉換完成,50爲最大等待時間,單位爲ms
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
ADC_Value = HAL_ADC_GetValue(&hadc1); //獲取AD值
printf("ADC1 Reading : %d \r\n",ADC_Value);
printf("PA3 True Voltage value : %.4f \r\n",ADC_Value*3.3f/4096);
printf("Z小旋測試\r\n");
}
HAL_Delay(1000);
就可以完成正常讀取
中斷讀取:
如果使能了ADC轉換結束中斷,並且使能了定時器中斷,可以這樣寫:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定時器中斷回調
{
HAL_ADC_Start_IT(&hadc1); //定時器中斷裏面開啓ADC中斷轉換,1ms開啓一次採集
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //ADC轉換完成回調
{
HAL_ADC_Stop_IT(&hadc1); //關閉ADC
HAL_TIM_Base_Stop_IT(&htim3); //關閉定時器
AD_Value=HAL_ADC_GetValue(&hadc1); //獲取ADC轉換的值
printf("ADC1 Reading : %d \r\n",AD_Value);
printf("%.4f V\r\n",(AD_Value*3.3/4096)); //串口打印電壓信息
HAL_TIM_Base_Start_IT(&htim3); //開啓定時器
}
函數講解:
開啓ADC 3種模式 ( 輪詢模式 中斷模式 DMA模式 )
• HAL_ADC_Start(&hadcx); //輪詢模式開啓ADC
• HAL_ADC_Start_IT(&hadcx); //中斷輪詢模式開啓ADC
• HAL_ADC_Start_DMA(&hadcx); //DMA模式開啓ADC
關閉ADC 3種模式 ( 輪詢模式 中斷模式 DMA模式 )
• HAL_ADC_Stop()
• HAL_ADC_Stop_IT()
• HAL_ADC_Stop_DMA()
ADC校準函數 :
• HAL_ADCEx_Calibration_Start(&hadcx);
F4系列不支持
讀取ADC轉換值
• HAL_ADC_GetValue()
等待轉換結束函數
• HAL_ADC_PollForConversion(&hadc1, 50);
第一個參數爲那個ADC,第二個參數爲最大等待時間
ADC中斷回調函數
• HAL_ADC_ConvCpltCallback()
轉換完成後回調,DMA模式下DMA傳輸完成後調用
規則通道及看門狗配置
• HAL_ADC_ConfigChannel() 配置規則組通道
• HAL_ADC_AnalogWDGConfig()
原理講解部分參考: https://blog.csdn.net/weixin_42653531/article/details/81123770 https://zhuanlan.zhihu.com/p/27866193 正點原子 --ADC