搜索
bottom↓
回复: 2

DS2438测量电压是比较接近,但电流和剩余容量不准

[复制链接]

出0入0汤圆

发表于 2015-6-13 13:29:38 | 显示全部楼层 |阅读模式
本帖最后由 love萍萍 于 2015-6-12 23:15 编辑

利用MSP430F5438A和DS2438做一电池监测电路,电路如下图所示:

图中VCC是用MSP430板子的3.3V供电.
数据能够读出,电压基本上准的,但是测量电池电流的时候测出来是4.99A,电池容量是0.0。明显不对了,请问是哪的问题是我硬件有问题吗?
下面是我参考网上例程改写的程序

  1. ds2438.h
  2. #ifndef _DS2438_H_
  3. #define _DS2438_H_

  4. #define CPU_F           ((double)8000000)
  5. #define delay_us(x)     __delay_cycles((long)(CPU_F*(double)x/1000000.0))
  6. #define delay_ms(x)     __delay_cycles((long)(CPU_F*(double)x/1000.0))

  7. #define SKIP_ROM  0xCC                   //跳过ROM选择步骤
  8. #define CONVERT_V  0xB4                   //启用电压转换功能
  9. #define RECALL   0xB8                        //重调EEPROM
  10. #define READ_SP  0xBE                        //读暂存器
  11. #define WRITE_SP  0x4E                        //写暂存器
  12. #define COPY_SP   0x48                        //复制暂存器

  13. #define        DQ_PxDIR                        P5DIR
  14. #define        DQ_PxIN                                P5IN
  15. #define        DQ_PxOUT                        P5OUT
  16. #define        DQ                                        BIT5                                       
  17. //高低电平定义
  18. #define        DQ_IN()                                DQ_PxDIR         &=         ~DQ
  19. #define        DQ_OUT()                        DQ_PxDIR        |=        DQ
  20. #define        DQ_OUTH()                        DQ_PxOUT |= DQ
  21. #define        DQ_OUTL()                        DQ_PxOUT &= ~DQ
  22. #define DQ_IN_HL()          DQ_PxIN & DQ

  23. #define  R    0.050

  24. void OWWritebit(unsigned char bit);
  25. unsigned char OWReadbit(void);
  26. void OWWriteByte(unsigned char data);
  27. unsigned char OWReadByte(void);
  28. unsigned char OWReset(void);
  29. void initcommand(void);
  30. float Read_Current(void);
  31. float Read_Temperature(void);
  32. float Read_Voltage(void);
  33. float Read_ICAcurrent(void);
  34. float Read_CCAcurrent(void);
  35. float Read_DCAcurrent(void);

  36. #endif
  37. //ds2438.c
  38. #include "msp430f5438a.h"
  39. #include "math.h"
  40. #include "ds2438.h"
  41. void OWWritebit(unsigned char bit)
  42. {
  43.     if(bit)
  44.     {//write bit 1
  45.         DQ_OUTL();
  46.         delay_us(6);
  47.         DQ_OUTH();
  48.         delay_us(64);
  49.     }   
  50.     else
  51.     {//write bit 0
  52.         DQ_OUTL();
  53.         delay_us(60);
  54.         DQ_OUTH();
  55.         delay_us(10);
  56.     }
  57. }
  58. unsigned char OWReadbit(void)
  59. {
  60.     unsigned char result;
  61.     DQ_OUTL();
  62.     delay_us(6);
  63.     DQ_OUTH();
  64.     DQ_IN();
  65.         delay_us(9);  
  66.         result= DQ_PxIN & DQ;
  67.     delay_us(55);
  68.       
  69.     return result;
  70. }
  71. void OWWriteByte(unsigned char data)
  72. {
  73.     unsigned char loop,i;
  74.     DQ_OUT();
  75.     for(loop=0;loop<8;loop++)
  76.     {
  77.         
  78.         i=data&0x01;
  79.         if(i)
  80.         {
  81.             DQ_OUTL();
  82.             delay_us(6);
  83.             DQ_OUTH();
  84.             delay_us(64);            
  85.         }
  86.         else
  87.         {
  88.             DQ_OUTL();
  89.             delay_us(60);
  90.             DQ_OUTH();
  91.             delay_us(10);
  92.         }
  93.         data=data>>1;
  94.     }
  95. }
  96. unsigned char OWReadByte(void)
  97. {
  98.     unsigned char count, temp;
  99.     unsigned char result=0;
  100.     for(count=0;count<8;count++)
  101.     {
  102.         // shift the result to get it ready for the next bit
  103.         DQ_OUT();
  104.         DQ_OUTL();
  105.         delay_us(6);
  106.         DQ_OUTH();
  107.                 DQ_IN();
  108.         delay_us(9);
  109.         
  110.         temp= DQ_PxIN & DQ;
  111.                 if(temp!=0x00)
  112.                         result |=0x80;
  113.         if(count<7)
  114.                         result=result>>1;
  115.                 delay_us(55);
  116.                 DQ_OUT();
  117.         //DQ_OUTH();
  118.                 //delay_us(10); // Complete the time slot and 10us recovery
  119.     }
  120.     return result;
  121. }
  122. //复位函数
  123. unsigned char OWReset(void)
  124. {
  125.     unsigned char presence;
  126.     DQ_OUT();
  127.     DQ_OUTL();
  128.     delay_us(480);   // leave it low for 480us
  129.     //delay_us(226);
  130.     //DQ_OUTH();
  131.     DQ_IN();
  132.     delay_us(70);   //leave it low for 45us
  133.    
  134.     presence = DQ_PxIN & DQ;
  135.     //presence &= DQ;
  136.     delay_us(410); // wait for end of timeslot240u
  137.     DQ_OUT();
  138.     //delay_us(170);
  139.     return presence;  
  140. } // 0=presence, 1 = no part
  141. void initcommand(void)
  142. {     
  143.     unsigned char c[9];  
  144.     unsigned char i,j;
  145.     unsigned char rebit;
  146.     i=OWReset();
  147.     while(i==0x20);
  148.     OWWriteByte(0xCC); // Skip ROM
  149.     OWWriteByte(0x4E); // Write Scratchpad
  150.     OWWriteByte(0x00); // Write Page
  151.     OWWriteByte(0x07); // Write Cortrol
  152.     i=OWReset();
  153.     while(i==0x20);
  154.     OWWriteByte(0xCC); // Skip ROM
  155.     OWWriteByte(0xBE); // Read Scratchpad
  156.     OWWriteByte(0x00); // Read 0th Page
  157.     for(j=0;j<9;j++)
  158.     {
  159.         c[j]=OWReadByte();
  160.     }
  161.     i=OWReset();
  162.     while(i==0x20);
  163.     OWWriteByte(0xCC); // Skip ROM
  164.     OWWriteByte(0x48); // Read Scratch Pad to Memory  
  165.     OWWriteByte(0x00); // Copy 0th Page
  166.     rebit=OWReadbit();
  167.     i=OWReset();
  168.     while(i==0x20);
  169.     delay_ms(20);
  170. }
  171. //读当前电流
  172. float Read_Current(void)
  173. {         
  174.     unsigned char c[9];
  175.     unsigned char i,j;
  176.     float n;
  177.     //initcommand();
  178.     i=OWReset();
  179.     while(i==0x20);
  180.     OWWriteByte(0xCC); // Skip ROM
  181.     OWWriteByte(0xB8); // Read Scratchpad
  182.     OWWriteByte(0x00); // Read 0th Page
  183.     i=OWReset();
  184.     while(i==0x20);
  185.     OWWriteByte(0xCC); // Skip ROM
  186.     OWWriteByte(0xBE); // Read Scratchpad
  187.     OWWriteByte(0x00); // Read 0th Page
  188.     for(j=0;j<9;j++)
  189.     {
  190.         c[j]=OWReadByte();
  191.     }
  192.     n=((c[6]&0x03)*256+c[5])/(4096*R);  
  193.     return (n);
  194. }
  195. //读取当前电池温度
  196. float Read_Temperature(void)
  197. {
  198.     unsigned char g[9];
  199.     unsigned char i,j;
  200.     float u;
  201.     i=OWReset();
  202.     while(i==0x20);
  203.     OWWriteByte(0xCC); //Skip ROM
  204.     OWWriteByte(0x44); // Start Conversion
  205.     delay_ms(20);
  206.     i=OWReset();
  207.     while(i==0x20);
  208.     OWWriteByte(0xCC); // Skip ROM
  209.     OWWriteByte(0xB8); //READ SCRATCHPAD
  210.     OWWriteByte(0x00); //READ 0TH PAGE
  211.     i=OWReset();
  212.     while(i==0x20);
  213.     OWWriteByte(0xCC); // Skip ROM
  214.     OWWriteByte(0xBE); // Read Scratch Pad
  215.     OWWriteByte(0x00);
  216.     for(j=0;j<9;j++)
  217.     {
  218.         g[j]=OWReadByte();
  219.     }
  220.     u=((g[2]&0x7f)*256+g[1])*0.03125;
  221.     return (u);
  222. }
  223. //读取电压转换值
  224. float Read_Voltage(void)
  225. {        
  226.     unsigned char b[9];
  227.     unsigned char i,j,p,q;
  228.     float m;
  229.     i=OWReset();
  230.     while(i==0x20);  
  231.     OWWriteByte(0xCC); // Skip ROM
  232.     OWWriteByte(0xB4); //WRITE VOLTAGE CORTROL
  233.     delay_ms(20);
  234.     i=OWReset();
  235.     while(i==0x20);
  236.     OWWriteByte(0xCC); // Skip ROM
  237.     OWWriteByte(0xB8); //READ SCRATCHPAD
  238.     OWWriteByte(0x00); //READ 0TH PAGE
  239.     i=OWReset();
  240.     while(i==0x20);         
  241.     OWWriteByte(0xCC); // Skip ROM
  242.     OWWriteByte(0xBE); //READ SCRATCHPAD
  243.     OWWriteByte(0x00); //READ 0TH PAGE
  244.     for(j=0;j<9;j++)
  245.     {
  246.         b[j]=OWReadByte();
  247.     }
  248.     m=((b[4]&0x03)*256+b[3])*0.01;
  249.     return (m);
  250. }
  251. //读电池的当前剩余容量
  252. float Read_ICAcurrent(void)
  253. {      
  254.     unsigned char d[9];
  255.     unsigned char i,j;
  256.     float p;
  257.    
  258.     i=OWReset();
  259.     while(i==0x20);
  260.     OWWriteByte(0xCC); // Skip ROM
  261.     OWWriteByte(0xBE);
  262.     OWWriteByte(0x01);
  263.     for(j=0;j<9;j++)
  264.     {
  265.         d[j]=OWReadByte();
  266.     }
  267.     p=(float)d[4]/(2048*R);  
  268.     return (p);
  269. }
  270. //读电池的充电累计容量
  271. float Read_CCAcurrent(void)
  272. {
  273.     unsigned char a[9];
  274.     unsigned char e[9];
  275.     unsigned char i,j;
  276.     float q;
  277.      
  278.     i=OWReset();
  279.     while(i==0x20);
  280.     OWWriteByte(0xCC); // Skip ROM
  281.     OWWriteByte(0xB8); //READ SCRATCHPAD
  282.     OWWriteByte(0x07); //READ 07TH PAGE
  283.     i=OWReset();
  284.     while(i==0x20);
  285.     OWWriteByte(0xCC); // Skip ROM
  286.     OWWriteByte(0xBE);
  287.     OWWriteByte(0x07);
  288.     for(j=0;j<9;j++)
  289.     {
  290.         e[j]=OWReadByte();
  291.     }
  292.     q = (e[5]*256+e[4])*0.015625;  
  293.     return (q);
  294. }
  295. //读电池的累计放电容量
  296. float Read_DCAcurrent(void)
  297. {   
  298.     unsigned char a[9];
  299.     unsigned char f[9];
  300.     unsigned char i,j;
  301.     float t;
  302.         
  303.     i=OWReset();
  304.     while(i==0x20);
  305.     OWWriteByte(0xCC); // Skip ROM
  306.     OWWriteByte(0xB8); //READ SCRATCHPAD
  307.     OWWriteByte(0x07); //READ 07TH PAGE
  308.     i=OWReset();
  309.     while(i==0x20);
  310.     OWWriteByte(0xCC); // Skip ROM
  311.     OWWriteByte(0xBE);
  312.     OWWriteByte(0x07);
  313.     for(j=0;j<9;j++)
  314.     {
  315.         f[j]=OWReadByte();
  316.     }
  317.     t=(f[7]*256+f[6])*0.015625;
  318.     return (t);

  319. }
  320. main.c
  321. #include "msp430f5438a.h"
  322. #include "ds2438.h"
  323. void Init_GPIO(void);
  324. void Init_Clock(void);

  325. void main( void )
  326. {
  327.     float A,B,J,D,E,F;
  328.     float H,I;
  329.     // Stop watchdog timer to prevent time out reset
  330.     WDTCTL = WDTPW + WDTHOLD;
  331.     Init_GPIO();
  332.     Init_Clock();
  333.     initcommand();             //初始化函数的一些值  
  334.     while(1)
  335.     {
  336.         A=Read_Current();          //读当前电流值   
  337.         A=Read_Current();          //读当前电流值  
  338.         A=Read_Current();          //读当前电流值     
  339.         B=Read_Temperature();  //读当前电池壳体的表面的温度
  340.         B=Read_Temperature();  //读当前电池壳体的表面的温度     
  341.         J=Read_Voltage();          //读当前电池的电压值
  342.         J=Read_Voltage();          //读当前电池的电压值
  343.         J=Read_Voltage();          //读当前电池的电压值         
  344.         D=Read_ICAcurrent();        //读当前电池的容量值
  345.         D=Read_ICAcurrent();        //读当前电池的容量值
  346.         D=Read_ICAcurrent();        //读当前电池的容量值
  347.         E=Read_CCAcurrent();        //读当前充电电流的累计值
  348.         E=Read_CCAcurrent();        //读当前充电电流的累计值
  349.         E=Read_CCAcurrent();        //读当前充电电流的累计值
  350.         F=Read_DCAcurrent();        //读当前电池放电电流的累计值
  351.         F=Read_DCAcurrent();        //读当前电池放电电流的累计值
  352.         F=Read_DCAcurrent();        //读当前电池放电电流的累计值
  353.         H=D/1600;                  //当前电池的容量的百分比
  354.         I=D/A;                     //电池还能使用多常时间     
  355.     }
  356. }
  357. void Init_GPIO(void)
  358. {
  359.         // set all ports  to low on all pins
  360.         P1OUT         =         0x00;
  361.         P1DIR         =        0xD7;
  362.         P2OUT        =         0x00;
  363.         P2DIR        &=        0x77;
  364.         P3OUT        =         0x00;
  365.         P3DIR        |=        0xDB;
  366.     P4OUT   =   0X00;
  367.     P4DIR   |=  0XFF;
  368.     P5OUT   =   0X00;
  369.     P5DIR   |=  0X63;   
  370.     P6OUT   =   0x00;
  371.     P6DIR   |=  0xFF;
  372.     P7OUT   =   0x00;
  373.     P7DIR   |=  0xFC;
  374.     P8OUT   =   0x00;
  375.     P8DIR   |=  0xFF;
  376.     P9OUT   =   0x00;
  377.     P9DIR   |=  0xDB;
  378.     P10OUT   =   0x00;
  379.     P10DIR   |=  0xDD;
  380.    
  381.     P3OUT   |= BIT0;
  382.     P4OUT   |= BIT0;
  383.     //P5OUT   |= BIT5;
  384.     P6OUT   |= BIT4;
  385.     P9OUT   |= BIT0;   
  386. }
  387. /*系统时钟初始化SMCLK = MCLK = XT2 ACLK=XT1 */
  388. void Init_Clock(void)
  389. {
  390.         //XT1
  391.         P7SEL |= BIT0 + BIT1;        // Select XT1
  392.         UCSCTL6 &= ~(XT1OFF);        // XT1 On
  393.         UCSCTL6 |= XCAP_3;         // Internal load cap
  394.         //XT2
  395.         P5SEL |= BIT2 + BIT3;//select XT2
  396.         UCSCTL6 &= ~XT2OFF;
  397.         UCSCTL3   |= SELREF_2;        // FLLref = REFO
  398.         UCSCTL4   |= SELA_2;        // ACLK=REFO,SMCLK=DCO,MCLK=DCO
  399.         do
  400.         {
  401.                 UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志                                                         
  402.                 SFRIFG1 &= ~OFIFG;
  403.          }while(SFRIFG1&OFIFG);        // 检测振荡器错误标志
  404.         UCSCTL6   &= ~XT2DRIVE0;
  405.         UCSCTL4   |= SELA_0+SELS_5 + SELM_5;        // SMCLK = MCLK = XT2 ACLK=XT1
  406. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2015-6-13 14:09:24 | 显示全部楼层
是否需要经过一个学习的过程.
电量是累加的数据.

出0入0汤圆

 楼主| 发表于 2015-6-13 14:13:50 | 显示全部楼层
liufabing 发表于 2015-6-13 14:09
是否需要经过一个学习的过程.
电量是累加的数据.

电流为什么会这么大呢?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 01:33

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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