#include "bsp_adc.h" // https://www.cnblogs.com/gscw/p/17682385.html // 计算公式参考手册,建议使用 “建议实际可用测量电压范围” 作为 ADC 采集的增益选择判断标准。计算公式参考手册。 // 仅使用 ADC 功能,同时降低功耗,可以将引脚的数字输入功能关闭,配置 R16_PIN_ANALOG_IE。 注:如果引脚用于模拟功能(ADC/TouchKey),建议将该引脚的数字输入功能关闭,即设置数字输入禁用,从而可以降低功耗,并有利于减少干扰。 // PA9 引脚进行 ADC 采集,在置为浮空后,过 300ms 左右再进行 ADC 的采集。因为初次烧录的时候 boot 是串口功能开启的,PA9 是输出高电平。切换到浮空会需要等待时间。 uint16_t adcBuff[40]; volatile uint8_t adclen; volatile uint8_t DMA_end = 0; signed short RoughCalib_Value = 0; // ADC粗调偏差值 uint32_t countadc = 0; uint16_t min_number = 0; uint16_t max_number = 0; double voltage = 0; void BSP_ADC_Init(void) { uint8_t i; /* 温度采样并输出 */ PRINT("\n1.Temperature sampling...\n"); ADC_InterTSSampInit(); for (i = 0; i < 20; i++) { adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次 } for (i = 0; i < 20; i++) { uint32_t C25 = 0; C25 = (*((PUINT32)ROM_CFG_TMP_25C)); PRINT("%d %d %d \n", adc_to_temperature_celsius(adcBuff[i]), adcBuff[i], C25); } // VBAT uint32_t CountBat = 0; ADC_InterBATSampInit(); for (i = 0; i < 20; i++) { adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次 } for (i = 0; i < 20; i++) { CountBat += adcBuff[i]; if (i == 0) { min_number = adcBuff[i]; max_number = adcBuff[i]; } min_number = ((min_number > adcBuff[i]) ? adcBuff[i] : min_number); // 软件滤波 max_number = ((max_number < adcBuff[i]) ? adcBuff[i] : max_number); } printf("min_number = %d, max_number = %d\n", min_number, max_number); CountBat = (CountBat - min_number - max_number) / 18; // 删除最小与最大值 printf("AverageCountBat = %d\n", CountBat); /* 单通道采样:选择adc通道3做采样,对应 PA13引脚, 带数据校准功能 */ GPIOA_ModeCfg(GPIO_Pin_13, GPIO_ModeIN_Floating); // 6dB(2倍) (ADC/4096+0.5)*Vref 1.5*Vref 0.525V~1.575V 0.6V~1.5V ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_2); RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中 PRINT("RoughCalib_Value =%d \n", RoughCalib_Value); printf("PA13:::::\n"); ADC_ChannelCfg(3); for (i = 0; i < 20; i++) { adcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value; // 连续采样20次 } printf("original: "); for (i = 0; i < 20; i++) { PRINT("%d ", adcBuff[i]); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象 } printf("\n"); for (i = 0; i < 20; i++) { countadc += adcBuff[i]; if (i == 0) { min_number = adcBuff[i]; max_number = adcBuff[i]; } min_number = ((min_number > adcBuff[i]) ? adcBuff[i] : min_number); // 软件滤波 max_number = ((max_number < adcBuff[i]) ? adcBuff[i] : max_number); } printf("min=%d, max=%d, diff=%d\n", min_number, max_number, (max_number - min_number)); countadc = (countadc - min_number - max_number) / 18; // 删除最小与最大值 printf("countaveradc = %d\n", countadc); voltage = (double)countadc / 2048 * 1.05; printf("voltage=%1.3lfv\n", voltage); }