F446RE ADC internal channels test: VREF, VBAT, temp sensor

Dependencies:   mbed

F446RE ADC internal channels test: VREF, VBAT, temp sensor

Revision:
0:0e42d22824a3
Child:
1:709e8e98f880
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Nov 12 23:21:14 2015 +0000
@@ -0,0 +1,78 @@
+// access F446RE internal ADC channels temp sensor, VBAT, VREF
+//  based on pyboard implementation and analogin_api.c
+// VBAT and temp are both channel 18, vref channel 17
+#include "mbed.h"
+
+#define PRREG(z) printf(#z" 0x%x\n",z) 
+
+#define CORE_TEMP_V25          (4096*.76/3.3)  // (0.76v/3.3v)*(2^ADC resoultion)
+#define CORE_TEMP_AVG_SLOPE    (4096*.0025/3.3)    // (2.5mv/3.3v)*(2^ADC resoultion)
+
+// ? from pyboard version
+#define VBAT_DIV (4)
+
+
+static ADC_HandleTypeDef AdcHandle;
+
+void adc_init() {
+            // Enable ADC clock
+        __ADC1_CLK_ENABLE();
+
+        // Configure ADC
+        AdcHandle.Instance = (ADC_TypeDef *)ADC1;
+        AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV2;
+        AdcHandle.Init.Resolution            = ADC_RESOLUTION12b;
+        AdcHandle.Init.ScanConvMode          = DISABLE;
+        AdcHandle.Init.ContinuousConvMode    = DISABLE;
+        AdcHandle.Init.DiscontinuousConvMode = DISABLE;
+        AdcHandle.Init.NbrOfDiscConversion   = 0;
+        AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
+        AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
+        AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
+        AdcHandle.Init.NbrOfConversion       = 1;
+        AdcHandle.Init.DMAContinuousRequests = DISABLE;
+        AdcHandle.Init.EOCSelection          = DISABLE;
+        HAL_ADC_Init(&AdcHandle);
+}
+
+uint16_t adc_read_channel(uint32_t channel) {
+    ADC_ChannelConfTypeDef sConfig;
+    sConfig.Channel = channel;
+    sConfig.Rank = 1;
+    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+    sConfig.Offset = 0;
+    HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
+
+    HAL_ADC_Start(&AdcHandle); // Start conversion
+
+    // Wait end of conversion and get value
+    if (HAL_ADC_PollForConversion(&AdcHandle, 10) == HAL_OK) {
+        return (HAL_ADC_GetValue(&AdcHandle));
+    } else {
+        return 0;
+    }
+}
+
+int main() {
+    uint16_t val;
+    float tempc, Vbat, Vcc;
+    
+    printf("\nSystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
+    adc_init();
+ 
+    val = adc_read_channel(ADC_CHANNEL_VBAT);
+    Vbat = 3.3*VBAT_DIV*val/4096;
+    printf("%d Vbat %.2f\n",val,Vbat);
+    ADC->CCR=0;     // clear CCR to avoid conflicting use 
+    val = adc_read_channel(ADC_CHANNEL_TEMPSENSOR);
+    tempc = ((val - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25.;
+    printf("%d %.1f C\n",val, tempc);
+    val = adc_read_channel(ADC_CHANNEL_VREFINT);
+    Vcc = 4095*1.21/val;
+    printf("%d Vcc %.2f\n",val,Vcc);
+
+    PRREG(ADC1->CR1);
+    PRREG(ADC1->CR2);
+    PRREG(ADC->CCR);
+
+}