gs0208 发表于 2018-9-11 16:20

开源:电池容量测试仪 Labview与STC的结合

前一段时间开源了一个智能小车,小车需要锂电池供电,家里一大堆电池,当使用的时候才发现好久没有容量大减,正好最近在研究labview,所以就做了1个来测试一下电池容量,其实原理非常简单,用单片机就能轻松搞定,为了高大上而且能为了能看到电池充电和放电的曲线所以就需要上位软件了,第一次用labview编程程序写的非常烂高手见谅了
功能:
上位机 labview负责采集数据计时显示设置充放电截止电压和电池曲线图
下位机 stc125a60s2 负责ad检测电压电流串口通信


由于手底下没有mos管所以暂时使用317进行横流放电
充电采用锂电池专用模块
通信 串口发送字符串
检测电压电流 Work_v_ad
充电    Work_v_cd
放电    Work_v_fd
关闭    Work_voff

电脑和单片机通信采用一个usb ttl下载器进行
ad采集为了准确,采用Tl431做标准基准源,还算比较准确的



这个是第二版带LCD,可以脱机使用






labview显示电池放电曲线
蓝色是放电 红色是充电

放电根据自己设定的截止电压检测,我设置的是3v
为了以防万一电池上面我加了保护板,由于手头没有热敏电阻所以暂时没加
电池容量随时计算10s检测一次电压和电流1分钟上传图表一次



电路图

充放电数据

第一次写labview写的很差,我用手机发的帖子,不能上传附件有需要的可以找我要



#include<stc12c5a60s2.h>
#include"stdio.h"
#include"intrins.h"


#define uint unsigned int
#define uchar unsigned char


sbit v_cd=P2^0;
sbit v_fd=P2^1;
sbit key=P2^2;


