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

ADC 疑惑求助

[复制链接]
  • TA的每日心情
    慵懒
    2024-2-22 09:29
  • 签到天数: 38 天

    [LV.5]常住居民I

    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
    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-6-10 08:59
  • 签到天数: 181 天

    [LV.7]常住居民III

    9

    主题

    310

    回帖

    3859

    积分

    荣誉版主

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

    使用道具 举报

    该用户从未签到

    46

    主题

    3189

    回帖

    7211

    积分

    超级版主

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

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-2-22 09:29
  • 签到天数: 38 天

    [LV.5]常住居民I

    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
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    1 小时前
  • 签到天数: 171 天

    [LV.7]常住居民III

    21

    主题

    1255

    回帖

    3063

    积分

    论坛元老

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

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-2-22 09:29
  • 签到天数: 38 天

    [LV.5]常住居民I

    5

    主题

    51

    回帖

    285

    积分

    中级会员

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

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

    使用道具 举报

  • TA的每日心情
    无聊
    1 小时前
  • 签到天数: 171 天

    [LV.7]常住居民III

    21

    主题

    1255

    回帖

    3063

    积分

    论坛元老

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

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-2-22 09:29
  • 签到天数: 38 天

    [LV.5]常住居民I

    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
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 08:15
  • 签到天数: 204 天

    [LV.7]常住居民III

    12

    主题

    358

    回帖

    1296

    积分

    金牌会员

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

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

    使用道具 举报

  • TA的每日心情
    无聊
    1 小时前
  • 签到天数: 171 天

    [LV.7]常住居民III

    21

    主题

    1255

    回帖

    3063

    积分

    论坛元老

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

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

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-6-18 08:45 , Processed in 0.074707 second(s), 72 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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