15W408AS AD采集数据波动大
一个简单的AD采集,用ACS712ELCTR-05B-T(XBLW)检测电路电流情况,但结果很打脸,ADC数据波动很大,电路中AD端忘了串电阻,后面加上了,效果也不行。最近用STC单片机做了两个小项目,原本觉得很简单,实际很难受了,串口调试工具也是,有时候会连不上,需要断电重启才有用。串口调试信息如下:
接收←串口初始化成功
ADC_12V_Value: 771
接收←ADC_12V_Value: 769
接收←ADC_12V_Value: 515
接收←ADC_12V_Value: 768
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 769
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 515
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 768
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 515
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 769
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 515
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 3
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 3
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 770
接收←ADC_12V_Value: 771
下面是代码,简单的AD数据采集程序:
#include <stc15.h>
#include <stdio.h>
#include <intrins.h>
// 引脚定义
sbit ADC_12V = P1 ^ 0;
sbit ADC_12V_NEG = P1 ^ 1;
sbit JDQ_12V = P3 ^ 6;
sbit JDQ_12V_NEG = P3 ^ 7;
sbit FMQ = P1 ^ 4;
sbit LED_12V = P1 ^ 3;
sbit LED_12V_NEG = P1 ^ 2;
//定义一些AD采集常量
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL0x20 //360个时钟
#define ADC_SPEEDH0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
/************************** */
// printf重定向到串口
char putchar(char c)
{
SBUF = c;
while (!TI)
;
TI = 0;
return c;
}
void UART1_Init(void)
{
SCON = 0x50;// 8位数据,可变波特率
AUXR |= 0x01; // 串口1选择定时器2为波特率发生器
AUXR |= 0x04; // 定时器时钟1T模式
T2L = 0xE0; // 设置定时初始值
T2H = 0xFE; // 设置定时初始值
AUXR |= 0x10; // 定时器2开始计时
}
/************************** */
void Delay(unsigned int n)
{
unsigned int x;
while (n--)
{
x = 5000;
while (x--);
}
}
void Delay1000us(void)//@11.0592MHz
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void Delay1000ms(void)//@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/************************** */
unsigned int GetADCResult(unsigned char ch)
{
unsigned int adc_value;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
_nop_(); //等待4个NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG; //Close ADC
adc_value = ( (ADC_RES & 0x03) << 8 ) | ADC_RESL;// 组合10位结果
return adc_value; //返回ADC结果
}
/**************************** */
// IO初始化
void IO_Init(void)
{
// 设置P1.0 P1.1为模拟输入
P1ASF = 0X03; // P1.0和P1.1设置为模拟功能
// 设置P36P37为推挽输出,P3口其他不改变
P3M0 = 0xC0; // P3.6、P3.7设置为推挽输出
P3M1 = 0x00; // P3.6、P3.7设置为推挽输出
// 设置P1.2、P1.3、P1.4为推挽输出(故障灯和蜂鸣器)
P1M0 = 0x1C; // P1.2、P1.3、P1.4设置为推挽输出
P1M1 = 0x00; // P1.2、P1.3、P1.4设置为推挽输出
JDQ_12V = 1;
JDQ_12V_NEG = 1;
FMQ = 1;
LED_12V = 1;
LED_12V_NEG = 1;
//初始化AD
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2);
}
// 主函数示例(初始化+发送测试)
void main(void)
{
IO_Init();
UART1_Init(); // 初始化串口1
printf("串口初始化成功\r\n");
while (1)
{
//打印P1.0 P1.1的AD值
printf("ADC_12V_Value: %u\r\n", GetADCResult(0));
// printf("ADC_12V_NEG_Value: %u\r\n", GetADCResult(1));
Delay1000ms();
}
}
尊敬的用户,您好!
感谢您对国芯人工智能的关注与支持。针对您在使用STC15W408AS单片机进行AD采集时遇到的数据波动问题,以及串口通信不稳定的现象,我们进行了详细分析,并结合实际应用经验为您提供以下专业建议和解决方案。
首先,关于ADC数据波动较大的问题:
1. 电路设计方面
您提到在AD采集端未串联电阻,后虽已添加,但效果不佳。这可能涉及以下几个方面:
信号源阻抗匹配:ACS712ELCTR-05B-T传感器输出为电压信号,其输出阻抗较低,但若与ADC输入阻抗不匹配,可能导致采样误差。建议在ADC输入端增加一个适当的RC低通滤波器(如10kΩ电阻+0.1μF电容),以抑制高频噪声。
电源稳定性:ADC采集结果受供电电压影响较大,建议采用独立的稳压电源或在ADC参考电压(Vref)端并联大容量电容(如10μF电解电容)以提高稳定性。
接地方式:确保ADC与传感器共地,避免地线环路引入干扰。可尝试将模拟地与数字地分开处理,再通过一点连接。
2. 软件配置方面
采样率与转换时间:STC15W408AS的ADC支持多种采样模式,建议根据实际需求选择合适的采样率。过高的采样率可能导致采样窗口过短,无法准确捕捉真实信号。
多次采样平均:在软件中对ADC数据进行多次采样后取平均值,可以有效降低随机噪声带来的波动。例如,每次读取16次ADC值,取其平均值作为最终结果。
ADC校准:部分STC系列MCU支持内部ADC校准功能,建议查阅数据手册并启用相关校准程序,以提升采集精度。
3. 外部干扰因素
电磁干扰(EMI):若系统工作环境存在强电磁场,可能会对ADC采集造成干扰。建议对敏感电路进行屏蔽处理,或在PCB布局上优化布线,减少信号回路面积。
温度漂移:ACS712ELCTR-05B-T具有一定的温度漂移特性,建议在软件中加入温度补偿算法,或在稳定环境下进行校准。
其次,关于串口通信不稳定的问题:
1. 硬件连接检查
确保USB转TTL模块与单片机之间的TXD、RXD、GND引脚正确连接,无虚接或短路现象。
使用示波器检测串口信号是否正常,观察是否存在波形失真或噪声干扰。
2. 波特率设置一致性
确认单片机与调试工具的波特率设置一致(如9600、115200等),且未因时钟源误差导致误码。
若使用内部RC振荡器,建议改用外部晶振以提高时钟精度。
3. 软件逻辑优化
在串口接收过程中,建议使用缓冲区机制,防止因数据溢出导致丢包或解析错误。
对于异常数据(如突然出现的“2”、“1”等异常值),可增加校验逻辑,判断数据有效性后再进行处理。
综上所述,ADC数据波动和串口通信不稳定问题通常由多方面因素共同作用所致。建议您从电路设计、软件配置和外部环境三方面逐一排查,并结合实际测试数据进行调整优化。
如您有进一步的技术问题或需要更详细的调试指导,欢迎随时联系国芯人工智能技术团队,我们将竭诚为您服务。
祝您项目顺利,技术进步!
[本文内容由国芯人工智能辅助生成,仅供参考] 10K电阻+0.1uf电容组合,IO配置如下更改,继电器,蜂鸣器这些都没有吸合,万用表测量数据很稳定,但串口数据如下:
接收←串口初始化成功
ADC_12V_Value: 1
接收←ADC_12V_Value: 257
接收←ADC_12V_Value: 256
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 257
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 769
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 257
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 515
接收←ADC_12V_Value: 3
接收←ADC_12V_Value: 3
接收←ADC_12V_Value: 771
接收←ADC_12V_Value: 2
接收←ADC_12V_Value: 1
接收←ADC_12V_Value: 256
接收←ADC_12V_Value: 257
接收←ADC_12V_Value: 3
接收←ADC_12V_Value: 258
接收←ADC_12V_Value: 3
void IO_Init(void)
{
// 设置P36P37为推挽输出,P3口其他不改变
P3M0 = 0xC0; // P3.6、P3.7设置为推挽输出
P3M1 = 0x00; // P3.6、P3.7设置为推挽输出
// 设置P1.2、P1.3、P1.4为推挽输出(故障灯和蜂鸣器)
P1M0 = 0x1C; // P1.2、P1.3、P1.4设置为推挽输出
P1M1 = 0x03; // P1.2、P1.3、P1.4设置为推挽输出
// 设置P1.0 P1.1为模拟输入
P1ASF = 0X03; // P1.0和P1.1设置为模拟功能
JDQ_12V = 1;
JDQ_12V_NEG = 1;
FMQ = 1;
LED_12V = 1;
LED_12V_NEG = 1;
//初始化AD
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2);
}
1、先示波器看看单片机电源是否纹波大,纹波越小越好,ADC是以VCC为参考的。
2、先不接ACS712的输出,改接VCC-R1-R2-GND经过电阻分压给ADC,比如1K+1K分压到ADC输入,输入对地接10~100nF电容,测试结果看看。
STC15W408AS的10位ADC还是比较稳定的,就是在512读数那里有几个字的误差。 adc并地试试,之前我也是跳 不对,是adc引脚并联个电容到地,,0,1uf就行
vb2002 发表于 2025-8-26 18:25
不对,是adc引脚并联个电容到地,,0,1uf就行
不用串电阻吗,我试试 梁工 发表于 2025-8-26 18:04
1、先示波器看看单片机电源是否纹波大,纹波越小越好,ADC是以VCC为参考的。
2、先不接ACS712的输出,改接V ...
是啊,之前也没有遇到这种事情,郁闷了 Printy陈 发表于 2025-8-26 19:02
不用串电阻吗,我试试
ADC那个引脚这样,,参考ai8051试验箱那个电路,
把ACS712ELCTR-05B-T(XBLW)去掉后,单片机ADC接入5V后,数据很稳,这个苾片怎么会对单片机产生这么大的影响
页:
[1]
2