int volt,curr;
uchar key_flag=0;
uchar num;
uchar shi,ge,xiao1,xiao2;
uchar s,g,x1,x2;
uchar data table; //暂存数组,可以将10改为你需要的数值
uint i=0;
uchar code table1[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
bit com_flag;




void AD_init();
unsigned int AD_get(unsigned char channel);
float AD_work(unsigned char channel);
void delayms(uint z);
void delay(unsigned int a); //延时约1ms
void UART_init(void);               //初始化函数
void senddata(uchar dat);
void uart_sendstring(uchar *upStr);




void delayms(uint z)
{
      uint x,y;
      for(x=z;x>0;x--)
            for(y=110;y>0;y--);
}      


/**********************************************************/


void UART_init(void)               //初始化函数
{
    SCON = 0x50;
    TMOD = 0x20;
    TH1= 0xFD;                  //波特率9600
    TL1= 0xFD;
    TR1= 1;
    ES   = 1;
    EA   = 1;
//    TI   =0;
//    REN = 1;


}
/**********************************************************/


void senddata(uchar dat)
{               


    ES = 0;                     //关串口中断
    TI = 0;                     //将串口发送完成中断请求标志清零
    SBUF = dat;                //写数据到发送缓冲区
    while(!TI);                   //等待发送完成
    TI = 0;                     //将串口发送完成中断请求标志清零
    ES = 1;                   //将串口发送完成中断请求标志清零
}
/* ***************************************************** */


// 函数名称:UART_SendString()
// 函数功能:发送字符串
// 入口参数:待发送的字符串(*upStr)
// 出口参数:无
/* ***************************************************** */
void uart_sendstring(uchar *upStr)
{
    while(*upStr)                  // 检测是否发送完毕
    {
      senddata(*upStr++);   
      // 调用UART_SendOneByte函数一个字节一个字节发送数据
    }
}
/* ***************************************************** */



         




void delay(unsigned int a) //延时约1ms
{
      unsigned int i;
      while (--a!=0)
      for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
}




void AD_init()
{
      P1ASF=0xff; //P1口全部作为模拟功能AD使用
      ADC_RES=0;   //清零转换结果寄存器高8位
      ADC_RESL=0; //清零转换结果寄存器低2位
      ADC_CONTR=0x80;//开启AD电源
      delay(2);   //等待1ms,让AD电源稳定
}




unsigned int AD_get(unsigned char channel)
{
      ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
      _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
      while(!(ADC_CONTR&0x10));    //等待转换完成
      ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
      return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
}






void keysean()
{
      if(key==0)
      {
                delay(10);
                if(key==0)
                {
                        key_flag++;
                  if(key_flag>2)
                        key_flag=0;
                  
                }
                while(!key);
      }
      
      if(key_flag==0)
      {
                v_fd=1;
                v_cd=1;
      }
      if(key_flag==1)
      {
                v_fd=1;
                v_cd=0;
      }
      if(key_flag==2)
      {
                v_cd=1;
                v_fd=0;
      }
            
}
   
   
//    float AD_work(unsigned char channel)
//    {
//      float AD_val;   //定义处理后的数值AD_val为浮点数
//      unsigned char i;
//      for(i=0;i<100;i++)
//      AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
//      AD_val/=100;
//    //    AD_val=(AD_val*2.5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
//      return AD_val;
//    }




void main()
{   
      AD_init();
      UART_init();   
      v_cd=1;
      v_fd=1;
      while(1)
      {
                if(com_flag==0)
                keysean();
      }
}


/**********************************************************/


void interrupt_uart() interrupt 4
{


   
          ES=0;    //关串口中断
   
          table=SBUF;//命令存到命令数组
            if(table=='W')
            i++;
            else
            RI=0; //软件清除接收中断
            ES=1;//开串口中断
                if(i>8)      //如果接受字节大于8个开始检测接受字节后六位数据Work_v_ad
    {
                if(table=='v'&&table=='_'&&table=='a'&&table=='d')
      {
                        shi=volt/1000;
                        ge=volt%1000/100;
                        xiao1=volt%100/10;
                        xiao2=volt%10;
                  
                        senddata(table1);
                        senddata('.');
                        senddata(table1);
                        senddata(table1);
                        senddata(table1);
                        
                        volt=(AD_get(2)*0.002)*1000;
                        shi=volt/1000;
                        ge=volt%1000/100;
                        xiao1=volt%100/10;
                        xiao2=volt%10;
                  
                        senddata('_');
                        if(shi>0)
                        senddata(table1);
                        senddata(table1);
                        senddata(table1);
                        senddata(table1);

                  
                }
                if(table=='v'&&table=='_'&&table=='a'&&table=='a')
      {
                        volt=(AD_get(2)*0.002)*1000;
                        shi=volt/1000;
                        ge=volt%1000/100;
                        xiao1=volt%100/10;
                        xiao2=volt%10;
                  
                        senddata(table1);
                        //senddata('.');
                        senddata(table1);
                        senddata(table1);
                        senddata(table1);
                        senddata(0x0d);
                        senddata(0x0a);
                        com_flag=1;
                        
                  
                  
                }
                if(table=='v'&&table=='_'&&table=='c'&&table=='d')
      {
                            com_flag=1;
                            v_fd=1;
                            v_cd=0;
                }
               
                if(table=='v'&&table=='_'&&table=='f'&&table=='d')
      {
                            com_flag=1;
                            v_cd=1;
                            v_fd=0;
                }
               
                if(table=='v'&&table=='o'&&table=='f'&&table=='f')
      {
                            com_flag=1;
                            v_cd=1;
                            v_fd=1;
                           
                }
                i=0;   
      }
            
}





gs0208 发表于 2018-9-11 16:22

自己先占个沙发{:5_643:}

sdingo78 发表于 2018-9-11 16:29

虽然不懂,但是看起来很厉害的样子http://www.shoudian.org//mobcent//app/data/phiz/default/06.pnghttp://www.shoudian.org//mobcent//app/data/phiz/default/06.pnghttp://www.shoudian.org//mobcent//app/data/phiz/default/06.png

cyp450 发表于 2018-9-11 17:05

年薪百万?

wanegg 发表于 2018-9-11 17:36

出个套件呗

华电人 发表于 2018-9-11 17:40

好厉害!

wuqiong10 发表于 2018-9-11 17:55

资赐,发个百度盘链接呗。

mytomatoes 发表于 2018-9-11 18:54

本帖最后由 mytomatoes 于 2018-9-11 18:56 编辑

这单片机型号咋这么熟悉呢? 原来我用过。。{:6_652:}
LZ开放一下串口协议吧,这样我就可以直接用你的上位机软件了。

https://www.yleee.com.cn/thread-17799-1-1.html
https://www.yleee.com.cn/thread-18490-1-1.html

天地一号 发表于 2018-9-11 19:01

不明觉厉

kyd12345 发表于 2018-9-11 19:09

这种技术贴应该发去隔壁 手电坛撸货的居多

whseen 发表于 2018-9-11 19:48

要是能连接android手机更好了,通常比电脑更静音无风扇散热没有机械硬盘声。

donkey 发表于 2018-9-11 20:14

mytomatoes 发表于 2018-9-11 18:54
这单片机型号咋这么熟悉呢? 原来我用过。。
LZ开放一下串口协议吧,这样我就可以直接用你的上位 ...

labview是数据处理软件,装上这个,让楼主发他的文件给你就可以了.

还没睡 发表于 2018-9-11 22:39

成本多少钱?

读书行路 发表于 2018-9-12 00:15

楼主这个厉害。佩服。

gs0208 发表于 2018-9-14 08:52

donkey 发表于 2018-9-11 20:14
labview是数据处理软件,装上这个,让楼主发他的文件给你就可以了.



检测电压电流 Work_v_ad
充电    Work_v_cd
放电    Work_v_fd
关闭    Work_voff

按照上面 波特率9600 直接发送字符串就可以

iloveqinqin 发表于 2018-9-14 16:21

好厉害

x3159 发表于 2018-9-14 17:14

电流是固定的??

gs0208 发表于 2018-9-16 10:03

x3159 发表于 2018-9-14 17:14
电流是固定的??

由于手头没有mos管,程序不能调节,调节可以通过改变317的电路来调节电流
页: [1]
查看完整版本: 开源:电池容量测试仪 Labview与STC的结合