找回密码
 立即注册
楼主: Lkck8210

ADC 读不到电压 | 已解决

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-5-24 15:47:03 | 显示全部楼层

那就是你通道切换的时候需要把后四位先清零再赋值。。大概就是这样

ADC_CONTR = (ADC_CONTR & 0xf0) | ADC_START | channel;
1 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-5-24 16:03:00 | 显示全部楼层
_奶*** 发表于 2024-5-24 15:47
那就是你通道切换的时候需要把后四位先清零再赋值。。大概就是这样

ADC_CONTR = (ADC_CONTR & 0xf0) |  ...

行了~!!
感谢解答
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-5-24 16:11:34 | 显示全部楼层
以下是修改好的代码
  1. #include "reg51.h"
  2. #include "intrins.h"
  3. #include <stdio.h>//printf, sprintf
  4. #include <intrins.h>//_nop_, _cror_, _crol_
  5. typedef         unsigned char        u8;  //0 to 255
  6. typedef         unsigned int        u16;  //0 to 65535
  7. typedef         unsigned long        u32;  //0 to 4294967295
  8. //测试工作频率为11.0592MHz
  9. sfr         AUXR        =           0x8e;
  10. sfr     ADC_CONTR   =   0xbc;
  11. sfr     ADC_RES     =   0xbd;
  12. sfr     ADC_RESL    =   0xbe;
  13. sfr     ADCCFG      =   0xde;
  14. sfr P3M0        =   0xb2;                                       //P3口配置寄存器0
  15. sfr P3M1        =   0xb1;                                       //P3口配置寄存器1
  16. sfr P5M0        =   0xca;                                       //P5口配置寄存器0
  17. sfr P5M1        =   0xc9;                                       //P5口配置寄存器1
  18. bit Busy = 0;
  19. void Uart1_Isr(void) interrupt 4
  20. {
  21.     if (TI)                                //检测串口1发送中断
  22.     {
  23.         TI = 0;                        //清除串口1发送中断请求位
  24.         Busy = 0;
  25.     }
  26.     if (RI)                                //检测串口1接收中断
  27.     {
  28.         RI = 0;                        //清除串口1接收中断请求位
  29.     }
  30. }
  31. u8 putchar(u8 dat)
  32. {
  33.     Busy = 1;
  34.     SBUF = dat;
  35.     while(Busy);
  36.     return dat;
  37. }
  38. void Uart1_Init(void)        //115200bps@11.0592MHz
  39. {
  40.     SCON = 0x50;                //8位数据,可变波特率
  41.     AUXR |= 0x40;                //定时器时钟1T模式
  42.     AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  43.     TMOD &= 0x0F;                //设置定时器模式
  44.     TL1 = 0xE8;                        //设置定时初始值
  45.     TH1 = 0xFF;                        //设置定时初始值
  46.     ET1 = 0;                        //禁止定时器中断
  47.     TR1 = 1;                        //定时器1开始计时
  48.     ES = 1;                                //使能串口1中断
  49. }
  50. void Delay1000ms(void)        //@11.0592MHz
  51. {
  52.     unsigned char data i, j, k;
  53.     i = 17;
  54.     j = 27;
  55.     k = 112;
  56.     do
  57.     {
  58.         do
  59.         {
  60.             while (--k);
  61.         }
  62.         while (--j);
  63.     }
  64.     while (--i);
  65. }
  66. void Delay1ms(void)        //@11.0592MHz
  67. {
  68.     unsigned char data i, j;
  69.     i = 15;
  70.     j = 90;
  71.     do
  72.     {
  73.         while (--j);
  74.     }
  75.     while (--i);
  76. }
  77. u16 ADC_Sel(u8 ch)
  78. {
  79.     u16 Temp;
  80.     ADC_CONTR |= 0x40 | ch;                      //启动AD转换
  81.     _nop_();
  82.     _nop_();
  83.     while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
  84.     ADC_CONTR &= ~0x2F;                     //清完成标志及频道选择
  85.     Temp = ADC_RES;                           //读取ADC结果
  86.     Temp = Temp<<8 | ADC_RESL;
  87.     return Temp;
  88. }
  89. u16 Temp;
  90. u16 Cnt = 0;
  91. void main()
  92. {
  93.     P3M0 = 0x00;
  94.     P3M1 = 0x0c;
  95.     P5M0 = 0x00;
  96.     P5M1 = 0x10;
  97.     ADCCFG = 0x2f;                              //设置ADC时钟为系统时钟/2/16/16
  98.     Uart1_Init();
  99.     EA=1;
  100.     ADC_CONTR = 0x82;                           //使能ADC模块
  101.     Delay1ms();
  102.     while (1)
  103.     {
  104.         Cnt++;
  105.         printf("ADC Test: %u\r\n",Cnt);
  106.         Delay1ms();
  107.         Temp = ADC_Sel(2);
  108.         printf("P32 Raw: %u\r\n",Temp);
  109.         printf("P32 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  110.         Delay1ms();
  111.         Temp = ADC_Sel(3);
  112.         printf("P33 Raw: %u\r\n",Temp);
  113.         printf("P33 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  114.         Delay1ms();
  115.         Temp = ADC_Sel(4);
  116.         printf("P54 Raw: %u\r\n",Temp);
  117.         printf("P54 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  118.         Delay1000ms();
  119.     }
  120. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-5-24 16:19:44 | 显示全部楼层
Lkck*** 发表于 2024-5-24 16:11
以下是修改好的代码

参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-5-24 17:04:03 | 显示全部楼层

什么然后呢?   你要问什么?  能不能多打几个字啊?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-5-24 17:23:26 | 显示全部楼层
梁*** 发表于 2024-5-24 17:04
什么然后呢?   你要问什么?  能不能多打几个字啊?

我要问的就是贴子的标题和1楼的内容
但梁工你只是贴一个例程注释
然后附上一个附件
你甚至连一个字都没打
2024-05-24_172258.png


点评

你1楼说的:ADC读不到电压。 于是,我贴了我的程序,我拷贝程序里的详细说明,那也是我编程时一个一个字打上去的,难道我还要再一个一个字再打一遍么?拷贝不是更快? 你说ADC读不到电压,我专门发了8脚的程序让你测  详情 回复 发表于 2024-5-24 18:36
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2025-05-02 08:15:40
已绑定手机

13

主题

1257

回帖

2975

积分

金牌会员

积分
2975
发表于 2024-5-24 17:45:11 | 显示全部楼层
本帖最后由 21cnsound 于 2024-5-24 18:00 编辑
Lkck*** 发表于 2024-5-24 16:11
以下是修改好的代码

看了下,其实就是改了清完成标志及频道选择,把~0x20改成了~0x2F,而~0x20更为合理吧,把通道号指向内部通道,主要是修改这个不影响测试结果吧
ADC_CONTR &= ~0x2F;                     //清完成标志及频道选择
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-5-24 18:36:58 | 显示全部楼层
Lkck*** 发表于 2024-5-24 17:23
我要问的就是贴子的标题和1楼的内容
但梁工你只是贴一个例程注释
然后附上一个附件

你1楼说的:ADC读不到电压。
于是,我贴了我的程序,我拷贝程序里的详细说明,那也是我编程时一个一个字打上去的,难道我还要再一个一个字再打一遍么?拷贝不是更快?
你说ADC读不到电压,我专门发了8脚的程序让你测试下,好像你只测了ADC15计算VCC的程序,并且正常了,你贴了一个图,没有任何说明,就发了一个“然后呢?” 我就不明白你要表达什么。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-5-24 23:27:08 | 显示全部楼层
21cns*** 发表于 2024-5-24 17:45
看了下,其实就是改了清完成标志及频道选择,把~0x20改成了~0x2F,而~0x20更为合理吧,把通道号指向内部通 ...

对,这样写好像有问题
我会再更新一下代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:294
  • 最近打卡:2025-03-06 09:25:41

8

主题

318

回帖

1835

积分

金牌会员

积分
1835
发表于 2024-5-24 23:28:32 | 显示全部楼层
最终版本
  1. #include "reg51.h"
  2. #include "intrins.h"
  3. #include <stdio.h>//printf, sprintf
  4. #include <intrins.h>//_nop_, _cror_, _crol_
  5. typedef         unsigned char        u8;  //0 to 255
  6. typedef         unsigned int        u16;  //0 to 65535
  7. typedef         unsigned long        u32;  //0 to 4294967295
  8. //测试工作频率为11.0592MHz
  9. sfr         AUXR        =           0x8e;
  10. sfr     ADC_CONTR   =   0xbc;
  11. sfr     ADC_RES     =   0xbd;
  12. sfr     ADC_RESL    =   0xbe;
  13. sfr     ADCCFG      =   0xde;
  14. sfr P3M0        =   0xb2;                                       //P3口配置寄存器0
  15. sfr P3M1        =   0xb1;                                       //P3口配置寄存器1
  16. sfr P5M0        =   0xca;                                       //P5口配置寄存器0
  17. sfr P5M1        =   0xc9;                                       //P5口配置寄存器1
  18. bit Busy = 0;
  19. void Uart1_Isr(void) interrupt 4
  20. {
  21.     if (TI)                                //检测串口1发送中断
  22.     {
  23.         TI = 0;                        //清除串口1发送中断请求位
  24.         Busy = 0;
  25.     }
  26.     if (RI)                                //检测串口1接收中断
  27.     {
  28.         RI = 0;                        //清除串口1接收中断请求位
  29.     }
  30. }
  31. u8 putchar(u8 dat)
  32. {
  33.     Busy = 1;
  34.     SBUF = dat;
  35.     while(Busy);
  36.     return dat;
  37. }
  38. void Uart1_Init(void)        //115200bps@11.0592MHz
  39. {
  40.     SCON = 0x50;                //8位数据,可变波特率
  41.     AUXR |= 0x40;                //定时器时钟1T模式
  42.     AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  43.     TMOD &= 0x0F;                //设置定时器模式
  44.     TL1 = 0xE8;                        //设置定时初始值
  45.     TH1 = 0xFF;                        //设置定时初始值
  46.     ET1 = 0;                        //禁止定时器中断
  47.     TR1 = 1;                        //定时器1开始计时
  48.     ES = 1;                                //使能串口1中断
  49. }
  50. void Delay1000ms(void)        //@11.0592MHz
  51. {
  52.     unsigned char data i, j, k;
  53.     i = 17;
  54.     j = 27;
  55.     k = 112;
  56.     do
  57.     {
  58.         do
  59.         {
  60.             while (--k);
  61.         }
  62.         while (--j);
  63.     }
  64.     while (--i);
  65. }
  66. void Delay1ms(void)        //@11.0592MHz
  67. {
  68.     unsigned char data i, j;
  69.     i = 15;
  70.     j = 90;
  71.     do
  72.     {
  73.         while (--j);
  74.     }
  75.     while (--i);
  76. }
  77. u16 ADC_Sel(u8 ch)
  78. {
  79.     u16 Temp;
  80.         ADC_CONTR &= 0xF0;
  81.     ADC_CONTR |= 0x40 | ch;                      //启动AD转换
  82.     _nop_();
  83.     _nop_();
  84.     while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
  85.     ADC_CONTR &= ~0x20;                     //清完成标志
  86.     Temp = ADC_RES;                           //读取ADC结果
  87.     Temp = Temp<<8 | ADC_RESL;
  88.     return Temp;
  89. }
  90. u16 Temp;
  91. u16 Cnt = 0;
  92. void main()
  93. {
  94.     P3M0 = 0x00;
  95.     P3M1 = 0x0c;
  96.     P5M0 = 0x00;
  97.     P5M1 = 0x10;
  98.     ADCCFG = 0x2f;                              //设置ADC时钟为系统时钟/2/16/16
  99.     Uart1_Init();
  100.     EA=1;
  101.     ADC_CONTR = 0x82;                           //使能ADC模块
  102.     Delay1ms();
  103.     while (1)
  104.     {
  105.         Cnt++;
  106.         printf("ADC Test: %u\r\n",Cnt);
  107.         Delay1ms();
  108.         Temp = ADC_Sel(2);
  109.         printf("P32 Raw: %u\r\n",Temp);
  110.         printf("P32 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  111.         Delay1ms();
  112.         Temp = ADC_Sel(3);
  113.         printf("P33 Raw: %u\r\n",Temp);
  114.         printf("P33 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  115.         Delay1ms();
  116.         Temp = ADC_Sel(4);
  117.         printf("P54 Raw: %u\r\n",Temp);
  118.         printf("P54 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
  119.         Delay1000ms();
  120.     }
  121. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 15:45 , Processed in 0.204577 second(s), 109 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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