⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 battery.cpp

📁 通过串口读取EC传送的电池信息
💻 CPP
字号:
/*****************************************************************************
*    battery.cpp ------ 检测电池状态并以文本和曲线的方式显示出来
*    主要功能1:利用spcomm元件获取串口RS232的数据
*    (包括;电量、电流、电压、电量剩余百分比)
*             实现函数:Comm1ReceiveData
*
*    功能2:对数据进行筛选和转换并以文本形式显示出来
*             实现函数:   ReceiveFlagData(buffer);        //获取充电状态
*                          ReceiveCapaData(buffer);       //获取电量数据
*                          ReceiveChargeData(buffer);    //获取电流数据
*                          ReceiveVoltData(buffer);     //获取电压数据
*                          ReceivePercentData(buffer); //获取剩余电量百分比
*
*    功能3:利用TeeChart元件根据所得最终数据绘制曲线
******************************************************************************/

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "battery.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "SPComm"
#pragma link "TeeTools"
#pragma link "TeeEdit"
#pragma link "TeeChartGrid"
#pragma link "TeeNavigator"
#pragma link "TeeURL"
#pragma link "TeeBannerTool"
#pragma link "EVENTLISTLib_OCX"
#pragma resource "*.dfm"
TMainForm *MainForm;

//--------------------构造函数,初始化变量------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
   bFlashflag = false;    //判断是否闪烁窗体
   bLinkflag = false;   //判断是否连接
   BatFullFlag = false; //判断电池是否已满
   RemCapacity= 0;     //剩余电量值
   Current=0;         //电流
   Voltage=0;        //电压
   Power=0;         //功耗
   iInterval=0;    //数据显示超时时间 (s)
   tStartTime=0;   //连接后计时时间
}
//-----------------------创建表单,初始化控件-----------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
    //清空曲线点
    RamCapicitySeries->Clear();
    VoltageSeries->Clear();
    ChargeCurrentSeries->Clear();



}
//-----------------------关闭表单,释放资源------------------------------------

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
   Comm1->StopComm();
   //AnimateWindow(this->Handle,1500,AW_CENTER | AW_HIDE);
}

/*************************************************************************************\
************************[     主要功能实现函数      ]**********************************
\*************************************************************************************/

//------------------------连接或断开串口------------------------------
void __fastcall TMainForm::BtnLinkClick(TObject *Sender)
{
     if(!bLinkflag) //-----连接-----
    {      
      BtnLink->Caption="断开";
      tStartTime=Time();
      iInterval=0;
      
      //获取波特率和COM口
      Comm1->BaudRate=RateComboBox->Text.ToInt();
      Comm1->CommName=ComComboBox->Text;
      Comm1->StartComm(); //打开串口
      Memo1->Lines->Add("已经连接:Com="+ ComComboBox->Text +" Rate="+RateComboBox->Text);
    }
    else         //-----断开-------
    {
      BtnLink->Caption="连接";
      Edit1->Clear();
      TextTool->Text="0:00:00";
      ScrollTool->Text="";

      Comm1->StopComm(); //关闭串口
      Memo1->Lines->Add("已经断开");


    }
    //控件可用/不可用的转换
      bLinkflag = !bLinkflag;
      Timer1->Enabled = !(Timer1->Enabled);
      BtnWrite->Enabled = !(BtnWrite->Enabled);
      Edit1->Enabled = !(Edit1->Enabled);
      ComComboBox->Enabled = !(ComComboBox->Enabled);
      RateComboBox->Enabled = !(RateComboBox->Enabled);
      MaskEdit1->Enabled = !(MaskEdit1->Enabled);
}

//-----------------------写入数据到串口--------------------------------

void __fastcall TMainForm::BtnWriteClick(TObject *Sender)
{

    AnsiString str;
    str = Edit1->Text;
    if(str.IsEmpty())
        return;
    Memo1->Lines->Add("Write: "+str);
    Comm1->WriteCommData( str.c_str(),str.Length());
}


