找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9361|回复: 11
打印 上一主题 下一主题
收起左侧

关于15系列单片机AD采样电压的问题,想测量电池剩余电压

[复制链接]
跳转到指定楼层
楼主
ID:122751 发表于 2018-8-21 23:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AD采样的程序本人已经弄好,想测量电池剩余电压,但是15系列单片机上电后P1口的io普遍都有4v以上的电压,而恰恰ad采样口就在p1口的io上,那我怎么才能消除原有io上的电压,用来测量电池电压,不然总是在测量io口上原本的电压
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:386381 发表于 2018-8-22 00:33 来自手机 | 只看该作者
这个好办呀,在P1口接下拉电阻P1口的电压不就没了吗,因为P1口那个电流很小的,是上拉电阻过来的,接个下拉电阻就把它给放掉了,电池电压没影响的

评分

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

查看全部评分

回复

使用道具 举报

板凳
ID:213173 发表于 2018-8-22 06:36 | 只看该作者
沙发的建议是错误的。有很多型号的STC15系列单片机内置有ADC功能,只要把其P1相应端口特殊功能寄存器初始化时设置为高阻即可。
以P1.0设置高阻为例:
        P1M1 = 0x01; //设置P1.0高阻:0000 0001
        P1M0 = 0x00;//设置P1.0高阻 :0000 0000
        P1ASF= 0x01;//设置P1的0通道端口作为模拟输入
回复

使用道具 举报

地板
ID:164602 发表于 2018-8-22 08:58 | 只看该作者
你想多了!
第一:你要测量的电源与单片机共地。
第二:设置好AD转换通道,设置寄存器如图所示:

其它设置,去看手册。STC15的手册可以从STC官网下载http://www.stcmcu.com/,手册中还有例子。
第三:开启AD转换,单片机会自动从你设置的AD转换口,读取数据进行转换。

例如我的一个小程序(部分)
void ADCInit (void)//ADC设置
{
        P1ASF=0x03;//P10、P11为ADC输入口。手册P878
        CLK_DIV=0x20;//ADC转换结果存放方式。手册P880
}


void ADC0 (void)//第一路AD转换函数
{
        ADC_CONTR=0xe8;//开ADC电源、速度最快、开始转换、P10口。手册P879
        while (!(ADC_CONTR&0x10));//如果转换没结束,则等待
        ADC_CONTR=0x00;//关ADC电源、清转换完毕标志
        ADCdate=ADC_RES;//ADC转换数据高两位。手册P880
        ADCdate=(ADCdate<<8);
        ADCdate=(ADCdate|ADC_RESL);//合并10位转换数据
        ADCXX();
}


我测过一节、两节干电池的电压。
注意:我不是高手,这样做可能从电路来说是很粗暴的——仅仅是做了程序方面的试验。
欢迎指正
回复

使用道具 举报

