F446RE ADC internal channels test: VREF, VBAT, temp sensor
F446RE ADC internal channels test: VREF, VBAT, temp sensor
Diff: main.cpp
- 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); + +}