找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4585|回复: 24
收起左侧

STC8A8K单片机多路ADC采集得到的结果一模一样,可能会是什么问题?

  [复制链接]
ID:898834 发表于 2021-7-25 15:37 | 显示全部楼层 |阅读模式
单片机程序如下,求大神指导
  1. #include  <stc8.h>
  2. #include  <delay.h>
  3. #include  <uart.h>
  4. #include  <adc12.h>
  5. #include  <adc13.h>        
  6. #include  <adc14.h>

  7. //float R;

  8. void main()
  9. {
  10.         P3M1 &= 0xFE;        P3M0 &= 0xFE;                          //设置P3.0为准双向口
  11.         P3M1 &= 0xFD;        P3M0 |= 0x02;                          //设置P3.1为推挽输出
  12.                
  13.         ADC12_config();         
  14.         ADC13_config();
  15.   ADC14_config();                             //ADC初始化

  16.         Uart1_Init();                                 //串口1初始化         
  17.         EA = 1;                                       //使能总中断
  18.   Delay10ms();                                  //初始化后延时
  19.         
  20. //        R=(HandleADC13()*3000)/(2*HandleADC12()-HandleADC13());  //输入电阻计算
  21.         
  22.   while (1)
  23.         {
  24.                  printf("\r\n P0.4上的电压: %.3f\r\n",HandleADC12());      //输入电压1        
  25.                  printf("\r\n P0.5上的电压: %.3f\r\n",HandleADC13());      //输入电压2        
  26.                  printf("\r\n P0.6上的电压: %.3f\r\n",HandleADC14());      //输出电压               
  27. //                  printf("\r\n 电压增益: %.3f\r\n",HandleADC14()/HandleADC13());     //串口打印上传的采集的电压值
  28. //           printf("\r\n 输入电阻: %.1f\r\n",R);        
  29.      Delay1000ms();
  30.         }
  31. }

复制代码


差分放大电路电压放大倍数ADC测量.zip

89.73 KB, 下载次数: 40

回复

使用道具 举报

ID:401564 发表于 2021-7-25 23:38 | 显示全部楼层
你看一下你的ADC程序里面有没有这个查询ADC完成标志位的我是没有在你程序里找到
ADC是要一个过程的,启动ADC之后,如果是查询方式的话,是要一直等待ADC完成才能正确的得到ADC结果的
51hei截图20210725233503.png

回复

使用道具 举报

ID:898834 发表于 2021-7-26 09:12 | 显示全部楼层
Y_G_G 发表于 2021-7-25 23:38
你看一下你的ADC程序里面有没有这个查询ADC完成标志位的我是没有在你程序里找到
ADC是要一个过程的,启动AD ...

但是我在实际测试中,ADC已经发挥作用了,也能得到端口检测到的值,只是多路使用的时候无法实现
回复

使用道具 举报

ID:170318 发表于 2021-7-26 09:40 | 显示全部楼层
贴上来的程序不完整,不好分析原因,可以肯定地说是程序的问题
回复

使用道具 举报

ID:898834 发表于 2021-7-26 09:48 | 显示全部楼层
jhczy 发表于 2021-7-26 09:40
贴上来的程序不完整,不好分析原因,可以肯定地说是程序的问题

ADC初始化及采集程序如下
void        ADC_config(void)   //ADC 初始化
{       
        ADC_CONTR|=0x80;              //开AD转换电源
        delay_ms(10);           //适当延时等待AD转换供电稳定
        ADC_CONTR|=0x0E;                          //选择P0.6作为模拟功能AD使用
        ADC_CONTR&=0xFE;                          //选择P0.6作为模拟功能AD使用
       
        ADCCFG&=0xFC;             //AD转换速度为416个时钟数转换一次
        ADCCFG|=0x0C;             //AD转换速度为416个时钟数转换一次
        ADC_CONTR&=0xDF;          //清AD转换完成标志
               
        EADC=0;                   //禁止ADC转换中断
        ADCCFG|=0x20;             //ADC转换结果ADC_RES存高4位,ADC_RESL存低8位

}