5#
ID:155507 发表于 2018-8-22 09:02 | 只看该作者
你可以运用这个程序
读ADC内部基准计算MCU的工作电压, 不需要增加任何硬件零件.


  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited ----------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.GXWMCU.com --------------------------------------------*/
  8. /* --- QQ:  800003751 -------------------------------------------------*/
  9. /* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
  10. /*---------------------------------------------------------------------*/


  11. /*************        本程序功能说明        **************

  12. 读ADC内部基准计算MCU的工作电压, 不需要增加任何硬件零件.

  13. 用STC的MCU的IO方式控制74HC595驱动8位数码管。

  14. 用户可以修改宏来选择时钟频率.

  15. 用户可以在"用户定义宏"中选择共阴或共阳. 推荐尽量使用共阴数码管.

  16. 使用Timer0的16位自动重装来产生1ms节拍,程序运行于这个节拍下, 用户修改MCU主时钟频率时,自动定时于1ms.

  17. 右边4位数码管显示MCU的工作电压值值.


  18. ******************************************/

  19. #define MAIN_Fosc                22118400L        //定义主时钟

  20. #include        "STC15Fxxxx.H"


  21. /***********************************************************/

  22. #define DIS_DOT                0x20
  23. #define DIS_BLACK        0x10
  24. #define DIS_                0x11

  25. #define P1n_pure_input(bitn)                P1M1 |=  (bitn),        P1M0 &= ~(bitn)

  26. /****************************** 用户定义宏 ***********************************/

  27. #define                LED_TYPE        0x00                //定义LED类型, 0x00--共阴, 0xff--共阳

  28. #define        Timer0_Reload        (65536UL -(MAIN_Fosc / 1000))                //Timer 0 中断频率, 1000次/秒

  29. /*****************************************************************************/






  30. /*************        本地常量声明        **************/
  31. u8 code t_display[]={                                                //标准字库
  32. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  33.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  34. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  35.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
  36.         0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};        //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

  37. u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};                //位码


  38. /*************        IO口定义        **************/
  39. sbit        P_HC595_SER   = P4^0;        //pin 14        SER                data input
  40. sbit        P_HC595_RCLK  = P5^4;        //pin 12        RCLk        store (latch) clock
  41. sbit        P_HC595_SRCLK = P4^3;        //pin 11        SRCLK        Shift data clock


  42. /*************        本地变量声明        **************/

  43. u8         LED8[8];                //显示缓冲
  44. u8        display_index;        //显示位索引
  45. bit        B_1ms;                //1ms标志

  46. u8        msecond;

  47. u16        Get_ADC10bitResult(u8 channel);        //channel = 0~7




  48. /**********************************************/
  49. void main(void)
  50. {
  51.         u8        i;
  52.         u16        j;

  53.         P0M1 = 0;        P0M0 = 0;        //设置为准双向口
  54.         P1M1 = 0;        P1M0 = 0;        //设置为准双向口
  55.         P2M1 = 0;        P2M0 = 0;        //设置为准双向口
  56.         P3M1 = 0;        P3M0 = 0;        //设置为准双向口
  57.         P4M1 = 0;        P4M0 = 0;        //设置为准双向口
  58.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  59.         P6M1 = 0;        P6M0 = 0;        //设置为准双向口
  60.         P7M1 = 0;        P7M0 = 0;        //设置为准双向口
  61.        
  62.         display_index = 0;
  63.         P1ASF = 0;        //对内部基准做ADC
  64.         ADC_CONTR = 0xE0;                        //90T, ADC power on
  65.        
  66.         AUXR = 0x80;        //Timer0 set as 1T, 16 bits timer auto-reload,
  67.         TH0 = (u8)(Timer0_Reload / 256);
  68.         TL0 = (u8)(Timer0_Reload % 256);
  69.         ET0 = 1;        //Timer0 interrupt enable
  70.         TR0 = 1;        //Tiner0 run
  71.         EA = 1;                //打开总中断
  72.        
  73.         for(i=0; i<8; i++)        LED8[i] = 0x10;        //上电消隐

  74.        
  75.         while(1)
  76.         {
  77.                 if(B_1ms)        //1ms到
  78.                 {
  79.                         B_1ms = 0;
  80.                         if(++msecond >= 200)        //200ms到
  81.                         {
  82.                                 msecond = 0;

  83.                                 for(j=0,i=0; i<16; i++)                j += Get_ADC10bitResult(0);        //读内部基准ADC, P1ASF=0, 读0通道
  84.                                 j = (u32)128000UL*16 / j;        // ADC = 1024 * Uref / Ux, 则 Ux = 1024 * Uref / ADC = 1024 * 1.25 / ADC = 1280 / ADC

  85.                                 LED8[5] = j / 100 + DIS_DOT;        //显示MCU电压值, 计算时放大了100倍, 电压有两位小数.
  86.                                 LED8[6] = (j % 100) / 10;
  87.                                 LED8[7] = j % 10;
  88.                         }
  89.                 }
  90.         }
  91. }
  92. /**********************************************/

  93. //========================================================================
  94. // 函数: u16        Get_ADC10bitResult(u8 channel)
  95. // 描述: 查询法读一次ADC结果.
  96. // 参数: channel: 选择要转换的ADC.
  97. // 返回: 10位ADC结果.
  98. // 版本: V1.0, 2012-10-22
  99. //========================================================================
  100. u16        Get_ADC10bitResult(u8 channel)        //channel = 0~7
  101. {
  102.         ADC_RES = 0;
  103.         ADC_RESL = 0;

  104.         ADC_CONTR = (ADC_CONTR & 0xe0) | 0x08 | channel;         //start the ADC
  105.         NOP(4);

  106.         while((ADC_CONTR & 0x10) == 0)        ;        //wait for ADC finish
  107.         ADC_CONTR &= ~0x10;                //清除ADC结束标志
  108.         return        (((u16)ADC_RES << 2) | (ADC_RESL & 3));
  109. }



  110. /**************** 向HC595发送一个字节函数 ******************/
  111. void Send_595(u8 dat)
  112. {               
  113.         u8        i;
  114.         for(i=0; i<8; i++)
  115.         {
  116.                 dat <<= 1;
  117.                 P_HC595_SER   = CY;
  118.                 P_HC595_SRCLK = 1;
  119.                 P_HC595_SRCLK = 0;
  120.         }
  121. }

  122. /********************** 显示扫描函数 ************************/
  123. void DisplayScan(void)
  124. {       
  125.         Send_595(~LED_TYPE ^ T_COM[display_index]);                        //输出位码
  126.         Send_595( LED_TYPE ^ t_display[LED8[display_index]]);        //输出段码

  127.         P_HC595_RCLK = 1;
  128.         P_HC595_RCLK = 0;                                                        //锁存输出数据
  129.         if(++display_index >= 8)        display_index = 0;        //8位结束回0
  130. }


  131. /********************** Timer0 1ms中断函数 ************************/
  132. void timer0 (void) interrupt TIMER0_VECTOR
  133. {
  134.         DisplayScan();        //1ms扫描显示一位
  135.         B_1ms = 1;                //1ms标志
  136. }


