找回密码
 立即注册
查看: 2206|回复: 12

STC8G1K08A ADC采集忽然之间跳出一个较大数值 | 已解决

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2024-10-14 11:22:58

3

主题

1

回帖

48

积分

新手上路

积分
48
发表于 2024-2-23 16:57:17 | 显示全部楼层 |阅读模式
本人在使用STC8G1K08A 做数据采集;
信号源采用的是一个精密电压源;
电源供电为5V  稳压电源供电;
为防止阻抗问题,恒压源后接一个电压跟随器接至ADC;
现在出现在采集过程中几组准的数值,后又会夹杂着一些不太准确的数值;


代码如下:

void main()
{
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
        P5M1 = 0x30; //P54高阻
    P_SW2 |= 0x80;
    //ADCTIM = 0x3f;                              //设置ADC内部时序
        ADCTIM = 0xff;
    P_SW2 &= 0x7f;
    ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x80;                           //使能ADC模块
        UartInit();
         ES = 1;
    TMOD = 0x00;                                //模式0
    TL0 = 0x66;                                 //65536-11.0592M/12/1000
    TH0 = 0xfc;
    TR0 = 1;                                    //启动定时器
    ET0 = 1;                                    //使能定时器中断
    EA = 1;
    while (1)
    {
                        adc4= GetADCResult(4);
                           ave3= (adc4*4.88);
                        UartSend (ave3 / 1000 + 0x30);
                        UartSend (ave3 % 1000 / 100 + 0x30);
                        UartSend (ave3 % 100 / 10 + 0x30);
                        UartSend (ave3 % 10 + 0x30);
                        UartSendStr("\r\n");

        }
                   adc4=0;
                         Delay(20000);
}


  WORD GetADCResult(BYTE ch)
{           
        ADCTMP=0;
        ADC_RES=0;
        ADC_RESL=0;
    ADC_CONTR = ADC_POWER| ch | ADC_START;
         Delay(500);  
          while(~(ADC_CONTR|0xdf));//等待ADC转换完成
//                UartSend(ADC_RES);
//                UartSend(ADC_RESL);
    ADC_CONTR &= 0xdf;         //清完成标志
        ADCTMP=(ADC_RES)<<2;
        ADCTMP|=ADC_RESL;
    return ADCTMP;                 //返回ADC结果
        WDT_CONTR |= 0x10;
}





示意图

示意图
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-2-23 17:53:01 | 显示全部楼层

电路设计一定要按 STC8H 中的讲的更专业的电路来

截图202402231751505457.jpg

截图202402231752563665.jpg

截图202402231752301820.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-2-23 17:54:38 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-2-23 17:57:31 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2024-2-23 19:13:54 | 显示全部楼层
截图202402231909225977.jpg
注意一下数据的问题呢~你用的左对齐的格式;
也就是 实际上应该是  ((adc_res << 8)|adc_resl)>>6 才对,
你这写法有一点思路错了首先adc_res 左移两位没毛病,
但是adc_resl的数据在高位,在第bit7和bit6,
你这直接或上去那不妥妥的出事情??
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-2-23 22:12:57 | 显示全部楼层
程序有几个问题:
1、变量做好不要用全大写。常量或特殊功能寄存器才大写。(这是编程习惯)。
2、ave3= (adc4*4.88);
     没看到你的变量定义,如果定义的是unsigned int adc4,则(adc4*4.88)可能只执行(adc4*4),
必须强制转换一下:ave3= (u16)((float)adc4*4.88);
3、ADCTMP=(ADC_RES)<<2;
   这句会将ADC_RES最高2位去掉,必须强制转换一下(变量用小写):
    AdcTmp = ((u16)ADC_RES << 2) + (ADC_RESL & 0x03);

以上规范写法不容易出错,特别是隐含的错误,很难查的。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-2-24 09:03:53 | 显示全部楼层
梁*** 发表于 2024-2-23 22:12
程序有几个问题:
1、变量做好不要用全大写。常量或特殊功能寄存器才大写。(这是编程习惯)。
2、ave3= (a ...

请问 关于第2点这里 整型和浮点型数据进行计算时,这个可能执行时啥意思0.0
我好像记得C语言中在变量进行计算时  会将低级别类型的变量转换成高级别类型

那么这里的可能是还要考虑上优化等级之类的因素么0.0

点评

不去猜测,而是用可靠的方法编程。不依赖于编译器的默认规则是最好的。  详情 回复 发表于 2024-2-24 09:36
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-2-24 09:36:40 | 显示全部楼层
_奶*** 发表于 2024-2-24 09:03
请问 关于第2点这里 整型和浮点型数据进行计算时,这个可能执行时啥意思0.0
我好像记得C语言中在变量进行 ...

不去猜测,而是用可靠的方法编程
不依赖于各种编译器的默认规则是最好的。
他哪个版本搞错默认规则咋办
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-2-24 09:56:53 | 显示全部楼层
梁*** 发表于 2024-2-24 09:36
不去猜测,而是用可靠的方法编程。不依赖于编译器的默认规则是最好的。 ...

不不 平常确实不这样去隐式转换的用,但是这个是需要搞清楚的东西,,所以为什么是   可能  
因为这个是C语言规定的东西,就目前您叙述的东西和C语言已经有出入了,,不过基于您的权威和我的认知有限,所以我认为可能在keil的C51中对于这部分有什么变化,,最好是可以说明清楚,这样也能提升坛友们的编程水平,,方法论的东西这我也知道,但是我已经提出了疑问,请梁工更细致的解释一下。这里替大家伙谢过梁工了

点评

我是企业工程师,我要保证程序风险尽量低,所以程序中的计算,我会大量使用括号而不去搞透KEL的运算优先级,使用强制转换将计算的变量对齐而不去搞透KEIL的默认规则。 不同的编译器,规则会不同,为了更好的移植性(  详情 回复 发表于 2024-2-24 10:53
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-2-24 10:53:08 | 显示全部楼层
_奶*** 发表于 2024-2-24 09:56
不不 平常确实不这样去隐式转换的用,但是这个是需要搞清楚的东西,,所以为什么是   可能  
因为这个是C ...

我是企业工程师,我要保证程序风险尽量低,所以程序中的计算,我会大量使用括号而不去搞透KEL的运算优先级,使用强制转换将计算的变量对齐而不去搞透KEIL的默认规则。
不同的编译器,规则会不同,为了更好的移植性(尽量与编译器无关),所以规范些程序。
个人的程序有问题可以慢慢查,但是对于我们企业,如果程序语法不严谨,会增加很多不确定性。如果程序在我的编译器是正常的,但是你的编译器不正常,这个怎么说?

你可以用各种程序去测试,看KEIL的默认规则。
回复 支持 1 反对 0

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:30 , Processed in 0.134543 second(s), 119 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表