|
本帖最后由 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_ROM 0xCC //跳过ROM选择步骤
- #define CONVERT_V 0xB4 //启用电压转换功能
- #define RECALL 0xB8 //重调EEPROM
- #define READ_SP 0xBE //读暂存器
- #define WRITE_SP 0x4E //写暂存器
- #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
- #define R 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[9];
- 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[j]=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[9];
- 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[j]=OWReadByte();
- }
- n=((c[6]&0x03)*256+c[5])/(4096*R);
- return (n);
- }
- //读取当前电池温度
- float Read_Temperature(void)
- {
- unsigned char g[9];
- 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[j]=OWReadByte();
- }
- u=((g[2]&0x7f)*256+g[1])*0.03125;
- return (u);
- }
- //读取电压转换值
- float Read_Voltage(void)
- {
- unsigned char b[9];
- 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[j]=OWReadByte();
- }
- m=((b[4]&0x03)*256+b[3])*0.01;
- return (m);
- }
- //读电池的当前剩余容量
- float Read_ICAcurrent(void)
- {
- unsigned char d[9];
- 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[j]=OWReadByte();
- }
- p=(float)d[4]/(2048*R);
- return (p);
- }
- //读电池的充电累计容量
- float Read_CCAcurrent(void)
- {
- unsigned char a[9];
- unsigned char e[9];
- 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[j]=OWReadByte();
- }
- q = (e[5]*256+e[4])*0.015625;
- return (q);
- }
- //读电池的累计放电容量
- float Read_DCAcurrent(void)
- {
- unsigned char a[9];
- unsigned char f[9];
- 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[j]=OWReadByte();
- }
- t=(f[7]*256+f[6])*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 ports to 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
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|