STM32 HAL庫學習(三)ADC採樣以及printf的使用

ADC輸出的電壓值經轉換後一般爲一個浮點數,要將其打印到串口則需要對串口輸出函數做一個調整。

首先是printf函數的重定向,將一下代碼加入到usart.c中,完成後便可以用printf函數輸出字符串到串口中,而要輸出浮點數,則還需在“項目/建立設置/C Linker/Miscellaneous/Other options”中添加“-u _printf_float”

#include <stdio.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,HAL_MAX_DELAY);
	return ch;
}
#endif
int _write(int file,char*ptr,int len)
{
	int Dataldx;
	for(Dataldx = 0;Dataldx < len;Dataldx++)
	{
		__io_putchar(*ptr++);
	}
	return len;
}

接下來是配置ADC採樣,ADC採樣可以配置爲單通道、多通道,連續、非連續等採樣模式,傳輸獲取採樣值的方式也有查詢獲取、中斷獲取以及DMA獲取等方式,都有提供相應的HAL庫函數。

STM32F070的ADC時鐘來源主要有兩種方式:

  • 直接來源於HSI 14MHZ,也是可配置的最大時鐘頻率,對應在CubeMX中的Clock Prescaler配置爲Asynchronous clock mode
  • 來源於APB時鐘的2分頻或者4分頻(但最大都不能超過14MHZ)

獲取ADC採樣值的方式

1、查詢方式獲取ADC採樣值

  查詢方式主要用到的函數是HAL_ADC_Start()、HAL_ADC_PollForConversion()以及HAL_ADC_GetValue(),其中,HAL_ADC_Start是軟件開始ADC轉換,PollForConversion則等待ADC轉換完成,當轉換完成後,既可在主函數中調用HAL_ADC_GetValue獲取採樣值,進行相應的轉換和輸出。

uint32_t value = 0;
float vol = 0;
while(1)
{
   /*USER CODE BEGIN WHILE*/
   HAL_ADC_Start(&hadc);
   HAL_ADC_PollForConversion(&hadc,HAL_DELAY_MAX);
   value = HAL_ADC_GetValue(&hadc);
   vol = (float)(value *3.3/4096);
   printf("%.2f",vol);
   HAL_Delay(1000);
   /*USER CODE END WHILE*/
}

2、DMA中斷方式 

當ADC採樣方式配置爲連續採樣時,可以藉助DMA對採樣值進行存儲,當DMA傳輸完成時產生中斷,再在中斷函數中對採樣到的數據進行處理。具體步驟是:在CubeMX中配置DMA Request爲ADC,對應的選擇通道DMA1 Channel1,數據寬度選擇word(因爲ADC採樣值類型爲uint32_t),generate code。在main函數中調用HAL_ADC_Start_DMA(),配置DMA數據存儲的位置以及傳輸的數據個數。假設設置數據個數爲100,則當ADC採樣並轉換100個數據後,DMA這邊接收到100個數據後則會產生DMA中斷。而當DMA中斷產生時,HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)先是判斷是傳輸一半數據中斷標誌還是傳輸完成中斷標誌,再根據綁定的句柄調用相應的回調函數。而當選擇ADC DMA傳輸時,DMA傳輸完成後其回調函數會調用 HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc),因此只需重寫該函數進行數據處理即可。(對於這一點,查看DMA_IRQHandler可以發現其根據句柄調用相應的回調函數。但是目前我還沒找到在哪裏調用了HAL_ADC_ConvCpltCallback........存疑)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
   uint32_t value = 0;
   float vol = 0;
   value = ADC_Data[0];
   vol = (float)(3.3*value);
   vol = (float)vol/4096;
   printf("%.3f",vol);
   printf("\r\n");
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章