找回密码
 立即注册
搜索
楼主: 搬砖道人

直播——锂电池保护板主控部分大电流板PCB和程序制作

[复制链接]

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-4-24 21:17:10 | 显示全部楼层
本帖最后由 bsm56321 于 2018-4-24 21:37 编辑

刚才调试了一下充电模式,充电时电流流过C-端对电池负极是负的电压,通过运算放大正确显示,测试结果0.46A时ADC值是0050(=80),56倍放大,2480/4096*80/56=0.8649mv,管子内阻是0.8649/0.46=1.88毫欧。0.92A时ADC值是009D(=157),56倍放大,2480/4096*157/56=1.6974mv,管子内阻是1.6974/0.92=1.845毫欧。
测试微小电流17豪安充电,ADC值是2左右,有跳动1或者3,平均是2,2480/4096*2/56=0.021623mv,这么微小电压能测量出来都是是靠运放的功劳!!,如果用再高级的运放估计效果还有好。这板是第一次开,运算倍数设计多少就多少,不能应用中改变,下次开板放大倍数做成2档,正常工作档(56倍)和微小电流档1000倍


使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-4-25 10:55:25 | 显示全部楼层
本帖最后由 bsm56321 于 2018-4-25 10:57 编辑

开始写主程序
/******************************电池电压电流扫描**********************************/
void ks()
{
        if(num0==0)                  //开始 进入检查负载程序
        {
                 f_out=0;           c_out=0;                                       //放电关闭 充电关闭            
                 ADC_CONTR|=0x01;NOP();NOP();adc();                           //开启P1.1通道,并ADC   
                 if(adc0>=4095){f_out=1;c_out=1; NOP();NOP();adc();}else num0=1;  //ADC 是否是负载
                 if(adc0<4094){ num0=2;}else{ f_out=0;c_out=0;num0=20;}         //如果是负载则进入负载程序,否则就是短路关闭充防管
        }
        else  
     if(num0==1)         //进入检查是否是充电
         {
         ADC_CONTR|=0x05;NOP();NOP();adc();                                                      //开启P1.5通道
                 if(adc0>=4095){f_out=1;c_out=1; NOP();NOP();adc();}else num0=19;  //ADC 是否是充电
                 if(adc0<4094){ num0=3;}else{ f_out=0;c_out=0;        num0=20;}         //如果是充电程序,否则就是充电电流过大关闭充防管

         }
         else
         if(num0==2)                //        进入负载程序
         {
                        UartSend(0xaa); UartSend(0x55);        UartSend(0x77);//向均衡板发查询代码
                        
         }
         else
         if(num0==3)                //        进入充电程序
         {

         }




}

使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-4-29 20:50:53 | 显示全部楼层
充放电控制电路基本代码已经测试完成,

使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-4 10:30:21 | 显示全部楼层
本帖最后由 bsm56321 于 2018-5-4 11:13 编辑

NTC温度测试,从下面3个图表看出,串联电阻选择和温度范围有关系,选择得好可以德到很好的非线性纠正,如果生活中温度范围在-20~+50度那么串联电阻选择10K,如果测量功率管和电池温度,范围10-120度,一个选择图2的曲线,串联电阻3K曲线最好线性,如果测量50-150度,串联电阻用1K。/******************************测试代码********************************************/
                 if(a>=1&&b==0)
                {
                           ntc1=1,ntc2=0;          f_out=1;c_out=1;  //打开NTC1串联电阻电源,
                          ADC_CONTR=0x86;NOP();NOP();            //打开P1.6 ADC通道
                   if(a>=100&&b==0)
                   {
                                 
                          for(j=0,i=0;i<16;i++)
                          {
                                    adc();j+=adc0;                                         //16次累加
                          }  
                         wd0=j>>4;        b=1; ntc1=0;                                                         //取出16次平均值
                         if(wd0<=5){wd0=0;}else {wd0=wd0-5;}        //把ADC底值清除掉
                          UartSend(0x88);        UartSend(wd0>>8);        UartSend(wd0);           //发送NTC1温度数据到串口
                   }
                }
            if(a>=750&&b==1)
                {         ntc1=0,ntc2=1;         f_out=1;c_out=1;                //打开NTC2串联电阻电源,
                        ADC_CONTR=0x84;NOP();NOP();adc();            //打开充放管,打开P1.4 ADC通道
                    if(a>=850&&b==1)
                   {                          
                          for(j=0,i=0;i<16;i++)
                          {
                                    adc();j+=adc0;                                         //16次累加
                          }  
                         wd0=j>>4;                b=2; ntc2=0;                        //取出16次平均值
                         if(wd0<=5){wd0=0;}else {wd0=wd0-5;}        //把ADC底值清除掉
                          UartSend(0x77);        UartSend(wd0>>8);        UartSend(wd0);           //发送NTC2温度数据到串口
                  }
                }
                 if(a>=1500)a=0,b=0;





