如何使用ADC驅動庫
1 實現如下兩個函數
a: HAL_ADC_MspInit()使能ADC時鍾,設置時鍾源, 使能ADC Pin,設置為輸入模式,
可選 DMA,中斷
b:HAL_ADC_MspDeInit() 與
HAL_ADC_MspInit()作用相反,用來關閉ADC,
可選 DMA,中斷
2 配置ADC參數,詳細參數描述參考ADC屬性定義。通過HAL_ADC_Init()來加載參數
3 配置ADC通道,包括使用的通道,采樣時間等 HAL_ADC_ConfigChannel()
4 校准ADC(HAL_ADCEx_Calibration_Start(&hadc);有些芯片不支持校准),必須在ADC轉換啟動前或停止后
5 使用下面函數中的一個激活ADC外設:
HAL_ADC_Start() -- 輪詢模式
HAL_ADC_Start_IT(), -- 中斷模式
HAL_ADC_Start_DMA(). -- DMA模式
ADC屬性定義
• uint32_tClockPrescaler--時鍾源,同步PLL,異步HSI ADC_CLOCK_ASYNC,ADC_CLOCK_SYNC_PCLK_DIV2,ADC_CLOCK_SYNC_PCLK_DIV4,ADC_CLOCKPRESCALER_PCLK_DIV2,ADC_CLOCKPRESCALER_PCLK_DIV4 • uint32_tResolution -- ADC分辨率(6,8,10,12)ADC_RESOLUTION12b........ • uint32_tDataAlign --數據對齊方式(左,右)ADC_DATAALIGN_LEFT, ADC_DATAALIGN_RIGHT • uint32_tScanConvMode--配置規則組序列,該參數可以關聯“DiscontinuousConvMode”對主序列細分,如果設置多個通道則序列自動使能;如果只有一個通道,執行單一轉換模式;如果有多個通道,執行序列轉換模式;Rank(隊列)定義為通道號,rank0->channel0,rank1-->channel1.....;掃描方向可以遞增(0-->18)或遞減(18-->0)ADC_SCAN_DIRECTION_FORWARD,ADC_SCAN_DIRECTION_BACKWARD,ADC_SCAN_ENABLE • uint32_tEOCSelection -- EOC(EndOfConversion),用來做輪詢或中斷標記;每個rank轉換結束,或序列轉換結束;EOC_SINGLE_CONV,EOC_SEQ_CONV,EOC_SINGLE_SEQ_CONV(保留供以后用) • uint32_tLowPowerAutoWait • uint32_tLowPowerAutoPowerOff • uint32_tContinuousConvMode --定義當選擇的觸發事件(軟件觸發 or 外部觸發)發生后規則組執行單一轉換還是連續轉換 ENABLE or DISABLE • uint32_tDiscontinuousConvMode---指定當規則組是完整序列/非連續序列(序列分布在)時是否轉換序列;只有在Continuous禁用時,DisContinuous才有效;如果ContinuousConvMode使能,則該參數拋棄 • uint32_tExternalTrigConv --觸發方式 ADC_SOFTWARE_START 外部觸發禁止,使用軟件觸發 • uint32_tExternalTrigConvEdge --外部觸發規則,ADC_EXTERNALTRIGCONVEDGE_NONE,ADC_EXTERNALTRIGCONVEDGE_RISING,ADC_EXTERNALTRIGCONVEDGE_FALLING,ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING • uint32_tDMAContinuousRequests--//DMA轉換請求,指定DMA執行單次(當轉換數達標時停止傳送)or連續請求模式;備注:連續模式: //DMA必須配置為循環模式,否則當DMA buffer存滿時將觸發溢出; ENABLE or DISABLE • uint32_tOverrun--選擇數據溢出時的行為:保存數據或覆蓋數據;這個參數只作用於規則組,包含DMA
說明:
ContinuousConvMode | DiscontinuousConvMode | 通道結束 | 序列結束 | |||
DISABLE | DISABLE | 單次轉換 | EOC | EOS | 單次轉換 | 觸發一次,轉換一個序列(轉換所有被選通道),轉換結束后停止 |
ENABLE | 無效 | 連續轉換 | EOC | EOS | 連續轉換 | 觸發一次,轉換一個序列(轉換所有被選通道),轉換結束后自動重新開始 |
DISABLE | ENABLE | 斷續轉換 | EOC | EOS | 斷續轉換 | 觸發一次,轉換一個通道,在觸發,在轉換。在所選轉換通道循環 |
ADC方法:
1 初始化函數
a 自定義初始化
HAL_ADC_Init() 用戶自行調用 加載ADC屬性
HAL_ADC_MspInit() 由HAL_ADC_Init()調用,對底層初始化,主要包括時鍾,IO,DMA等
b 缺醒初始化
HAL_ADC_DeInit() 用戶自行調用,退出ADC HAL_ADC_MspDeInit() 由 HAL_ADC_DeInit()調用,操作底層,關閉時鍾,IO等
2 IO操作函數(輪詢,中斷,DMA 3中編程模型)
a 激活ADC,啟動轉換規則組
• HAL_ADC_Start() • HAL_ADC_Start_IT() 中斷模式ADC_EOC_SINGLE_CONV通道轉換結束,EOC_SEQ_CONV序列轉換結束 • HAL_ADC_Start_DMA()
b 關閉ADC,停止轉換規則組
• HAL_ADC_Stop() • HAL_ADC_Stop_IT() • HAL_ADC_Stop_DMA()
C 讀取ADC值
• HAL_ADC_GetValue()
d 其他
• HAL_ADC_PollForConversion() 等待轉換結束,不適用一下情況:DMA模式且輪詢每個轉換(ADC_EOC_SINGLE_CONV) • HAL_ADC_PollForEvent() • HAL_ADC_IRQHandler() ADC中斷請求,在<stm32fxx_it.c>中調用 // 回調函數,“weak”屬性,使用時再在應用代碼中實現 • HAL_ADC_ConvCpltCallback() 轉換完成后回調,DMA模式下DMA傳輸完成后調用 • HAL_ADC_ConvHalfCpltCallback() 轉換過程中回調 • HAL_ADC_LevelOutOfWindowCallback() • HAL_ADC_ErrorCallback()
3 外設控制函數--動態配置外設參數
• HAL_ADC_ConfigChannel() 配置規則組通道
• HAL_ADC_AnalogWDGConfig()
4 狀態函數--返回運行狀態獲取錯誤信息
• HAL_ADC_GetState()
• HAL_ADC_GetError()
例子,
ADC工作狀態均為非阻塞
1 輪詢模式
-- 非阻塞
/*##-3- Start the conversion process ######/ if(HAL_ADC_Start(&AdcHandle) != HAL_OK) { Error_Handler(); } /*##-4- Wait for the end of conversion ######/ HAL_ADC_PollForConversion(&AdcHandle, 10); if(HAL_ADC_GetState(&AdcHandle) == HAL_ADC_STATE_EOC_REG) { /*##-5- Get the converted value of channel ##*/ uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle); }
2 中斷模式
/*##-3- Start the conversion process ######/ if(HAL_ADC_StartIT(&AdcHandle) != HAL_OK) { Error_Handler(); } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) { /* Get the converted value of regular channel */ uhADCxConvertedValue = HAL_ADC_GetValue(AdcHandle); }
3 DMA模式
/*##-3- Start the conversion process ######/ if(HAL_ADC_StartDMA(&AdcHandle,&uhADCxConvertedValue,1) != HAL_OK) { Error_Handler(); } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) { /* Turn LED1 on: Transfer process is correct */ BSP_LED_On(LED1); }
使用stm32cubemx設置


收集
更進一步將if(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&uhADCxConvertedValue,1)!= HAL_OK),中的1改成6,然后將轉換后的存儲變量定義為二維數組uhADCxConvertedValue[2][3];再觀察串口輸出的情況如下:v
-
alue[0][0] is 0 value[0][1] is 255 value[0][2] is 255 value[1][0] is 0 value[1][1] is 255 value[1][2] is 255 value[0][0] is 0 value[0][1] is 255 value[0][2] is 255 value[1][0] is 0 value[1][1] is 255 value[1][2] is 255 value[0][0] is 0 value[0][1] is 255 value[0][2] is 255 value[1][0] is 1 value[1][1] is 255 value[1][2] is 255
這樣就是把第一次掃描轉換的三個通道值存在數組的第一行的三個元素中,第二次掃描轉換的值放在第二行的三個元素中。這樣就可以方便后面的數字濾波處理了。