N32G032的ADC,采样电池分压后的电压,为什么有比较大的误差
使用N32G032内部的ADC,锂电池使用2个47k电阻分压,计算得到的电压误差比较大,但是分压的电阻越小,则误差也越小。实际电压是2.05V,采样后计算为2.16,这是芯片自身的特性吗?现在主时钟配置为48MHz,ADC时钟是4M,采样周期是600,看资料这个状态外部允许的外部输入阻抗是几百k:
https://bbs.21ic.com/icview-3253266-1-1.html
有谁遇到过类似的问题吗?
以下是代码:
void Adc_Init(void)
{
GPIO_InitType GPIO_InitStructure;
DMA_InitType DMA_InitStructure;
ADC_InitType ADC_InitStructure;
ADC_InitTypeEx ADC_InitStructureEx;
/* Enable DMA clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
/* Enable GPIOC clocks */
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
/* Enable ADC clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE);
/* enable ADC 1M clock */
RCC_EnableHsi(ENABLE);
RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8);//这里必须是 1M 的时钟
/* RCC_ADCHCLK_DIV3*/
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV12); //48/12 = 4M // 最高 18 MHz
//ADC 中有的引脚
GPIO_InitStruct(&GPIO_InitStructure);
/* Configure PA.01 as analog input -------------------------*/
GPIO_InitStructure.Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.GPIO_Pull = GPIO_NO_PULL;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.GPIO_Current = GPIO_DC_HIGH;
GPIO_InitStructure.GPIO_Alternate = GPIO_NO_AF;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_4;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* DMA channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA_CH1);
DMA_InitStructure.PeriphAddr = (uint32_t)&ADC->DAT;
DMA_InitStructure.MemAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = 3;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc= DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(DMA_CH1, &DMA_InitStructure);
DMA_RequestRemap(DMA_REMAP_ADC, DMA, DMA_CH1, ENABLE);
/* Enable DMA channel1 */
DMA_EnableChannel(DMA_CH1, ENABLE);
/* ADC configuration ------------------------------------------------------*/
ADC_InitStructure.MultiChEn = ENABLE;
ADC_InitStructure.ContinueConvEn = ENABLE;
ADC_InitStructure.ExtTrigSelect= ADC_EXT_TRIGCONV_NONE;
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
ADC_InitStructure.ChsNumber = ADC_CHANNEL_NUM;
ADC_Init(ADC, &ADC_InitStructure);
ADC_InitStructureEx.ClkMode = ADC_CTRL3_CKMOD_AHB;//
ADC_InitStructureEx.EndcIntEn = DISABLE;//禁用注入结束中断
ADC_InitStructureEx.JendcIntEn = DISABLE;//禁用规则结束中断
ADC_InitStructureEx.RefSel = DISABLE;//是否内部2.4V为参考
ADC_InitStructureEx.VrefEn = ENABLE;//使能内部参考
ADC_InitEx(ADC,&ADC_InitStructureEx);
/* ADC regular channel1 configuration */
//每个通道的时长是 (600+12)/4 = 153us @4MHz
//每个通道的时长是 (600+12)/12 = 51us @12MHz
ADC_ConfigRegularChannel(ADC, ADC_CH_5_PA5, 1, ADC_SAMP_TIME_600CYCLES5);
ADC_ConfigRegularChannel(ADC, ADC_CH_4_PA4, 2, ADC_SAMP_TIME_600CYCLES5);
ADC_ConfigRegularChannel(ADC, ADC_CH_17, 3, ADC_SAMP_TIME_600CYCLES5); //内部参照电压, 1.16---1.26 , 标准 1.21V
/* Enable ADC DMA */
ADC_EnableDMA(ADC, ENABLE);
/* Enable ADC */
ADC_Enable(ADC, ENABLE);
/*wait ADC is ready to use*/
while(!ADC_GetFlagStatusNew(ADC, ADC_FLAG_RDY))//等待这个寄存器为 1
;
/*wait ADC is powered on*/
while(ADC_GetFlagStatusNew(ADC, ADC_FLAG_PD_RDY))//等待这个寄存器为 0
;
/*wait ADC VREFRDY is ready*/
while(!ADC_GetFlagStatusNew(ADC, ADC_FLAG_VREF_RDY))
;
/* Start ADC Software Conversion */
ADC_EnableSoftwareStartConv(ADC, ENABLE);
} 使用内部跟随器后再采样,可以降低误差达到可用状态,但我想知道这是芯片的原因还是配置的原因 是不是单片机内部AD的输入电阻太小导致的。 是阻抗的问题,AD的输入阻抗不是太大,一般需要低阻的输入,或者用运放做缓冲.
这个阻抗不是指外部信号的阻抗,而是指从外部看进去的阻抗,就是我们一般说的输入阻抗.
具体你这个情况,可以并联一个小电容到分压电阻上,比如1nf.不过这样的话,对电压的快速细微变化会不敏感.
ADC一般都是这个这个水平,所以既不是芯片的问题也不是设置的问题,是设计初未考虑好. 与基准和分压电阻精度有关 给下面的电阻并联一个103以上的电容看看 确实可以通过下面电阻增加电容来解决这个问题
在电池电压为4.15V时
没有电容,测量到电压是 4.28V
1uF电容,测量到电压是 4.15V
100nF电容,测量到电压是 4.15V
1nf电容,测量到电压是 4.21V 电池电压本身也在变化 分压会后,肯定是有误差的。 你看看差多少,使用修正一下。 说明你的电阻不是高精度电阻 误差在哪查看的 这个误差是固定的吗? 你可以人工修正数据,比较接近原来的数值的。 可能电阻不是精密电阻,数值不精确。 是误差较大的吗? 会不会ADC存在串扰的问题,对数据采集造成干扰? 推荐使用滤波算法,把数据精准度提高一下。 这个是硬件的问题吗? 可能是你选用的电阻存在问题。
页:
[1]
2