找回密码
 立即注册
查看: 2145|回复: 24

ADC 疑惑求助

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2024-02-22 09:29:24

5

主题

51

回帖

285

积分

中级会员

积分
285
发表于 2024-1-13 16:29:54 | 显示全部楼层 |阅读模式
我参考的是例程  “利用ADC第15通道测量外部电压”


以下是ADC.C文件
-------------------------------------------------------------

-------------------------------------------------------------


int *BGV;                                       //内部1.19V参考信号源值存放在idata中
                                                //idata的EFH地址存放高字节
                                                //idata的F0H地址存放低字节
                                                //电压单位为毫伏(mV)

void ADC_Init()
{
    P_SW2 |= 0x80;
    ADCTIM = 0x3f;                              //设置ADC内部时序
    P_SW2 &= 0x7f;

    ADCCFG = 0x2f;                              //设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x8f;                           //使能ADC模块,并选择第15通道
}

int ADC_Read()
{
    int res;

    ADC_CONTR |= 0x40;                          //启动AD转换
    _nop_();
    _nop_();
    while (!(ADC_CONTR & 0x20));                //查询ADC完成标志
    ADC_CONTR &= ~0x20;                         //清完成标志
    res = (ADC_RES << 8) | ADC_RESL;            //读取ADC结果

    return res;
}


以下上main.c文件

-------------------------------------------------------------

-------------------------------------------------------------


void main ()
{
        int res;
        int vcc;
        int i;
       
        Io_Init();
        UartInit();
        ADC_Init();
       
       
        ES = 1;
  EA = 1;
        BGV = (int idata *)0xef;
       
         res = 0;
   for (i=0; i<8; i++)
   {
       res += ADC_Read();                       //读取8次数据
   }
   res >>= 3;                                  //取平均值

   vcc = (int)(1024L * *BGV / res);            //(10位ADC算法)计算VREF管脚电压,即电池电压

       
        while(1)
        {
//                UartSend(3);
                UartSend(vcc >> 8);                         //输出电压值到串口
    UartSend(vcc);
        }

}


我暂时想问的点是:
1、我的硬件电路上 是不是需要在 P1.0 脚外加测试电压
2、程序会在 ADC_Init();这个函数中的 (  while (!(ADC_CONTR & 0x20));    //查询ADC完成标志   )卡死。这是不是意味着我为正确打开 ADC检测


ADC 部分实在是有点难理解 ,目前觉得有电混乱 ,自己大概知道如何配置以及开启,但是实际跑不起来,暂时也不清楚是硬件未正确连接还是程序编写错误,所以恳请各位大佬指点迷津,传授经验。


微信图片_20240113162924.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-03-09 19:40:01

9

主题

328

回帖

4501

积分

荣誉版主

积分
4501
发表于 2024-1-14 17:40:44 | 显示全部楼层
你读取的是内部1.19V参考电压(通道15),与外电路连接方式无关。如你需要读取P1.0引脚上的电压,则需要选择通道0。
你的程序似乎和手册上的程序是一致的,试试手册上的程序能不能正常运行。
回复 支持 反对

使用道具 举报 送花

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

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-1-14 22:56:53 | 显示全部楼层
读15通道计算VCC电压不需要外部硬件配合,直接读取就可以计算了。
另外,ADC初始化后至少要延时1ms让模拟电路稳定后,才能进行ADC转换。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2024-02-22 09:29:24

5

主题

51

回帖

285

积分

中级会员

积分
285
发表于 2024-1-15 17:12:59 | 显示全部楼层
void main(void)
{
        // 初始化
         int res;
   int vcc;
   int i;
       
        Io_Init();
  BGV = (int idata *)0xef;
  ADCInit();                                  //ADC初始化
  UartInit();                                 //串口初始化

  ES = 1;
  EA = 1;

  res = 0;
  for (i=0; i<8; i++)
  {
     res += ADCRead();                       //读取8次数据
   }
   res >>= 3;                                  //取平均值

    vcc = (int)(1024L * *BGV / res);            //(10位ADC算法)计算VREF管脚电压,即电池电压
//  vcc = (int)(4096L * *BGV / res);            //(12位ADC算法)计算VREF管脚电压,即电池电压
                                                //注意,此电压的单位为毫伏(mV)
//    UartSend(vcc >> 8);                         //输出电压值到串口
//    UartSend(vcc);

         Delay10ms();
    while (1)
                {
                        UartSend(vcc >> 8);                         //输出电压值到串口
                        UartSend(vcc);
                        Delay500ms();
               
                }
}


这是做了一点小修改 然后再串口得到了下面的数据,这数据是不是不太正确的?
读15通道计算VCC电压不需要外部硬件配合,直接读取就可以计算了。
另外,ADC初始化后至少要延时1ms让模拟电路稳定后,才能进行ADC转换。
微信图片_20240115170955.png
回复 支持 反对

使用道具 举报 送花

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-1-16 09:23:27 | 显示全部楼层
1381=> 4993 mV  你是5V供电么
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2024-02-22 09:29:24

5

主题

51

回帖

285

积分

中级会员

积分
285
发表于 2024-1-16 09:54:47 | 显示全部楼层
_奶*** 发表于 2024-1-16 09:23
1381=> 4993 mV  你是5V供电么

是   读取的15通道的值
回复 支持 反对

使用道具 举报 送花

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-1-16 10:07:01 | 显示全部楼层
那还有有什么问题啊0.0
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2024-02-22 09:29:24

5

主题

51

回帖

285

积分

中级会员

积分
285
发表于 2024-1-16 11:31:21 | 显示全部楼层
_奶*** 发表于 2024-1-16 10:07
那还有有什么问题啊0.0

首先 我对  1381 这个值有疑惑,因为如果是ADC采集到的值,那么应该是不超过2^10,如果是电压值,那么不应该是 5 左右的一个值吗??

还有一点比较疑惑的是计算公式  vcc = (int)(1024L * *BGV / res);  
按照我对手册的理解 他不应该是 vcc = (int)(*BGV / 1024L * res); 吗??

这是我感到困惑的点 很期待你的解答

点评

你的计算是错误的,并且明显错误。 BGV是ADC输入电压,参考电压是VCC,RES是ADC值,10位ADC,则 RES = 1024*BGV/VCC,所以推导出 VCC = 1024*BGV/RES? 还有疑问吗?  详情 回复 发表于 2024-1-18 21:49
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-05-02 07:32:37

21

主题

564

回帖

2678

积分

金牌会员

积分
2678
发表于 2024-1-16 13:11:24 | 显示全部楼层
Hons*** 发表于 2024-1-16 11:31
首先 我对  1381 这个值有疑惑,因为如果是ADC采集到的值,那么应该是不超过2^10,如果是电压值,那么不 ...

主控是啥型号,会不会是12位ADC
回复 支持 反对

使用道具 举报 送花

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

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-1-16 13:32:27 | 显示全部楼层
Hons*** 发表于 2024-1-16 11:31
首先 我对  1381 这个值有疑惑,因为如果是ADC采集到的值,那么应该是不超过2^10,如果是电压值,那么不 ...

你可以输出一下ADC寄存器的值,,你打印的这个vcc是计算之后的参考电压值
还有你这个是什么单片机 10位AD么
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-3 03:19 , Processed in 0.127820 second(s), 113 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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