//------------ spcomm 接收到数据后执行以下事件 ----------------------
void __fastcall TMainForm::Comm1ReceiveData(TObject *Sender, Pointer Buffer,
      WORD BufferLength)
{
 
      AnsiString buffer, bufferCap, bufferCurrent, bufferVolt, bufferPercent;

      //-----保存数据
      buffer = (char*)Buffer;
      if(buffer.Pos("IICisReady"))
      {

      //-----------------------------------------------------------

        // Power = Current * Voltage ;   //功耗
        //分别显示出: 当前时间--电量值---电流值---电压值---剩余电量百分比
      //  if(iInterval >= MaskEdit1->Text.ToInt())
      //  {
            //将数据传递给各个函数,分别进行筛选和转换,并返回所需数据

         ReceiveFlagData(buffer);                        //获取充电状态
         bufferCap    = ReceiveCapaData(buffer);        //获取电量数据
         bufferCurrent = ReceiveChargeData(buffer);    //获取电流数据
         bufferVolt   = ReceiveVoltData(buffer);      //获取电压数据
         bufferPercent = ReceivePercentData(buffer); //获取剩余电量百分比

           if(bufferCap=="error" || bufferCurrent=="error" || bufferVolt=="error" ||
              bufferPercent=="error" ) //为空表示有错误
            return;

            Memo1->Lines->Add(TimeToStr(Time())+ bufferCap + bufferCurrent + bufferVolt +bufferPercent);

           //绘制曲线点
           RamCapicitySeries->Add(RemCapacity,TimeToStr(Time()) ,clRed);
           VoltageSeries->Add(Voltage,TimeToStr(Time()) ,clRed);
           ChargeCurrentSeries->Add(Current,TimeToStr(Time()) ,clRed);
           iInterval=0;

      //  }
      }
      else
      {
           Memo1->Lines->Add(buffer);
      }



}

//-----------------------获取充电状态并输出--------------------
//-------------------------------------------------------------
//字符串处理流程:查找->截取->排序->转换->错误判断(防止乱码)
//-------------------------------------------------------------
void _fastcall TMainForm::ReceiveFlagData(AnsiString buffer)
{
   AnsiString myBuf(buffer),tempBuf,tempHexBuf;
   int iPos=0;
   int iTemp=0;

   if( (iPos = myBuf.Pos("BQ272_FLAGS")) !=0 )
   {
     ScrollTool->Text="正在充电";
     myBuf = myBuf.SubString(iPos,15);
      //----------防止乱码---------------
     if(myBuf.Length()<15)
       return;
     //重新给16进制字符串排序
     tempBuf.sprintf("%c%c",myBuf[13],myBuf[14]);
     //将16进制字符串转换为10进制整数
     iTemp=(int)strtol(tempBuf.c_str(),NULL,16);
     if(iTemp>=160 && iTemp<192)
     {
        Memo1->Lines->Add(TimeToStr(Time())+"    电池已满 "+tempBuf);
        //BatFullFlag = true;
     }
   }

   else if((myBuf.Pos("BQ27200_Discharge_Flags"))!=0)
   {
      ScrollTool->Text="正在放电";
   }
   else
     return ;

}

