目錄
ADC設備
前言
ADC相關參數說明
訪問ADC設備
配置ADC設備
ADC實例
硬件設計?
軟件設計
ADC設備
前言
ADC(Analog-to-Digital Converter) 指模數轉換器。是指將連續變化的模擬信號轉換為離散的數字信號的器件。
對于ADC的詳細介紹和在STM32中的裸機應用可參考以下博客
ADC電壓采集(基于STM32hal庫)(詳細介紹)_竹煙淮雨的博客-CSDN博客
ADC電壓采集(基于STM32hal庫)(保姆級應用)_竹煙淮雨的博客-CSDN博客
ADC相關參數說明
- 分辨率:
分辨率以二進制(或十進制)數的位數來表示,一般有 8 位、10 位、12 位、16 位等,它說明模數轉換器對輸入信號的分辨能力,位數越多,表示分辨率越高,恢復模擬信號時會更精確。
比如電壓訪問在0-3.3V,如果使用12Bit的分辨率的話,最大表示的數字量為2^11-1=4095(范圍為0-4095),也就是把3.3V分為4096份,實際電壓值=模擬電壓值/4095*3.3V
- 精度:
精度表示 ADC 器件在所有的數值點上對應的模擬值和真實值之間的最大誤差值,也就是輸出數值偏離線性最大的距離。
- 轉換速率:
轉換速率是指 A/D 轉換器完成一次從模擬到數字的 AD 轉換所需時間的倒數。例如,某 A/D 轉換器的轉換速率為 1MHz,則表示完成一次 AD 轉換時間為 1 微秒。
訪問ADC設備
應用程序通過 RT-Thread 提供的 ADC 設備管理接口來訪問 ADC 硬件,相關接口如下所示:
- 查找 ADC 設備
rt_device_t rt_device_find(const char* name);
- 使能 ADC 通道
rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel)
@dev ADC 設備句柄
@channel ADC 通道
- 讀取 ADC 通道采樣值(讀取到的是模擬量轉成數字量后的值)
rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_uint32_t channel);
@dev ADC 設備句柄
@channel ADC 通道
- 關閉 ADC 通道
rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel);
僅僅有這些函數接口,并不能夠實現ADC設備的功能,我們還需要進行相應的配置。
配置ADC設備
打開我們的工程源碼中的board.h,關于芯片的一些外設的配置基本上都在board.h中去配置,關于我們之前的時鐘、串口配置,以及IIC、SPI、PWM等等的配置。
打開board.h找到ADC的相關配置步驟描述
/** if you want to use adc you can use the following instructions.** STEP 1, open adc driver framework support in the RT-Thread Settings file** STEP 2, define macro related to the adc* such as #define BSP_USING_ADC1** STEP 3, copy your adc init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file* such as void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)** STEP 4, modify your stm32xxxx_hal_config.h file to support adc peripherals. define macro related to the peripherals* such as #define HAL_ADC_MODULE_ENABLED**/
- 步驟一:開啟ADC驅動框架的支持
- 步驟二:定義一個ADC設備相關的宏
共有三種選擇
根據我們的STM32開發板公有三個ADC外設,這里選擇使用ADC1
- 步驟三:拷貝ADC初始化函數,通過CubeMX生成stm32xxxx_hal_msp.c后,將相應的初始化函數拷貝到board.c中
- 步驟四:修改hal層配置文件,使其支持ADC外設
ADC實例
我們在這里以ADC的獨立模式單通道采集模式為例,來使用我們RTT的ADC設備。
硬件設計?
我們的霸道開發板板載了一個貼片滑動變阻器,滑動變阻器的滑片端連接到了 STM32 的 PC1 引腳。
貼片滑動變阻器的動觸點通過連接至 STM32 芯片的 ADC 通道引腳。當我們旋轉滑動變阻器調 節旋鈕時,其動觸點電壓也會隨之改變,電壓變化范圍為 0~3.3V,亦是開發板默認的 ADC 電壓 采集范圍。
軟件設計
我們接著前面配置ADC設備的步驟進行。
1.首先尋找ADC1設備句柄
2.接著如果查找到ADC,則打開我們的ADC設備,這里使用專屬的使能函數,注意我們需要對dev進行類型轉換為rt_adc_device_t
3.使能完成之后,我們就可以繼續數據讀取了。這里我們開啟一個線程來讀取ADC1的通道11。
(1)動態創建線程
(2)設置入口函數
(3)開啟線程
4.在線程處理函數中,通過rt_adc_read函數進行ADC通道數據的讀取
5.此外要注意在線程處理中加上延時,這樣可以讓線程主動釋放CPU資源,讓CPU去調度其它線程
6.完善打印結果
7.將我們的CubeMX生成的代碼復制到board.c中
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC1){/* USER CODE BEGIN ADC1_MspInit 0 *//* USER CODE END ADC1_MspInit 0 *//* ADC1 clock enable */__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();/**ADC1 GPIO ConfigurationPC1 ------> ADC1_IN11*/GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/* ADC1 interrupt Init */HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);HAL_NVIC_EnableIRQ(ADC1_2_IRQn);/* USER CODE BEGIN ADC1_MspInit 1 *//* USER CODE END ADC1_MspInit 1 */}
}
?8.編譯下載,注意要加上adc.h頭文件
運行結果,調節電壓旋鈕,模擬量正常輸出,但數字量輸出是%f???
(這個問題琢磨半天尚未解決,rt_kprintf("Analog val:%.3f\n\r\n",(float)val/4096.0*3.3);輸出的結果是%f???,同樣我將%.3f換成%d或%u輸出的結果卻是很大的隨機數,希望有大佬可以幫忙解決!!)