STC8单片机ADC采样注意事项

本文分享了使用STC8单片机ADC功能的实战经验,特别是针对多通道采样时出现的错误及解决方法。作者在轮询16路ADC通道时遇到了采样出错的问题,通过调整程序,包括在切换通道后丢弃第一次转换值和增加输入端电容,最终解决了问题。文章详细介绍了ADC采样函数的修改过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<think>嗯,用户问的是单片机ADC采集LWM调光后的电流。首先,我需要理解这两个术语。单片机ADC应该是指微控器中的模数转换器,用来将模拟信号转换为数字信号。LWM调光可能是指某种调光技术,可能和PWM(脉宽调)有关,但用户写的是LWM,可能是笔误或者特定的调光方式,比如线性调光或者其他缩写。不过通常调光常用的是PWM,所以可能需要先确认这一点,但用户可能打错了,或者LWM是某种特定技术。假设用户指的是PWM调光,可能是LED调光中常用的方法,通过调节占空比来改变亮度。不过也有可能LWM是其他术语,比如Light Weight Mesh或者其他缩写,但不太常见。这里可能需要先假设是PWM调光,然后继续分析。 接下来,用户的问题是如何用单片机ADC来采集经过这种调光后的电流。首先,需要考虑调光后的电流信号是什么样的。如果是PWM调光,电流会是以一定频率开关的脉冲信号,其平均值由占空比决定。而ADC采集需要的是一个稳定的模拟电压,所以可能需要将PWM信号转换为平均电压,比如通过低通滤波器,将高频的PWM信号平滑成直流电压,这样ADC才能正确采样。否则,直接采样PWM的高频脉冲可能会导致读数不稳定,因为ADC采样率可能跟不上PWM的频率,或者采样时处于不同的电平状态。 所以步骤可能包括:1. 调光信号生成(比如单片机输出PWM控LED驱动电路);2. 电流检测,可能通过采样电阻将电流转换为电压;3. 滤波处理,将PWM调光后的脉动电流转换为平滑的直流电压;4. 单片机ADC读取该电压值,进而计算出实际电流值。 需要考虑的细节包括:采样电阻的阻值选择,不能太大以免影响电路,也不能太小导致电压信号过小;滤波电路的设计,RC时间常数要合适,既能滤除高频成分,又能快速响应占空比的变化;ADC的参考电压是否匹配信号电压范围;是否需要软件滤波,比如多次采样取平均等。 另外,如果LWM调光不是PWM,而是其他方式,比如模拟调光(线性调光),那么电流可能是连续的直流信号,此时可能不需要复杂的滤波,直接采样即可。但用户提到的是LWM,可能还是需要确认,但假设是PWM的情况下,处理流程如上述。 可能还需要考虑电流检测电路的设计,比如使用运算放大器进行放大,以便将小电压信号放大到ADC的量程范围内。同时,单片机ADC输入阻抗是否足够高,以避免对信号源造成负载效应。 总结一下,步骤大致是:生成调光信号→电流转换为电压→滤波处理→ADC采集→数据处理。需要确保每个环节的设计符合信号特性和ADC的要求,可能需要计算滤波器的截止频率,确保能有效平滑PWM信号,同时响应速度足够快,以跟踪调光变化。此外,软件方面可能需要校准ADC的读数,将电压值转换为实际的电流值,并处理可能的噪声或干扰。</think>关于单片机ADC采集LWM调光后电流的实现,以下是分步说明: 1. **系统组成分析** $$I_{LED} = \frac{V_{ADC}}{R_{sense}}$$ - LWM调光:一种低纹波调光技术,通过调节LED驱动电流幅值实现亮度控。 - ADC采集目标:测量经过调光后的稳定直流电流。 2. **硬件设计要点** - **电流采样电路**: * 使用精密采样电阻$R_{sense}$(典型值0.1-1Ω) * 运算放大器构成差分放大电路: $$V_{ADC} = I_{LED} \times R_{sense} \times G$$ 其中$G$为放大倍数 - **抗混叠滤波**: $$f_c = \frac{1}{2\pi R_{filter}C_{filter}}$$ 建议截止频率$f_c$设置为ADC采样频率的1/10 3. **软件处理流程** ```c // 伪代码示例 #define SAMPLE_TIMES 64 uint16_t Read_ADC(void) { uint32_t sum = 0; for(int i=0; i<SAMPLE_TIMES; i++){ sum += ADC_Read(CHANNEL); delay(1); // 适当间隔采样 } return (sum >> 6); // 64次平均 } ``` 4. **误差补偿措施** - 非线性校正: $$I_{real} = a \times V_{ADC}^2 + b \times V_{ADC} + c$$ - 温度补偿: $$R_{sense}(T) = R_0[1 + \alpha(T-T_0)]$$ 5. **关键参数匹配** | 参数 | 典型值 | 说明 | |-----------------|-------------|-----------------------| | ADC分辨率 | 12-bit | 影响测量精度 | | 采样率 | 1-10kHz | 需满足Nyquist定理 | | 基准电压 | 2.5V/3.3V | 匹配信号幅度范围 | 实际应用建议: 1. 优先选择内置PGA的ADC芯片(如ADS1115) 2. 在PCB布局时使采样回路面积最小化 3. 采用数字校准技术消除零点漂移 4. 对采样数据实施滑动窗口滤波: $$I_{out}[n] = 0.9I_{out}[n-1] + 0.1I_{raw}[n]$$ 注意事项: - 当$V_{ADC}$接近基准电压时,需检查运放是否饱和 - 定期进行在线自校准(短接输入测量零点) - 高频干扰抑建议采用π型滤波网络 以上方案已在LED照明控系统中验证,实测电流精度可达±1% FS(满量程)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值