|
系统电池供电,3.6V电池,经过一个二极管(3A),大概是3.3V到Vbat . 测量电压为2.98V 左右。+ F- N4 `5 O: j. ?$ ^4 n3 Y* A 继续采用直流电源供电,当输入Vbat 3.0v 时,测量为 2.86V左右。 同时还发现一些怪现象,aADCxConvertedData[0],明显比后续的采集值小很多。 哪里操作有问题?. b& |: [2 r% g/ J åçå¾
- R ~" p/ o; |6 ^( F9 i# H /* Definition of ADCx conversions data table size */ #define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 10) /* Size of array aADCxConvertedData[] */ static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE];% V$ ]0 `1 y) o% n' O2 t /**1 i% m. _, F' L' Y: Q * @brief Conversion complete callback in non-blocking mode.6 D2 G+ a" {5 z, a$ v: o* d * @param hadc ADC handle * @retval None9 k/ ?$ \: Q) A) Y) F6 c */5 \; Q, @* _0 `. ~! P- ^4 U void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ u: w; I& S9 @/ K& ~ if(BinarySem_ADCHandle) osSemaphoreRelease(BinarySem_ADCHandle); + Z0 P- ] R7 x$ r+ F$ ~ /* NOTE : This function should not be modified. When the callback is needed, function HAL_ADC_ConvCpltCallback must be implemented in the user file.0 g4 m5 x3 f3 j9 ` */) F, b6 D. j- ~2 j# K( K& J( T- t; G } /**1 T# g$ l m3 M! G& r& c * @brief 测量电池电压 * @param[IN]& A! m6 R/ R* ^# `4 a# `/ }7 | * @retval None: X/ g) X% q8 k; g$ T$ e2 N1 G */- g4 W' w8 D: D5 Z0 e5 ? uint32_t getBattaryTemperatureMeasure(uint8_t bat_flag) { ADC_ChannelConfTypeDef sConfig = {0};- g7 O; @" X0 ?7 c7 N N+ a% V memset(aADCxConvertedData,0,sizeof(aADCxConvertedData)); /* ### - 1 - Initialize ADC peripheral #################################### */- a. d) q- z. V4 ? hadc1.Instance = ADC1; if (HAL_ADC_DeInit(&hadc1) != HAL_OK) {4 T2 K# s* Q% g( f8 Q( b7 n3 ^ /* ADC de-initialization Error */# U$ Y. o0 ]4 _( I0 q& |$ }3 j) L Error_Handler();7 H, W) Q" p/ C0 b& w4 |+ c' Q: G* j( Q' J9 ] } - R, n' L. E: e0 i$ v- s hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; /* Synchronous clock mode, input ADC clock divided by 2*/4 M# b1 m( @; d8 r% W. @1 Q+ J hadc1.Init.Resolution = ADC_RESOLUTION_12B; /* 12-bit resolution for converted data */ g' D( B4 B) Q8 [ hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Right-alignment for converted data */ hadc1.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */9 C3 E2 z9 a' s& X hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */) E: E" v8 E4 W' G6 X1 E+ O hadc1.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */7 A8 T4 {3 r7 x1 U; p' P hadc1.Init.ContinuousConvMode = ENABLE; /* Continuous mode enabled (automatic conversion restart after each conversion) */ hadc1.Init.NbrOfConversion = 1; /* Parameter discarded because sequencer is disabled */ hadc1.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */ hadc1.Init.NbrOfDiscConversion = 1; /* Parameter discarded because sequencer is disabled */% Z, [7 t {) J# ^" l, k hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */ hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */. M# X7 q4 b* @% { hadc1.Init.DMAContinuousRequests = ENABLE; /* ADC DMA continuous request to match with DMA circular mode */" E: m& b, n' R2 }1 ~. z hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */ hadc1.Init.OversamplingMode = DISABLE; /* No oversampling */( P& ^$ V9 m" i2 K% i( M2 D /* Initialize ADC peripheral according to the passed parameters */ if (HAL_ADC_Init(&hadc1) != HAL_OK) {2 R: Z: N) B: U% v& u {' T Error_Handler();' i C& x5 P! G, S }6 Z0 Z/ N% e( X 9 G3 Q. ^/ c& N % ~/ j) m( h$ h% I% h /* ### - 2 - Start calibration ############################################ */ if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK) { Error_Handler(); } , l$ I* Z( L0 d /* ### - 3 - Channel configuration ######################################## */& w. Q& f$ F9 f7 {3 T: G sConfig.Channel = ADC_CHANNEL_VBAT; /* Sampled channel number */5 K7 A0 } j- G: g2 ^# D sConfig.Rank = ADC_REGULAR_RANK_1; /* Rank of sampled channel number ADCx_CHANNEL */7 | A! r' o+ g. A, G, x0 _2 ]/ P sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; /* Sampling time (number of clock cycles unit) */ sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */ sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */ sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */8 w3 T) M5 U0 `, F; y; G if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {7 ]2 G5 B4 p3 ?# z$ \8 e6 D Error_Handler(); } / \5 _9 q7 s2 @ /* ### - 4 - Start conversion in DMA mode ################################# */ if (HAL_ADC_Start_DMA(&hadc1,0 Y! Y+ S- R& @/ k; q2 z (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE7 r) t7 U/ e+ M( N ) != HAL_OK) {6 L& y7 |% R( s; r) F& x. u$ | Error_Handler();& o3 T! f* E/ v' I- U }9 `6 V2 {1 q- @9 R( l# U( { uint32_t ret = 0 ;- Y. g5 p/ i$ s# X2 ~" A r* u if(osOK == osSemaphoreWait(BinarySem_ADCHandle,10)) { uint32_t adc_val = 0;//aADCxConvertedData[1];5 ]7 U6 e' g: d for (int i = ADC_CONVERTED_DATA_BUFFER_SIZE/2 ; i < ADC_CONVERTED_DATA_BUFFER_SIZE ; i++)$ d, X* P5 \+ L* V" {$ M& y {* l3 B8 w( A* o% P7 Z H adc_val += aADCxConvertedData; }: f$ _+ ~5 J* i, S* b adc_val = adc_val / (ADC_CONVERTED_DATA_BUFFER_SIZE/2); ret = __HAL_ADC_CALC_DATA_TO_VOLTAGE(2500,adc_val,ADC_RESOLUTION_12B);* m1 Y7 \4 P' b$ ] ret *= 3;* ?; g! @' `8 @ }+ I7 Y* k4 O) K1 M 5 W3 t0 d) X( [% r; B8 H return (ret); }+ E6 ?5 m+ C! m |% v 0 S. p2 F" T* ?& h" X ( M; t1 r1 W% a. ~ |
通过两天调试,讲采样周期设置长一些,比较接近了。要大于 ADC_SAMPLETIME_12CYCLES_5 。技术支持一直没响应。 |
微信公众号
手机版