复制代码


STC15Fxxxx.zip

8.73 KB, 下载次数: 29

回复

使用道具 举报

6#
ID:65956 发表于 2018-8-22 11:26 | 只看该作者
可能是你现在的IO口是悬空状态吧,在所在测的IO口上加上加一个下拉10-100K的电阻就行了,如果要测试电池电压,建议还是用分压电阻方案测试稳当点,我自己现在用的是10K+90K方案,测试正常,考虑到只有10位AD,精度并不是很好
回复

使用道具 举报

7#
ID:122751 发表于 2018-8-22 13:01 | 只看该作者
angmall 发表于 2018-8-22 09:02
你可以运用这个程序
读ADC内部基准计算MCU的工作电压, 不需要增加任何硬件零件.

并不是读取单片机的工作电压,我是想通过io口的ad采样功能测量18650电池电量
回复

使用道具 举报

8#
ID:122751 发表于 2018-8-22 13:02 | 只看该作者
wulin 发表于 2018-8-22 06:36
沙发的建议是错误的。有很多型号的STC15系列单片机内置有ADC功能,只要把其P1相应端口特殊功能寄存器初始化 ...

但是情况是我设置了高阻态,设置为ad采样的io还是有电压
回复

使用道具 举报

9#
ID:122751 发表于 2018-8-22 13:14 | 只看该作者
aking991 发表于 2018-8-22 11:26
可能是你现在的IO口是悬空状态吧,在所在测的IO口上加上加一个下拉10-100K的电阻就行了,如果要测试电池电 ...

是悬空状态用万用表测量有电压,我就是想测量电池电压,怕ad采样io口原来的电压会影响测量的数据,我不知道该怎么样测量,还有所说的分压电阻方案,是ad采样io接上10k+90k的电阻,然后接地,电阻中间引线出来接待测的的电池正极是吗
回复

使用道具 举报

10#
ID:122751 发表于 2018-8-22 13:26 | 只看该作者
HC6800-ES-V2.0 发表于 2018-8-22 08:58
你想多了!
第一:你要测量的电源与单片机共地。
第二:设置好AD转换通道,设置寄存器如图所示:

学习了
回复

使用道具 举报

11#
ID:213173 发表于 2018-8-22 15:42 | 只看该作者
18277067187 发表于 2018-8-22 13:02
但是情况是我设置了高阻态,设置为ad采样的io还是有电压

由于是高阻态,此端口悬空时测到的电压不必理会,不影响对外电路电压的测量精度。我用STC15W404AS设计的产品从来没有发生你担心问题。
回复

使用道具 举报

12#
ID:388947 发表于 2018-8-22 16:04 | 只看该作者
楼下说的有道理
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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