uint16        Get_ADC12bitResult(void)        //得到ADC12位结果
{       
        ADC_CONTR|=0x40;          //启动AD转换,ADC_START=1
        delay_ms(10);
        while(!(ADC_CONTR&0x20));    //查询ADC完成标志
  ADC_CONTR&=0xDF;              // 将ADC_FLAG完成标志清0
        ADC_CONTR&=0xBF;        //关闭AD转换,ADC_START=0
        //12位AD结果的高4位放ADC_RES的低4位,低8位在ADC_RESL
        AD_Dat = ADC_RES;                       //将ADC_RES低4位移到应在的第9位至第12位
        AD_Dat <<= 8;
        AD_Dat|= ADC_RESL;               //将ADC_RESL的8位移到应在的低8位
       
  ADC_CONTR|=0x40;           //启动AD转换,ADC_START=1
        return        AD_Dat;       
}
回复

使用道具 举报

ID:170318 发表于 2021-7-26 10:00 | 显示全部楼层
本帖最后由 jhczy 于 2021-7-26 10:07 编辑
zqz1345444061 发表于 2021-7-26 09:48
ADC初始化及采集程序如下
void        ADC_config(void)   //ADC 初始化
{        

这个程序确实有问题,STC8与STC15的ADC程序有点小区别,请详细看STC8的手册
回复

使用道具 举报

ID:898834 发表于 2021-7-26 10:07 | 显示全部楼层
jhczy 发表于 2021-7-26 10:00
这个程序确实有问题,STC8与STC15的ADC程序有点小区别,请详细看STC8G的手册

可是它的确也能实现ADC的功能
回复

使用道具 举报

ID:170318 发表于 2021-7-26 10:10 | 显示全部楼层
zqz1345444061 发表于 2021-7-26 10:07
可是它的确也能实现ADC的功能

采集的数据可能就是某一个通道上的
回复

使用道具 举报

ID:898834 发表于 2021-7-26 10:12 | 显示全部楼层
jhczy 发表于 2021-7-26 10:10
采集的数据可能就是某一个通道上的

确实是,我这个程序是选择固定通道,我的问题就在于不知道如何选择多个通道
回复

使用道具 举报

ID:123289 发表于 2021-7-26 10:14 | 显示全部楼层
在AD的硬件中,有一个采样电容,当你下达采样命令后,会经历如下的过程:
1、将这个电容与端口连通,并保持若干个时钟。目的让电容上得到与端口一样的电压。
2、再切断与端口的连接,防止在进行电压比较时,电压有波动,影响、绞乱逐次逼近的逻辑。
3、接下来才进行真正的AD转换(逐次逼近),需要N个时钟周期,得到AD值。
所以,采样时要注意(这是精华):
切换端口后,要过一段时间再下达采样命令,因为刚切换后,采样电容上是上一个通道的电压,需要有一个充放电的过程,才能变为新通道端口上的电压。这一点相当重要!!!新手一般不会考虑到这一点,许多高手也吃它的苦。表现为采样电压的数据不稳定,其实是部分地受上个通道的电压“残余”影响了。
解决的方案很简单:估计楼主想到了……
回复

使用道具 举报

ID:170318 发表于 2021-7-26 10:17 | 显示全部楼层
zqz1345444061 发表于 2021-7-26 10:07
可是它的确也能实现ADC的功能

我的STC8G的某一个端口的ADC程序(STC8G1K08的),12MHz
void W1_ADC()                                                //P3.4检测
{
//        TR0=0;
        P3M1=0x10;                          //P3.4高阻输入模式,P3.0-3.1-3.3为准双向
        P3M0=0x04;
        P_SW2|=0x80;
        ADCTIM=0x3f;
        P_SW2&=0x7f;
        ADCCFG=0x0f;                  //设置ADC时钟为系统频率的/2/16
        ADC_CONTR=0x80;               //使能ADC模块
        _nop_();
        _nop_();
        ADC_RES=0;                           //清除结果
        ADC_CONTR|=0x0c;               // 设定转换的通道,P3.4是1100(0x0c)
        ADC_CONTR|=0x40;                     // 开始AD转换,即ADC_START=1
        _nop_();
        _nop_();
        while(!(ADC_CONTR & 0x20));    //  等待转换完成 ,即ADC_FLAG=1
        ADC_CONTR&=~0x20;              //  清零 即D3位start清零,D4位转换结束标志位ADC_flag清零
        shuj=ADC_RES;                  //  取高八位
//        TR0=1;
        P3M1=0x00;
        P3M0=0x04;
}
回复

使用道具 举报

ID:170318 发表于 2021-7-26 10:18 | 显示全部楼层
zqz1345444061 发表于 2021-7-26 10:12
确实是,我这个程序是选择固定通道,我的问题就在于不知道如何选择多个通道

一个通道一个程序,端口状态要设置改变的
回复

使用道具 举报

ID:898834 发表于 2021-7-26 10:23 | 显示全部楼层
jhczy 发表于 2021-7-26 10:17
我的STC8G的某一个端口的ADC程序(STC8G1K08的),12MHz
void W1_ADC()                                                //P3.4检测
{

好的,谢谢,我再试一下
回复

使用道具 举报

ID:401564 发表于 2021-7-26 12:17 | 显示全部楼层
ADC用中断比较好,不用一直等待,程序也可以做其它的事
STC8A4k不需要设定转换时钟个数的,ADC时钟用最慢的时钟频率就可以了
我这个是自己写的,可以在有字库的12864上显示
你参考一下
STC8A4K_12864.rar (1.92 KB, 下载次数: 86)
回复

使用道具 举报

ID:898834 发表于 2021-7-26 14:43 | 显示全部楼层
Y_G_G 发表于 2021-7-26 12:17
ADC用中断比较好,不用一直等待,程序也可以做其它的事
STC8A4k不需要设定转换时钟个数的,ADC时钟用最慢的时 ...

好的,感谢帮助
回复

使用道具 举报

ID:898834 发表于 2021-7-26 14:50 | 显示全部楼层
Y_G_G 发表于 2021-7-26 12:17
ADC用中断比较好,不用一直等待,程序也可以做其它的事
STC8A4k不需要设定转换时钟个数的,ADC时钟用最慢的时 ...

好的感谢帮助
回复

使用道具 举报

ID:213173 发表于 2021-7-26 16:49 | 显示全部楼层
zqz1345444061 发表于 2021-7-26 10:12
确实是,我这个程序是选择固定通道,我的问题就在于不知道如何选择多个通道

对ADC_CONTR寄存器低4位赋值选择ADC通道。 无标题.jpg

回复

使用道具 举报

ID:382454 发表于 2021-7-27 16:43 | 显示全部楼层
按我的经验,8系列分时复用IO口检测ADC, 刚打开IO口的时候也要延时1-2ms的,不然测出来也不准
回复

使用道具 举报

ID:229375 发表于 2021-12-11 17:41 | 显示全部楼层
兄弟,请问这个问题解决了吗?
我按照之前10楼大佬说的解决办法,延迟采集似乎没有效果...
回复

使用道具 举报

ID:229375 发表于 2021-12-11 17:52 | 显示全部楼层
河边洗脚人 发表于 2021-12-11 17:41
兄弟,请问这个问题解决了吗?
我按照之前10楼大佬说的解决办法,延迟采集似乎没有效果...

是我切换通道时设置错了。

回复

使用道具 举报

ID:906597 发表于 2021-12-24 21:47 | 显示全部楼层
同问,我也是这个问题,我配置了2个ADC初始化,选的不同的口,但是还是只显示1个的值
回复

使用道具 举报

ID:382454 发表于 2021-12-29 10:15 | 显示全部楼层
你的逻辑步骤很重要,STC8A8K系列ADC有几种工作方式的,中断是比较实用的。因为中断不要CPU去等待,判断。你要先把单个口的ADC代码写OK才行,测好单个口的ADC代码没问题之后,再扩展多个IO口,那么这多个口怎么分时复用去扫描也是很简单的,可以定义一个扫描完成的标志位FLAG ,再定义一个多口数字变量,几个标志一起参写判断。简单的来就就是第一个口扫描完志成了,CPU自动进入第二个口扫描,扫完第二个,自动描扫第三个,以此反复循环,在写码的时候是很灵活的。重点是你要把小个的函数写好,把小个的凑成一个整体。小的局部没写好,大的找起来就一头乱。
回复

使用道具 举报

ID:382454 发表于 2021-12-29 10:18 | 显示全部楼层
还有一个就是CPU硬件AVCC这个ADC供电接口 接了没有?我以前试过画板时没有接上,找了我一个星期。
回复

使用道具 举报

ID:936755 发表于 2022-10-14 15:02 | 显示全部楼层
Y_G_G 发表于 2021-7-26 12:17
ADC用中断比较好,不用一直等待,程序也可以做其它的事
STC8A4k不需要设定转换时钟个数的,ADC时钟用最慢的时 ...

ganx,,
回复

使用道具 举报

ID:1051062 发表于 2022-11-9 15:03 | 显示全部楼层
采集到的数值是不变的吗,不变可能采集不到,变了的话就是所有采集到的数据都在一个通道里
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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