STC8单片机ADC采样注意事项

STC8单片机ADC采样注意事项

STC8单片机ADC采样注意事项

最近在做一个模块,使用宏晶公司的STC8单片机开发,模块主要使用了单片机的ADC采样功能,因为需要10个以上的通道,而且模块要经常震动,所以希望使用一种耐操一点的芯片, 于是我使用了STC8系列的单片机,有16路通道的ADC,采样精度是12位,可以比较好的满足我的要求。 一开始模块做的还不错,半年之后有一次要进行改进,在程序上我加大了单片机通道切换之间的时间,然而最后却出现了采样出错的现象。

因为我要轮询所有的ADC通道,出于设计方面,我采用了特别的采样顺序,采样出错的结果不知道是怎么回事,在改了程序之后便出现了问题, 我一直认为是程序的问题,搞到最后怀疑人生了,,感觉难道这又是STC的一个bug?

不过,最后我终于在网上找到了一个线索,并且尝试按照那个方法改了一下程序,ojbk了。 贴一下那个线索的原话:

如果输入信号内阻很大(超过1K就算大了,如果10K就很大了),ADC输入端对地接一个0.01~0.1uF的电容。
切换通道后,第一次转换值丢弃。

为什么会有这些要求?为什么外挂专门的ADC也一样的有这种要求?
对于没有输入缓冲的ADC(STC的ADC输入就是没有缓冲的),采样时ADC输入端通过一个电阻(r,通常是几K欧姆)给采样电容C充电(采样电容一般是10~30PF,STC的可以按30PF计算),假设信号源内阻为R0,则采样充电就是((R0+r)*C),采样时间t一般是很短的,比如STC最快时采样就是几个时钟,时间很短。

贴一下我的ADC采集函数(更改之前的):

/**
 * [ADCRead description]
 * @Author     叶鹏程
 * @DateTime   2019-08-01T20:24:46+0800
 * @discrption : ADC采样函数,
 *  
 * @param      n                        [要采样的通道]
 * @param      value_point              [采样值存放地址]
 */
void ADCRead(uint8_t n,unsigned int  xdata *value_point){
    unsigned int adc_value = 0;
    
    ADC_SET_CHANEL(n);  //设置当前待转换的ADC通道
    ADC_START_ENABLE();

    while(ADC_STATE()); //等待转换
    
    ADC_FLAG_CLEAR();  

    adc_value = (int)ADC_RES << 8;                               //读取ADC结果
    adc_value |= (int)ADC_RESL;
    adc_value = adc_value>>4;

    *value_point = adc_value;
}

这是按照线索,更改之后的:

/**
 * [ADCRead description]
 * @Author     叶鹏程
 * @DateTime   2019-08-01T20:24:46+0800
 * @discrption : ADC采样函数,
 *  
 * @param      n                        [要采样的通道]
 * @param      value_point              [采样值存放地址]
 */
void ADCRead(uint8_t n,unsigned int  xdata *value_point){
    unsigned int adc_value = 0;
    
    ADC_SET_CHANEL(n);  //设置当前待转换的ADC通道
    
    ADC_START_ENABLE();
    while(ADC_STATE()); //等待转换
    ADC_FLAG_CLEAR();  
    
    /* 这是清除了第一次转换的值,采用第二次采样,这样在切换通道时更加稳定*/
    ADC_START_ENABLE();
    while(ADC_STATE()); //等待转换
    ADC_FLAG_CLEAR();  

    adc_value = (int)ADC_RES << 8;                               //读取ADC结果
    adc_value |= (int)ADC_RESL;
    adc_value = adc_value>>4;

    *value_point = adc_value;
}

总结,这是ADC电路的问题, 以后一定要注意这些东西, 看来还是自己的知识没有学扎实。 加油!

posted on 2019-08-01 20:52  Gentleaves 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/Gentleaves/p/11285243.html

你可能感兴趣的:(STC8单片机ADC采样注意事项)