使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-4 20:58:08 | 显示全部楼层
本帖最后由 bsm56321 于 2018-5-4 21:07 编辑

蓝牙今天焊上了,在测试,用了2个不同的NTC,一个5%精度,一个1%精度,温度有稍微偏差APP用最文编译,代码如下
事件 BLE蓝牙1.通道数据改变(服务UUID 为 文本型,通道UUID 为 文本型,数据 为 字节型())
   变量 aa 为 文本型
        变量 bb 为 文本型
        变量 cc 为 文本型
        变量 成员数 为 整数型        
        变量 NTC1 为 文本型        
        变量 NTC2 为 文本型        
        变量 放电电流 为 文本型        
        变量 充电电流 为 文本型               
        变量 输入内容 为 文本型
        变量 ID 为 整数型
        成员数=取文本长度(字节集到十六进制(数据))
        变量 a 为 文本型
    变量 b 为 文本型
        变量 c 为 文本型        
        编辑框4.加入文本(字节集到十六进制(数据))
        如果 成员数 >= 6 则
                b=取文本中间( 字节集到十六进制(数据),0,6 )
        结束 如果
        如果 成员数 >=8 则
                c=取文本中间( 字节集到十六进制(数据),6,2 )
        结束 如果
        
        如果 b="55AAEE" 则
               
                如果 c="88" 则
                        NTC1= 四舍五入( 到十进制( 取文本中间( 字节集到十六进制(数据),8,2 ))-(到十进制( 取文本中间( 字节集到十六进制(数据),10,2 ))/到十进制( 取文本中间( 字节集到十六进制(数据),12,2 )))-40,3)
                        标签1.标题="  NTC1温度:" & NTC1        
                否则如果        c="77" 则
                        NTC2=四舍五入( 到十进制( 取文本中间( 字节集到十六进制(数据),8,2 ))-(到十进制( 取文本中间( 字节集到十六进制(数据),10,2 ))/到十进制( 取文本中间( 字节集到十六进制(数据),12,2 )))-40,3)
                        标签2.标题="  NTC1温度:" & NTC2
                否则如果        c="66" 则
                        放电电流=取文本中间( 字节集到十六进制(数据),8,4 )
                否则如果        c="55" 则
                        充电电流=取文本中间( 字节集到十六进制(数据),8,4 )
                结束 如果        
        结束 如果        
