DS2438测量电压是比较接近,但电流和剩余容量不准
本帖最后由 love萍萍 于 2015-6-12 23:15 编辑利用MSP430F5438A和DS2438做一电池监测电路,电路如下图所示:
图中VCC是用MSP430板子的3.3V供电.
数据能够读出,电压基本上准的,但是测量电池电流的时候测出来是4.99A,电池容量是0.0。明显不对了,请问是哪的问题是我硬件有问题吗?
下面是我参考网上例程改写的程序
ds2438.h
#ifndef _DS2438_H_
#define _DS2438_H_
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define SKIP_ROM0xCC //跳过ROM选择步骤
#define CONVERT_V0xB4 //启用电压转换功能
#define RECALL 0xB8 //重调EEPROM
#define READ_SP0xBE //读暂存器
#define WRITE_SP0x4E //写暂存器
#define COPY_SP 0x48 //复制暂存器
#define DQ_PxDIR P5DIR
#define DQ_PxIN P5IN
#define DQ_PxOUT P5OUT
#define DQ BIT5
//高低电平定义
#define DQ_IN() DQ_PxDIR &= ~DQ
#define DQ_OUT() DQ_PxDIR |= DQ
#define DQ_OUTH() DQ_PxOUT |= DQ
#define DQ_OUTL() DQ_PxOUT &= ~DQ
#define DQ_IN_HL() DQ_PxIN & DQ
#defineR 0.050
void OWWritebit(unsigned char bit);
unsigned char OWReadbit(void);
void OWWriteByte(unsigned char data);
unsigned char OWReadByte(void);
unsigned char OWReset(void);
void initcommand(void);
float Read_Current(void);
float Read_Temperature(void);
float Read_Voltage(void);
float Read_ICAcurrent(void);
float Read_CCAcurrent(void);
float Read_DCAcurrent(void);
#endif
//ds2438.c
#include "msp430f5438a.h"
#include "math.h"
#include "ds2438.h"
void OWWritebit(unsigned char bit)
{
if(bit)
{//write bit 1
DQ_OUTL();
delay_us(6);
DQ_OUTH();
delay_us(64);
}
else
{//write bit 0
DQ_OUTL();
delay_us(60);
DQ_OUTH();
delay_us(10);
}
}
unsigned char OWReadbit(void)
{
unsigned char result;
DQ_OUTL();
delay_us(6);
DQ_OUTH();
DQ_IN();
delay_us(9);
result= DQ_PxIN & DQ;
delay_us(55);
return result;
}
void OWWriteByte(unsigned char data)
{
unsigned char loop,i;
DQ_OUT();
for(loop=0;loop<8;loop++)
{
i=data&0x01;
if(i)
{
DQ_OUTL();
delay_us(6);
DQ_OUTH();
delay_us(64);
}
else
{
DQ_OUTL();
delay_us(60);
DQ_OUTH();
delay_us(10);
}
data=data>>1;
}
}
unsigned char OWReadByte(void)
{
unsigned char count, temp;
unsigned char result=0;
for(count=0;count<8;count++)
{
// shift the result to get it ready for the next bit
DQ_OUT();
DQ_OUTL();
delay_us(6);
DQ_OUTH();
DQ_IN();
delay_us(9);
temp= DQ_PxIN & DQ;
if(temp!=0x00)
result |=0x80;
if(count<7)
result=result>>1;
delay_us(55);
DQ_OUT();
//DQ_OUTH();
//delay_us(10); // Complete the time slot and 10us recovery
}
return result;
}
//复位函数
unsigned char OWReset(void)
{
unsigned char presence;
DQ_OUT();
DQ_OUTL();
delay_us(480); // leave it low for 480us
//delay_us(226);
//DQ_OUTH();
DQ_IN();
delay_us(70); //leave it low for 45us
presence = DQ_PxIN & DQ;
//presence &= DQ;
delay_us(410); // wait for end of timeslot240u
DQ_OUT();
//delay_us(170);
return presence;
} // 0=presence, 1 = no part
void initcommand(void)
{
unsigned char c;
unsigned char i,j;
unsigned char rebit;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x4E); // Write Scratchpad
OWWriteByte(0x00); // Write Page
OWWriteByte(0x07); // Write Cortrol
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
for(j=0;j<9;j++)
{
c=OWReadByte();
}
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0x48); // Read Scratch Pad to Memory
OWWriteByte(0x00); // Copy 0th Page
rebit=OWReadbit();
i=OWReset();
while(i==0x20);
delay_ms(20);
}
//读当前电流
float Read_Current(void)
{
unsigned char c;
unsigned char i,j;
float n;
//initcommand();
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratchpad
OWWriteByte(0x00); // Read 0th Page
for(j=0;j<9;j++)
{
c=OWReadByte();
}
n=((c&0x03)*256+c)/(4096*R);
return (n);
}
//读取当前电池温度
float Read_Temperature(void)
{
unsigned char g;
unsigned char i,j;
float u;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); //Skip ROM
OWWriteByte(0x44); // Start Conversion
delay_ms(20);
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); // Read Scratch Pad
OWWriteByte(0x00);
for(j=0;j<9;j++)
{
g=OWReadByte();
}
u=((g&0x7f)*256+g)*0.03125;
return (u);
}
//读取电压转换值
float Read_Voltage(void)
{
unsigned char b;
unsigned char i,j,p,q;
float m;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB4); //WRITE VOLTAGE CORTROL
delay_ms(20);
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE); //READ SCRATCHPAD
OWWriteByte(0x00); //READ 0TH PAGE
for(j=0;j<9;j++)
{
b=OWReadByte();
}
m=((b&0x03)*256+b)*0.01;
return (m);
}
//读电池的当前剩余容量
float Read_ICAcurrent(void)
{
unsigned char d;
unsigned char i,j;
float p;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE);
OWWriteByte(0x01);
for(j=0;j<9;j++)
{
d=OWReadByte();
}
p=(float)d/(2048*R);
return (p);
}
//读电池的充电累计容量
float Read_CCAcurrent(void)
{
unsigned char a;
unsigned char e;
unsigned char i,j;
float q;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x07); //READ 07TH PAGE
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE);
OWWriteByte(0x07);
for(j=0;j<9;j++)
{
e=OWReadByte();
}
q = (e*256+e)*0.015625;
return (q);
}
//读电池的累计放电容量
float Read_DCAcurrent(void)
{
unsigned char a;
unsigned char f;
unsigned char i,j;
float t;
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xB8); //READ SCRATCHPAD
OWWriteByte(0x07); //READ 07TH PAGE
i=OWReset();
while(i==0x20);
OWWriteByte(0xCC); // Skip ROM
OWWriteByte(0xBE);
OWWriteByte(0x07);
for(j=0;j<9;j++)
{
f=OWReadByte();
}
t=(f*256+f)*0.015625;
return (t);
}
main.c
#include "msp430f5438a.h"
#include "ds2438.h"
void Init_GPIO(void);
void Init_Clock(void);
void main( void )
{
float A,B,J,D,E,F;
float H,I;
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
Init_GPIO();
Init_Clock();
initcommand(); //初始化函数的一些值
while(1)
{
A=Read_Current(); //读当前电流值
A=Read_Current(); //读当前电流值
A=Read_Current(); //读当前电流值
B=Read_Temperature();//读当前电池壳体的表面的温度
B=Read_Temperature();//读当前电池壳体的表面的温度
J=Read_Voltage(); //读当前电池的电压值
J=Read_Voltage(); //读当前电池的电压值
J=Read_Voltage(); //读当前电池的电压值
D=Read_ICAcurrent(); //读当前电池的容量值
D=Read_ICAcurrent(); //读当前电池的容量值
D=Read_ICAcurrent(); //读当前电池的容量值
E=Read_CCAcurrent(); //读当前充电电流的累计值
E=Read_CCAcurrent(); //读当前充电电流的累计值
E=Read_CCAcurrent(); //读当前充电电流的累计值
F=Read_DCAcurrent(); //读当前电池放电电流的累计值
F=Read_DCAcurrent(); //读当前电池放电电流的累计值
F=Read_DCAcurrent(); //读当前电池放电电流的累计值
H=D/1600; //当前电池的容量的百分比
I=D/A; //电池还能使用多常时间
}
}
void Init_GPIO(void)
{
// set all portsto low on all pins
P1OUT = 0x00;
P1DIR = 0xD7;
P2OUT = 0x00;
P2DIR &= 0x77;
P3OUT = 0x00;
P3DIR |= 0xDB;
P4OUT = 0X00;
P4DIR |=0XFF;
P5OUT = 0X00;
P5DIR |=0X63;
P6OUT = 0x00;
P6DIR |=0xFF;
P7OUT = 0x00;
P7DIR |=0xFC;
P8OUT = 0x00;
P8DIR |=0xFF;
P9OUT = 0x00;
P9DIR |=0xDB;
P10OUT = 0x00;
P10DIR |=0xDD;
P3OUT |= BIT0;
P4OUT |= BIT0;
//P5OUT |= BIT5;
P6OUT |= BIT4;
P9OUT |= BIT0;
}
/*系统时钟初始化SMCLK = MCLK = XT2 ACLK=XT1 */
void Init_Clock(void)
{
//XT1
P7SEL |= BIT0 + BIT1; // Select XT1
UCSCTL6 &= ~(XT1OFF); // XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
//XT2
P5SEL |= BIT2 + BIT3;//select XT2
UCSCTL6 &= ~XT2OFF;
UCSCTL3 |= SELREF_2; // FLLref = REFO
UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志
SFRIFG1 &= ~OFIFG;
}while(SFRIFG1&OFIFG); // 检测振荡器错误标志
UCSCTL6 &= ~XT2DRIVE0;
UCSCTL4 |= SELA_0+SELS_5 + SELM_5; // SMCLK = MCLK = XT2 ACLK=XT1
} 是否需要经过一个学习的过程.
电量是累加的数据. liufabing 发表于 2015-6-13 14:09
是否需要经过一个学习的过程.
电量是累加的数据.
电流为什么会这么大呢?
页:
[1]