zoukankan      html  css  js  c++  java
  • 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电路的问题, 以后一定要注意这些东西, 看来还是自己的知识没有学扎实。 加油!

  • 相关阅读:
    机器学习-正则化方法
    机器学习-回归算法
    机器学习算法一
    机器学习概览
    tensorflow机器学习初接触
    tensorflow决策树初接触
    tensorflow语法
    tensorflow第一个例子简单实用
    Hyperledger Fabric 1.0架构入门
    结合《XXXX需求征集系统》分析可用性和可修改性战术
  • 原文地址:https://www.cnblogs.com/Gentleaves/p/11285243.html
Copyright © 2011-2022 走看看