结束 事件
//*****************************************************************************/

                 if(a>=1&&b==0)
                {
                           ntc1=1,ntc2=0;          f_out=1;c_out=1;  //打开NTC1串联电阻电源,
                          ADC_CONTR=0x86;NOP();NOP();            //打开P1.6 ADC通道
                   if(a>=100&&b==0)
                   {                                 
                          for(j=0,i=0;i<16;i++)
                          {
                                    adc();j+=adc0;                                         //16次累加
                          }  
                          wd0=j>>4;ntc1=0;                b=1;                      //取出16次平均值
                         if(wd0<=5){wd0=0;}else {wd0=wd0-5;}        //把ADC底值清除掉
                          tmp=2480*wd0/4096;                                         //临时参数
              for(j=0,i=0;i<160;i++)
                           {
                                  if((tmp)>ntctab){j=i; i=161;k=ntctab[(j-1)]- ntctab[j];z=(ntctab[(j-1)]- tmp); }//运算温度数
                           }  
                   Uart3Send(0x55);Uart3Send(0xAA);Uart3Send(0xEE);Uart3Send(0x88);Uart3Send(j);Uart3Send(z); Uart3Send(k);        //发送NTC1温度数据到蓝牙
                   UartSend(0x88);UartSend(j);UartSend(z);         UartSend(k);
                   }
                }
            if(a>=750&&b==1)
                {         ntc1=0,ntc2=1;         f_out=1;c_out=1;                //打开NTC2串联电阻电源,
                        ADC_CONTR=0x84;NOP();NOP();adc();            //打开充放管,打开P1.4 ADC通道
                    if(a>=850&&b==1)
                   {                          
                          for(j=0,i=0;i<16;i++)
                          {
                                    adc();j+=adc0;                                         //16次累加
                          }  
                         wd0=j>>4;                 ntc2=0;b=2;                        //取出16次平均值
                         if(wd0<=5){wd0=0;}else {wd0=wd0-5;}        //把ADC底值清除掉
                                   tmp=2480*wd0/4096;                                         //临时参数
              for(j=0,i=0;i<160;i++)
                           {
                                  if((tmp)>ntctab){j=i; i=161;k=ntctab[(j-1)]- ntctab[j];z=(ntctab[(j-1)]- tmp); }          //运算温度数
                           }  
                           Uart3Send(0x55);Uart3Send(0xAA);Uart3Send(0xEE); Uart3Send(0x77);Uart3Send(j);Uart3Send(z);         Uart3Send(k);//发送NTC2温度数据到蓝牙
                  }
                }
                 if(a>=1500)a=0,b=0;







使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-4 21:18:50 | 显示全部楼层
本帖最后由 bsm56321 于 2018-5-4 21:22 编辑

把2个温度头抓在手里,温度相当精确,温度运算用查表得到度数,然后插值运算。




使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-10 10:22:18 | 显示全部楼层
本帖最后由 bsm56321 于 2018-5-10 10:38 编辑

今天更新均衡板测试程序,不是最终程序。由于本贴关注人不多,后面将不再更新。
//**************************************************************//
/***********************************************************/
//MCU : STC15W404AS        20  均衡板程序 地址0x01           */
//DATA: 2018.05.10                                                                                   */
//EDIT: V 1
//bsm制作         QQ:489734618                                    */
/***********************************************************/
//--------------------------------------------------
//头文件
#include <IAP15W4K61S.h>
#include "intrins.h"
#include "USART.h"
#include "adc.h"
#define u16 unsigned int
#define u8 unsigned char
#define NOP() //_nop_()
#define FOSC0 11059200L
#define T1MS (65536-FOSC0/1000)      //1T模式
sbit en=P1^0;
sbit pwm_h=P3^7;
u16 tad,a,c;  
bit b;  
u8 num2;
u16 dl,dy;
u16 gc,hf,jl,qy,jh;
bit jh_on;                        

