緣起
我想一開始在做 ADC 轉換這項功能時,要驗證時可能會從 輪詢方式 先著手吧。因為第一印象通常是比較容易達成,確實也是。實作時很快就有結果,拿著官方範例一步一步做好。官方是使用單通道做為基本範例。可是當時我的需求是多通道,經過一番測試仍然測試不出來。迫於時間因素就先改弦易轍,換了 ADC DMA 模式,其實也沒花太多時間研究也就實做出來。雖然,輪詢模式缺點是比較耗 MCU 資源,但是在心中覺得還想試試看放在心中的一個疑問。
基本設定
這次使用 NUCLEO-F401RE 開發版測試,執行 STM32CubeIDE 後直接進入 ADC1 設定項目,選擇其中 3 個 ADC Input 。
IN0 -> PA0
IN1 -> PA1
IN4 -> PA4
Parameter Settings 標籤
Resoltion 維持 12 Bits 解析能力,也就是 0 ~ 4095 範圍。
Scan Conversion Mode 設定 Enabled
Continuous Conversion Mode 設定 Enabled
Number Of Conversion 選擇 3 ,表示有 3 組ADC Iinput
Rank 要各自選擇 Channel
其他設定項目維持 Default 值。
儲存後 ,由 STM32CubeIDE 產生程式碼。
程式碼
打開 main.c 後,首先建立 readVoltage() function
uint16_t readVoltage()
{
HAL_ADC_Start(&hadc1); /* 啟動 ADC 轉換*/
/* 等待轉換完成 , 100 指 timout 時間。 單位 ms*/
if(HAL_ADC_PollForConversion(&hadc1,100) == HAL_OK)
{
/* 確認轉換完成 Flag */
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
{
return (uint16_t)HAL_ADC_GetValue(&hadc1); /*讀取轉換數值 0 ~ 4095 之間*/
}
}
return 0;
}
建立 2 個 Value uint8_t x;
uint16_t ADValue[3];
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
ADValue[x] = readVoltage();
printf("idx[%d] value[%d]\r\n",x,ADValue[x] );
x++;
if(x >=3)
{
x = 0;
printf("\r\n");
}
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
readVoltage() 讀到值後,會將 3 組 ADC Input 值儲存在 ADValue[3] 陣列裡。
好了,這樣就完成了。
簡易的測試方法是將剛剛設定的 ADC 腳位 ,分別接入 3.3V 。看看是否 print 的 值是否是接近 4095 。接地是否為 0
不過,遇到一個不解的地方。以為 Polling 讀 ADC 值的時候,會按照 Channel 0 ,Channel 1 , Channel 4 按照這個順序。結果並不是,所以需要一個一個實際確認對應的 ADC Input 腳位及陣列的對應索引。這個問題不大,實務上本來就是需要各自確認 ADC 轉換有沒有工作正常。
原始碼連結
https://github.com/cold63/STM32_Code/tree/master/ADC_Polling
0 comments:
發佈留言