找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3267|回复: 18
收起左侧

最近测试了一下stc8G的ADC功能,想单独使用某一个口采集一路信号,比如P3^3口,怎....

  [复制链接]
ID:792404 发表于 2020-8-25 11:35 | 显示全部楼层 |阅读模式
1118.JPG
回复

使用道具 举报

ID:792404 发表于 2020-8-25 11:37 | 显示全部楼层
最近测试了一下stc8G的ADC功能,想单独使用某一个口采集一路信号,比如P3^3口,怎样设置IO口?
回复

使用道具 举报

ID:548551 发表于 2020-8-25 12:12 | 显示全部楼层
这个要初始化程序;首先 要把IO口最优先级的设置为输入,且不开上拉.其次,就是配置ADC寄存器.比如说通道,你的是通道几就配置通道机,还有就是采样频率,等这些寄存器一定要配置好,因为这个配置一旦配置好就不能改变.最后就是写采集的程序了.程序的话就是采集中和采集后,初始化是采集前. 采集中就等待采集完成.采集完成以后把采集出来的值转换成我们需要的10进制,因为一般情况下采集出来的是2进制的值. 再最后我们利用这个只来做比较,比如低电压报警,或者利用这个值来调光,调速等一系列的.
回复

使用道具 举报

ID:280512 发表于 2020-8-25 13:03 | 显示全部楼层
包括这两个设置   P3M0=00000000; P3M1=00001000(高阻);ADC_CONTR=XXXX1101;
回复

使用道具 举报

ID:155507 发表于 2020-8-25 13:13 | 显示全部楼层
我给你来个程序试试

  1. #include "reg51.h"
  2. #include "intrins.h"

  3. //测试工作频率为11.0592MHz

  4. sfr     ADC_CONTR   =   0xbc;
  5. sfr     ADC_RES     =   0xbd;
  6. sfr     ADC_RESL    =   0xbe;
  7. sfr     ADCCFG      =   0xde;

  8. sbit    EADC        =   IE^5;

  9. sfr     P1M0        =   0x92;
  10. sfr     P1M1        =   0x91;
  11. sfr     P3M0        =   0xB2;
  12. sfr     P3M1        =   0xB1;

  13. void ADC_Isr() interrupt 5
  14. {
  15.         ADC_CONTR &= ~0x20;                         //清中断标志
  16.         P2 = ADC_RES;                               //读取ADC结果
  17.         ADC_CONTR |= 0x40;                          //继续AD转换
  18. }

  19. void main()
  20. {
  21.         P3M0 = 0x00;                                //设置P3.3为ADC口
  22.         P3M1 = 0x08;       
  23.         ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16
  24.         ADC_CONTR = 0x8B;                           //使能ADC模块
  25.         EADC = 1;                                   //使能ADC中断
  26.         EA = 1;
  27.         ADC_CONTR |= 0x40;                          //启动AD转换

  28.         while (1);
  29. }

复制代码
回复

使用道具 举报

ID:792404 发表于 2020-8-25 18:19 | 显示全部楼层
xqleft 发表于 2020-8-25 12:12
这个要初始化程序;首先 要把IO口最优先级的设置为输入,且不开上拉.其次,就是配置ADC寄存器.比如说通道,你的 ...

感谢师傅赐教!
回复

使用道具 举报

ID:792404 发表于 2020-8-25 18:32 | 显示全部楼层
angmall 发表于 2020-8-25 13:13
我给你来个程序试试