/****************系统初始化************************************/
void sys()
{        //CLK_DIV = 0x00;        //系统时钟为内部R/C振荡时钟/16
    P1M0 = 0x01;
    P1M1 = 0x00;  
    P3M0 = 0x82;
    P3M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;        
        CLK_DIV=0x20;          //ADC,高2位,低8位        

}
/****************定时器初始化********************************************/
void Timerin()        //1ms@11059200MHz
{
         num2=10;  jh_on=0;
         gc=829; qy=757;      //初始化过压,欠压值
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = T1MS;                     //初始化计时值
        TH0 = T1MS >> 8;
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        ET0 = 1;  
        EA=1;
}
/*************定时器中断服务程序*********************/
void timer0() interrupt 1
{         
        TL0 = T1MS;                     //初始化计时值
       TH0 = T1MS >> 8;
        tad++;         a++;
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
    if (RI)
    {
            RI = 0;                 //清除RI位
            udat[us++]=SBUF;                //数据包写入
            if(us>12){ us=0;}  tad=0;
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        uf = 0;               //清忙标志
    }
}/***************控制程序*************************/
void xs()
{        
        if(jh>0)           //均衡电流大小控制  0-100%
        {         
                  c++;
                 if(jh>100){jh=100;}          //防止溢出
                 if(c>100)        { c=0;  }
                 if( c>jh  ) {pwm_h=1;}else  pwm_h=0;          //调节占空比
        }else          {pwm_h=1;}                                                          //占空比为0时无均衡电流

    if(a==1){ADC_CONTR=0xc7; }                                    //开启测量电流ADC通道
    if(a==10){adc (); dl= ADC_RES<<8|ADC_RESL;}         // 电流ADC
    if(a==20){        ADC_CONTR=0xc1; }                                        //开启测量电压ADC通道
    if(a==30){adc ();         dy= ADC_RES<<8|ADC_RESL;}        // 电压ADC

   if(a>1000)           //一秒检查一次电压,如果过压或者欠压,通知给主控板             {            
        a=0;         
        if(dy>gc||dy<qy)        
          {

                 UartSend(0xaa);UartSend(0x55) ; UartSend(0x01);UartSend(0xee);                  
               UartSend(dy>>8);UartSend(dy);          tad=0;  jh=0; TI=0;RI=0; us=0;en=0;pwm_h=1CON=0x02;
                 en=1;        pwm_h=1; NOP();          NOP();  a=0;
            }
   }

    /*************************串口通讯数据包解包***********************************************/
         if(tad==20)                          //在无串口通讯20毫秒后检查接收的数据信息
         {
                  if(udat[0]==0xaa)                                //通讯协议,头检错
                  {
                         if(udat[1]==0x55)                        //通讯协议,头检错
                          {
                                  if(udat[2]==0x01)                //通讯协议,本机地址
                                  {
                                           if(udat[3]==0xe0)        //送出电压电流数据
                                          {
                                                  UartSend(dl>>8);UartSend(dl);        UartSend(dy>>8);UartSend(dy);
        
                                          }
                                          else
                                          if(udat[3]==0xe1)                        //设置过充电压,恢复充电压,绢流电流,欠压值
                                          {
                                                        gc= udat[4]<<8|udat[5];  hf=udat[6]<<8|udat[7];jl=udat[8]<<8|udat[9]; qy=udat[10]<<8|udat[11];                 
                                          }
                                           else
                                           if(udat[3]==0xe2)                   //均衡开启量        
                                          {                                                
                                                        jh=        udat[4];
                                          }
                                          else

                                          if(udat[3]==0xef)                   //立即休眠
                                          {                                                
                                                        tad=0;  jh=0;  TI=0;RI=0; us=0;en=0;pwm_h=1CON=0x02; en=1;pwm_h=1; NOP(); NOP();  a=0;
                                          }

                                  }        else us=0;        //不是本机地址,状态机归零                 
                          } else us=0;                //不是本机协议,状态机归零
                  }         else us=0;                        //不是本机协议,状态机归零
         }

        if(tad>=10000){ tad=0;   jh=0;   TI=0;RI=0; us=0; en=0;pwm_h=1CON=0x02; en=1;pwm_h=1; NOP();  NOP();  a=0;}//自动休眠

}

void main()                  
{        
        sys      ();          //系统初始化
        adcin   ();          //ADC        初始化
        UartInit();          //串口初始化
       Timerin ();   //定时器初始化

    while (1)
    {
       xs();  
    }
}







使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-10 13:19:50 | 显示全部楼层
这个要严重支持一下

使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-10 14:43:19 | 显示全部楼层
呵呵,还有下文吗

使用道具 举报

24万

主题

442万

回帖

323

金币

版主

注册时间:2021-3-11

在线时间:9 小时

发表于 2018-5-12 21:53:00 | 显示全部楼层
强烈支持开板,出板给我一张,和蚂蚁板竞争一下。

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|电动车论坛

GMT+8, 2024-10-5 23:26 , Processed in 0.057924 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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