//-----------------------获取电量---------------------------
AnsiString _fastcall TMainForm::ReceiveCapaData(AnsiString buffer)
{
   AnsiString myBuf(buffer),tempBuf,tempHexBuf;
   int iPos=0, iTemp=0;

   if((iPos = myBuf.Pos("RemCapacity"))!=0)
     myBuf = myBuf.SubString(iPos,18);
   else
     return "error";
//%%%%%%%%%%%%%%%%%%%%%防止乱码%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   if(myBuf.Length()<18)
     return "error";
   for(int i=13; i<=17; i++)
   {
     if(i==15)
      continue;
     if(!(( myBuf[i]>='0' && myBuf[i]<='9' ) || ( myBuf[i]>='A' && myBuf[i]<='F' ))  )
       return "error";
   }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   //重新给16进制字符串排序
   tempBuf.sprintf("%c%c%c%c",myBuf[16],myBuf[17],myBuf[13],myBuf[14]);
   tempHexBuf=tempBuf;
   //将16进制字符串转换为10进制字符串
   iTemp=(int)strtol(tempBuf.c_str(),NULL,16);

   //RemCapacity = (double)iTemp*3.57/20;
   RemCapacity=iTemp;
   tempBuf.sprintf("%15d",iTemp);
   //test for error
   if(RemCapacity > 8500)
     return "error";
  // tempBuf+=tempHexBuf;

   return tempBuf;
}
//-----------------------获取电流---------------------------
AnsiString _fastcall TMainForm::ReceiveChargeData(AnsiString buffer)
{
  AnsiString myBuf(buffer),tempBuf,tempHexBuf;
   int iPos=0;
   int iTemp=0;

 /*********************检测充电电流***********************/
   if( (iPos=myBuf.Pos("ChargeCurrent")) !=0 )
   {
      myBuf = myBuf.SubString(iPos,19 );
 //-%%%%%%%%%%%%%%%%%%%%%%%%防止乱码-%%%%%%%%%%%%%%%%%%%%%%%%%---
      if(myBuf.Length()<19)
        return "error";
    for(int i=15; i<=19; i++)
   {
     if(i==17)
      continue;
     if(!(( myBuf[i]>='0' && myBuf[i]<='9' ) || ( myBuf[i]>='A' && myBuf[i]<='F' )))
       return "error";
   }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         //重新给16进制字符串排序
         tempBuf.sprintf("%c%c%c%c",myBuf[18],myBuf[19],myBuf[15],myBuf[16]);
         tempHexBuf=tempBuf;
         //将16进制字符串转换为10进制字符串
         iTemp=(int)strtol(tempBuf.c_str(),NULL,16);

        // tempBuf.sprintf("%15.2f",iTemp*3.57/20) ;
           tempBuf.sprintf("%15d",iTemp);
           Current = (double)iTemp;
         //Current = (double)iTemp*3.57/20;

  }
    /***********检测放电电流*******************/
    else if( (iPos = myBuf.Pos("DischargeCurrent")) !=0)
    {
      myBuf = myBuf.SubString(iPos,23);//ym
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%防止乱码%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      if(myBuf.Length()<23)
        return "error";
    for(int i=18; i<=22; i++)
   {
     if(i==20)
      continue;
     if(!(( myBuf[i]>='0' && myBuf[i]<='9' ) || ( myBuf[i]>='A' && myBuf[i]<='F' )))
       return "error";
   }

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         //重新给16进制字符串排序
         tempBuf.sprintf("%c%c%c%c",myBuf[21],myBuf[22],myBuf[18],myBuf[19]);
         tempHexBuf=tempBuf;
         //将16进制字符串转换为10进制字符串
         iTemp=(int)strtol(tempBuf.c_str(),NULL,16);

       // tempBuf.sprintf("%15.2f",iTemp*3.57/20) ;

        // Current = (double)iTemp*3.57/20;
        tempBuf.sprintf("%15d",iTemp) ;
        Current = (double)iTemp;
         if(Current > 8500)
           return "error";
     }
     return tempBuf;

}


//-----------------------获取电压-------------------------------------
AnsiString _fastcall TMainForm::ReceiveVoltData(AnsiString buffer)
{
  AnsiString myBuf(buffer),tempBuf,tempHexBuf;
   int iPos=0;
   int iTemp=0;

   if((iPos = myBuf.Pos("PreVOLT")) !=0)
     myBuf = myBuf.SubString(iPos,14);
   else
     return "error";

//%%%%%%%%%%%%%%%%%%%%%%%%%防止乱码---%%%%%%%%%%%%%%%%%%%%%%%%%%%------
   if(myBuf.Length()<14)
     return "error";
   for(int i=9; i<=13; i++)
   {
     if(i==11)
      continue;
     if(!(( myBuf[i]>='0' && myBuf[i]<='9' ) || ( myBuf[i]>='A' && myBuf[i]<='F' )))
       return "error";
   }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        //重新给16进制字符串排序
         tempBuf.sprintf("%c%c%c%c",myBuf[12],myBuf[13],myBuf[9],myBuf[10]);
         tempHexBuf=tempBuf;
         //将16进制字符串转换为10进制字符串
         iTemp=(int)strtol(tempBuf.c_str(),NULL,16);
         Voltage = iTemp;
         tempBuf.sprintf("%15d",iTemp);
         //test for error
        // if(Voltage > 6000)
           if(Voltage > 8500)
           return "error";
           //tempBuf+=tempHexBuf;

        return tempBuf;
}