还是不行,P3^3口怎么修改都是显示00.00,我是用P3^3口采集5V信号显示在数码管上的。单片机用的是STC8G1K08的TSSOP20封装的,我把代码传上去,帮忙看一下是哪里出了问题。

  1. #include"STC8G.H"
  2. #include"intrins.h"
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit led=P3^3;
  6. uchar data dis_buf[4];//显示缓存
  7. uchar code ledduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
  8.                                          0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  9. uchar i;
  10. uint num;

  11. void delay_ms(uint z)
  12. {
  13.         uint x,y;
  14.         for(x=z;x>0;x--)
  15.                 for(y=1150;y>0;y--);
  16. }

  17. void datapros()         //数据处理函数
  18. {   
  19.          float tp;         
  20.          tp=num;
  21.          num=tp*1.0/255*500;   
  22.          dis_buf[3]=ledduan[num/1000];
  23.           dis_buf[2]=ledduan[num%1000/100] & 0x7f;
  24.          dis_buf[1]=ledduan[num%100/10];
  25.          dis_buf[0]=ledduan[num%10];

  26.          if((dis_buf[2]>=1)&&(dis_buf[2]<=2))         //设置显示范围内执行的功能
  27.            led=0;
  28.            else
  29.            led=1;
  30.                   
  31.         P1=0xff;               
  32.         P3&=0x0f;                        
  33.         P1=dis_buf[i];               
  34.         P3|=0x10<<i;               
  35.         i++;
  36.         i%=4;
  37. }
  38. void main()
  39. {
  40.         P1M0=0X00;
  41.         P1M1=0X00;
  42.         P3M0=0Xff;//强推挽
  43.         P3M1=0X00;
  44.         P5M0=0X00;
  45.         P5M1=0X00;

  46.         P3M0=0Xff;
  47.         P3M1=0X08; //P3^3为ADC口
  48.         P_SW2|=0x80;
  49.         ADCTIM=0x3f;
  50.         P_SW2&=0x7f;
  51.         ADCCFG=0x0f;
  52.         ADC_CONTR=0x80;
  53.         while(1)
  54.         {
  55.            ADC_CONTR|=0x40;
  56.            _nop_();
  57.            _nop_();
  58.            while(!(ADC_CONTR&0x20));
  59.            ADC_CONTR&=~0x20;
  60.            num=ADC_RES;

  61.            datapros();        
  62.            delay_ms(1);
  63.         }
  64. }
复制代码
回复

使用道具 举报

ID:792404 发表于 2020-8-25 18:33 | 显示全部楼层
青桑叶 发表于 2020-8-25 13:03
包括这两个设置   P3M0=00000000; P3M1=00001000(高阻);ADC_CONTR=XXXX1101;

我试一下,谢谢
回复

使用道具 举报

ID:155507 发表于 2020-8-25 20:35 | 显示全部楼层
给你改了一下试试。 对比一下就知道哪里错了。


  1. #include "STC8G.H"
  2. #include "intrins.h"
  3. #define uint  unsigned int
  4. #define uchar unsigned char

  5. sbit led=P3^2;  //用P3^3口采集5V信号
  6. uchar data dis_buf[4]; //显示缓存
  7. uchar code ledduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
  8.                           0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  9. uchar i;
  10. uint num;

  11. void delay_ms(uint z)
  12. {
  13.         uint x,y;
  14.         for(x=z;x>0;x--)
  15.             for(y=1150;y>0;y--);
  16. }

  17. void datapros()         //数据处理函数
  18. {   
  19.         float tp;         
  20.         tp=num;
  21.         num=tp*1.0/255*500;   
  22.         dis_buf[3]=ledduan[num/1000];
  23.         dis_buf[2]=ledduan[num%1000/100] & 0x7f;
  24.         dis_buf[1]=ledduan[num%100/10];
  25.         dis_buf[0]=ledduan[num%10];

  26.         if((dis_buf[2]>=1)&&(dis_buf[2]<=2))         //设置显示范围内执行的功能
  27.           led=0;
  28.         else
  29.           led=1;
  30.        
  31.         P1=0xff;               
  32.         P3&=0x07;                        
  33.         P1=dis_buf[i];               
  34.         P3|=0x10<<i;               
  35.         i++;
  36.         i%=4;
  37. }
  38. void main()
  39. {
  40.         P1M0=0X00;
  41.         P1M1=0X00;
  42.         //P3M0=0Xff;//强推挽
  43.         //P3M1=0X00;
  44.         P5M0=0X00;
  45.         P5M1=0X00;

  46.         P3M0=0Xf7;
  47.         P3M1=0X08; //P3^3为ADC口 (高阻)
  48.         P_SW2|=0x80;
  49.         ADCTIM=0x3f;
  50.         P_SW2&=0x7f;
  51.         ADCCFG=0x0f;   //设置ADC时钟为系统时钟/2/16
  52.         ADC_CONTR=0x8B; //P3^3为ADC口 ADC_CONTR=1XXX1011
  53.         while(1)
  54.         {
  55.                 ADC_CONTR |= 0x40;    //启动AD转换
  56.                 _nop_();
  57.                 _nop_();
  58.                 while(!(ADC_CONTR&0x20));
  59.                 ADC_CONTR&=~0x20;
  60.                 num=ADC_RES;

  61.                 datapros();        
  62.                 delay_ms(1);
  63.         }
  64. }

复制代码

评分

参与人数 1黑币 +12 收起 理由
YUANYUXING + 12 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:792404 发表于 2020-8-25 21:10 | 显示全部楼层
angmall 发表于 2020-8-25 20:35
给你改了一下试试。 对比一下就知道哪里错了。

一切正常了,原来是ADC控制寄存器配置错了, ADC_CONTR=0x8B; //P3^3为ADC口 ADC_CONTR=1XXX1011
难怪我怎么样改P3口配置就是不行。谢谢老大!
回复

使用道具 举报

ID:792404 发表于 2020-8-25 21:47 | 显示全部楼层
angmall 发表于 2020-8-25 20:35
给你改了一下试试。 对比一下就知道哪里错了。

一切正常了,原来是ADC控制寄存器配置错了,ADC_CONTR=0x8B; //P3^3为ADC口 ADC_CONTR=1XXX1011
难怪我怎么改P3口的配置就是不行。谢谢老大!
回复

使用道具 举报

ID:283954 发表于 2020-8-25 21:48 | 显示全部楼层
STC8G与STC12的AD不同之处在于有一个叫ADCTIM的寄存器,放在很远的地址,需要用DPTR才能赋值。

INITADC:
MOV P_SW2,#80H           ;访问X寄存器打开
MOV DPTR,#ADCTIM;        ;设置 ADC 内部时序 #0FEA8H 这是厂家的数值
MOV A,#3FH               ;必须通过A才能送到
MOVX @DPTR,A
MOV P_SW2,#00H           ;访问X寄存器关闭
MOV ADCCFG,#0FH          ;设置 ADC 时钟为系统时钟/2/XXXX 16=慢,8=快 B6决定结果的格式
;MOV ADC_CONTR,#10001111B ;使能 ADC 模块, #1000 CCCC B 通道暂定16  为内部参考电压1.91V
MOV ADC_CONTR,#10001101B ;使能 ADC 模块, #1000 CCCC B 通道13 X
;MOV ADC_CONTR,#10001100B ;使能 ADC 模块, #1000 CCCC B 通道12 Y
;MOV ADC_CONTR,#10001010B ;使能 ADC 模块, #1000 CCCC B 通道10 MIC
NOP
NOP
NOP
RET
回复

使用道具 举报

ID:280512 发表于 2020-8-26 08:14 | 显示全部楼层
转换出来的数据的对齐格式是:左对齐; 不能直接使用ADC_RES  的数据吧?
回复

使用道具 举报

ID:792404 发表于 2020-8-26 11:57 | 显示全部楼层
dalaoshi 发表于 2020-8-25 21:48
STC8G与STC12的AD不同之处在于有一个叫ADCTIM的寄存器,放在很远的地址,需要用DPTR才能赋值。

INITADC: ...

谢谢,已经解决了。
回复

使用道具 举报

ID:792404 发表于 2020-8-26 12:03 | 显示全部楼层
青桑叶 发表于 2020-8-26 08:14
转换出来的数据的对齐格式是:左对齐; 不能直接使用ADC_RES  的数据吧?

谢谢,已经解决了,可以直接使用ADC_RES的数据的。STC8G的手册上说的,这款是新上市的单片机,和之前的有些区别。
回复

使用道具 举报

ID:608872 发表于 2020-12-7 21:14 | 显示全部楼层
YUANYUXING 发表于 2020-8-25 21:10
一切正常了,原来是ADC控制寄存器配置错了, ADC_CONTR=0x8B; //P3^3为ADC口 ADC_CONTR=1XXX1011
难怪我 ...

就是把 ADC_CONTR=0x80  改为 ADC_CONTR=0x8B就可以正常显示电压了吗?我这几天也在看这款单片机。片内1.19V的LDO怎么用呢
回复

使用道具 举报

ID:608872 发表于 2021-1-6 22:05 | 显示全部楼层
青桑叶 发表于 2020-8-25 13:03
包括这两个设置   P3M0=00000000; P3M1=00001000(高阻);ADC_CONTR=XXXX1101;

使用两路做ADC,ADC_CONTR是不是要重复写两次,还是能更简单点呢
ADC_CONTR=XXXX1101;
ADC_CONTR=XXXX1110;

回复

使用道具 举报

ID:1112016 发表于 2024-4-25 17:19 | 显示全部楼层
angmall 发表于 2020-8-25 20:35
给你改了一下试试。 对比一下就知道哪里错了。

您好!请问在ADC程序里,能解释一下第24为什么是*500而不是1023呀?  num=tp*1.0/255*500;  
回复

使用道具 举报

ID:1112016 发表于 2024-4-25 17:20 | 显示全部楼层
angmall 发表于 2020-8-25 20:35
给你改了一下试试。 对比一下就知道哪里错了。

您好!请问在ADC程序里,能解释一下为什么是*500而不是1023呀?  num=tp*1.0/255*500;  
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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