//-----------------------获取电量百分比---------------------------
AnsiString _fastcall TMainForm::ReceivePercentData(AnsiString buffer)
{
  AnsiString myBuf(buffer),tempBuf,tempHexBuf;
   int iPos=0;
   int iTemp=0;

   if((iPos = myBuf.Pos("RSOC")) != 0)
     myBuf = myBuf.SubString(iPos,8);
   else
     return "error";
//---%%%%%%%%%%%%%%%%防止乱码-----%%%%%%%%%%%%%%%%%%----
   if(myBuf.Length()<8)
     return "error";
   for(int i=6; i<=7; i++)
   {
     if(!(( myBuf[i]>='0' && myBuf[i]<='9' ) || ( myBuf[i]>='A' && myBuf[i]<='F' )))
       return "error";
   }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   //重新给16进制字符串排序
   tempBuf.sprintf("%c%c",myBuf[6],myBuf[7] );
   tempHexBuf=tempBuf;
   iTemp=(int)strtol(tempBuf.c_str(),NULL,16);
   tempBuf.sprintf("%15d%%",iTemp);
   //----------防止乱码---------
   if(iTemp > 100 || iTemp <= 0)
      return "error";
        //tempBuf+=tempHexBuf;

   return tempBuf;
}

/*---------------------------------------------------------------------------
------------------------->  次要功能实现函数  <------------------------------
----------------------------------------------------------------------------*/

//--------------添加计时显示功能-----------------------
void __fastcall TMainForm::Timer1Timer(TObject *Sender)
{
    TextTool->Text=TimeToStr(Time()-tStartTime);
    iInterval++;


}

//--------------------曲线全屏显示------------------------------------

void __fastcall TMainForm::BtnFullScrClick(TObject *Sender)
{
   FullScreenTool->Active = true;
}

//------------------将曲线打印------------------------------------
void __fastcall TMainForm::BtnPreViewClick(TObject *Sender)
{
   ChartPreviewer1->Execute();
}
//----------------将曲线导出--------------------------------------

void __fastcall TMainForm::BtnExportClick(TObject *Sender)
{
   ChartEditor1->Title="图表导出";
   ChartEditor1->HighLightTabs=true;
   ChartEditor1->DefaultTab=cetExport;
   ChartEditor1->Execute();
}


void __fastcall TMainForm::BtnFlashClick(TObject *Sender)
{
   if(!bFlashflag)
   {
     BtnFlash->Caption = "不闪* * !" ;
     FLASHWINFO fwi;
     fwi.cbSize = sizeof(fwi);
     fwi.hwnd = Application->Handle;
     fwi.dwFlags = FLASHW_TRAY | FLASHW_TIMER ;
    // fwi.uCount = 5;
     fwi.dwTimeout = 500;
     FlashWindowEx(&fwi);
   }
   else
   {
     BtnFlash->Caption = "闪烁^ ^" ;
     FLASHWINFO fwi;
     fwi.cbSize = sizeof(fwi);
     fwi.hwnd = Application->Handle;
     fwi.dwFlags = FLASHW_STOP ;
     //fwi.uCount = 5;
     fwi.dwTimeout = 500;
     FlashWindowEx(&fwi);
   }
   bFlashflag = !bFlashflag;
}
//---------------------------------------------------------------------------




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -