久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2212|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)讀BQ2040電池電量程序 原理圖

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:41347 發(fā)表于 2022-9-16 15:10 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
#include <AT89X51.H>
#include <absacc.h>
#include <intrins.h>

sbit  SMBC=P1^6;//sbit  SMBC=P1^4;          //bq2040中SMbus的時(shí)鐘端
sbit  SMBD=P1^7;//sbit  SMBD=P1^5;          //bq2040中SMbus的數(shù)據(jù)端
sbit  led3=P1^3;          //LED指示燈的最高位,4位中的第3位,0表示指示燈亮,1表示指示燈滅,即對(duì)讀出數(shù)據(jù)取反
sbit  led2=P1^2;          //LED指示燈4位中的第2位
sbit  led1=P1^1;          //LED指示燈4位中的第1位
sbit  led0=P1^0;          //LED指示燈的最低位,4位中的第0位
sbit  power_led=P1^4;//sbit  power_led=P1^7;
sbit  speaker=P1^5;//sbit  speaker=P1^6;

unsigned char bq2040_Command_RC=0x0f;     //讀剩余電量的指令
signed char bq2040_Command_C=0x0a;     //讀電流的指令
unsigned char bq2040_Command_BS=0x16;     //讀電池狀態(tài)
unsigned char ReceiveData_L,ReceiveData_H,Current_H_7,BatteryStatus_L_6,BatteryStatus_L_5;
      //從BQ2040接收數(shù)據(jù)的低位,高位,電流正負(fù)位(正表示充電,負(fù)表示放電),電池狀態(tài)充放電判斷(0表示充電,0x40表示放電),電池狀態(tài)滿充判斷(0表示未充滿,0x20表示充滿)
unsigned char ack;      //用于判斷接收確認(rèn)是否超時(shí),超時(shí)為1,未超時(shí)為0

unsigned char ADAPTER=0,ERROR; //用于判斷儀器采用電池供電或者采用電源適配器供電

void Delay(void)   //延時(shí)子程序
{
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

//以下函數(shù)詳見(jiàn)SMbus原理
void Star(void)  //開(kāi)始子程序      當(dāng)SMBC為高電平時(shí),SMBD上出現(xiàn)一個(gè)下降沿。該條件啟動(dòng)一次傳輸過(guò)程
{
  SMBC=0;
  Delay();
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  SMBD=0;
  Delay();
}


void Stop(void)  //停止子程序      當(dāng)SMBC為高電平時(shí),SMBD上出現(xiàn)一個(gè)上升沿。該條件停止一次傳輸過(guò)程
{
  SMBC=0;
  Delay();
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
  SMBD=1;
  Delay();
}


void Ackw(void)  //ACKNOWLEDGE寫子程序     SMBC為高時(shí),采樣到SMBD為低電平
{
  unsigned char a=0;
  ack=0;
  SMBC=0;
  Delay();
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  while(SMBD)
  {
    a++;
        ack=0;
    if(a==250)     //   向串口發(fā)送EE,表示發(fā)送出錯(cuò),未收到確認(rèn)。利用串口助手可以看到
    {
      ADAPTER++;
          if(ADAPTER==20)
          {
        ERROR=0xEE;
                ADAPTER=0;
      }
      else
            ERROR=0;
          ack=1;
      SBUF=0xEE;
      while(!TI);
      TI=0;
      break;
    }
  }
}

void Ackr(void) //ACKNOWLEDGE讀子程序     SMBC為高時(shí),采樣到SMBD為低電平
{
  SMBC=0;
  Delay();
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
}


void Nack(void)  //NOT ACKNOWLEDGE子程序    SMBC為高電平時(shí),采樣到SMBD為高電平
{
  SMBC=0;
  Delay();
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
}


void Send(unsigned char b)  //發(fā)送子程序      將b按從最高位到最低位的順序,逐位的發(fā)送給bq2040
{
  unsigned char i,x,y,z;
  z=0x80;
  for(i=1;i<9;i++)
  {
    x=b&z;
    if(x==0)
      y=0;
    else
      y=1;
    SMBC=0;
    Delay();
    SMBD=y;
    Delay();
    SMBC=1;
    Delay();
    z>>=1;
  }
}

unsigned char Receive(void)  //接收子程序     將bq2040中的數(shù)據(jù)逐位的讀出
{
  unsigned char i,g=0x00;
  for(i=1;i<9;i++)
  {
    SMBC=0;
    _nop_();
    _nop_();
    SMBD=1;
    Delay();
    SMBC=1;
    Delay();
    g<<=1;
    if(SMBD)
      g++;
    Delay();
  }
  return g;
}




void Read(unsigned char Command)   //讀剩余電量子程序
{
  unsigned int a;
  Star();      //開(kāi)始
  a=0x16;
  Send(a);    //發(fā)送器件地址0x16
  Ackw();     //發(fā)送確認(rèn)
  if(ack)     //未確認(rèn)則重新發(fā)送
    return;
  Send(Command);  //發(fā)送讀剩余電量指令
  Ackw();     //發(fā)送確認(rèn)
  if(ack)     //未確認(rèn)則重新發(fā)送
    return;
  Star();
  a=0x17;    //發(fā)送器件地址0x17
  Send(a);
  Ackw();    //發(fā)送確認(rèn)
  if(ack)    //未確認(rèn)則重新發(fā)送
    return;
  ReceiveData_L=Receive();  //接收剩余電量低8位數(shù)據(jù)
  Ackr();    //接收確認(rèn)
  ReceiveData_H=Receive();  //接收剩余電量高8位數(shù)據(jù)
  Nack();    //非確認(rèn)
  Stop();    //結(jié)束
}




void Delay2(void)   //4s顯示延時(shí)
{
  unsigned char i,j,k;
  for(i=0;i<255;i++)
   for(j=0;j<255;j++)
    for(k=0;k<20;k++);
}


void Delay3(void)   //power_led快閃延時(shí)
{
  unsigned char i,j,k;
  for(i=0;i<100;i++)
   for(j=0;j<150;j++)
    for(k=0;k<5;k++);
}

void Delay4(void)   //power_led特快閃延時(shí),speaker響延時(shí)
{
  unsigned char i,j,k;
  for(i=0;i<100;i++)
   for(j=0;j<150;j++)
    for(k=0;k<1;k++);
}

void Delay5(void)   //power_led慢閃延時(shí)
{
  unsigned char i,j,k;
  for(i=0;i<100;i++)
   for(j=0;j<150;j++)
    for(k=0;k<12;k++);
}

void LedDisplay_Battery(unsigned char h,unsigned char l)
{
  unsigned char i;
  if(BatteryStatus_L_5==0x20&&BatteryStatus_L_6==0)  //充電充滿時(shí),指示燈顯示0 1 0 0=11
  {
    power_led=0;
    speaker=1;
    led0=0;
    led1=0;
    led2=1;
    led3=0;
    Delay2();
  }
  else if(Current_H_7==0&&BatteryStatus_L_6==0)  //充電時(shí),指示燈顯示0 1 0 1=10
  {     
    power_led=0;
    speaker=1;
    led0=1;
    led1=0;
    led2=1;
    led3=0;
    Delay2();
  }
             //放電時(shí),指示燈指示電量0-9共10份
  else
  {
    if(h>0x22)     //超出電量范圍(當(dāng)讀出的剩余電量16位的高8位大于0x22,即電量大于8960mah時(shí)1,表示錯(cuò)誤,所有燈不亮)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=1;
      led2=1;
      led3=1;
    }

    if(h<=0x22&&h>=0x17)  //顯示09(當(dāng)剩余電量在5888mah~8960mah之間時(shí),指示燈表示 0 1 1 0=9)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=1;
      led2=1;
      led3=0;
      Delay2();
    }

    if(h<0x17&&h>=0x15)  //顯示08(當(dāng)剩余電量在5376mah~5888mah之間時(shí),指示燈表示 0 1 1 1=8)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=1;
      led2=1;
      led3=0;
      Delay2();
    }

    if(h<0x15&&h>=0x12)  //顯示07(當(dāng)剩余電量在4608mah~5376mah之間時(shí),指示燈表示 1 0 0 0=7)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=0;
      led2=0;
      led3=1;
      Delay2();
    }

    if(h<0x12&&h>=0x0f)  //顯示06(當(dāng)剩余電量在3840mah~4608mah之間時(shí),指示燈表示 1 0 0 1=6)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=0;
      led2=0;
      led3=1;
      Delay2();
    }

    if(h<0x0f&&h>=0x0d)  //顯示05(當(dāng)剩余電量在3328mah~3840mah之間時(shí),指示燈表示 1 0 1 0=5)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=1;
      led2=0;
      led3=1;
      Delay2();
    }
    if(h<0x0d&&h>=0x0a)  //顯示04(當(dāng)剩余電量在2560mah~3328mah之間時(shí),指示燈表示 1 0 1 1=4)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=1;
      led2=0;
      led3=1;
      Delay2();
    }

    if(h<0x0a&&h>=0x08)  //顯示03(當(dāng)剩余電量在2048mah~2560mah之間時(shí),指示燈表示 1 1 0 0=3)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=0;
      led2=1;
      led3=1;
      Delay2();
    }  

    if(h<0x08&&h>=0x05)  //顯示02(當(dāng)剩余電量在1280mah~2048mah之間時(shí),指示燈表示 1 1 0 1=2)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=0;
      led2=1;
      led3=1;
      Delay2();
    }

    if(h<0x05&&h>=0x01)  //顯示01(當(dāng)剩余電量在256mah~1280mah之間時(shí),指示燈表示 1 1 1 0=1)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=1;
      led2=1;
      led3=1;
      Delay2();
    }

    if(h<0x01)  //顯示01在閃爍(當(dāng)剩余電量在0mah~256mah之間時(shí),指示燈表示 1 1 1 0=0)
    {
      //led0=0;
      led1=1;
      led2=1;
      led3=1;
          if(l>=0x40&&l<0xa0)
          {
            speaker=1;
                for(i=0;i<15;i++)
        {
                  led0=!led0;
          power_led=!power_led;
          Delay3();
                }
      }
          else if(l<0x40)
          {                  
                speaker=0;
                for(i=0;i<15;i++)
        {
          led0=!led0;
                  power_led=!power_led;
                  Delay4();
                }
          }
          else
          {
            speaker=1;
                for(i=0;i<10;i++)
        {
          led0=!led0;
                  power_led=!power_led;
                  Delay5();
                }
      }   
        }  
   }
}

void LedDisplay_Adapter()  //燈全亮,表示采用電源適配器供電
{
  power_led=0;
  speaker=1;
  led0=0;
  led1=0;
  led2=0;
  led3=0;
  Delay2();
}

main()
{
  unsigned char RemainingCapacity_H,RemainingCapacity_L,Current_H,BatteryStatus_L;
  TMOD=0x20;   //串口波特率9600bps,方式3,無(wú)校驗(yàn),數(shù)據(jù)位8,停止位1.
  TH1=0xFD;
  TL1=0xFD;
  PCON=0x00;
  TR1=1;
  SCON=0xD8;

  power_led=0;
  while(1)
  {
   Read(bq2040_Command_C);
   //   向串口發(fā)送當(dāng)前電流,利用串口助手可以看到

   if(ack==0)   //讀數(shù)據(jù)成功,則執(zhí)行賦值
     Current_H=ReceiveData_H;

   SBUF=bq2040_Command_C;
   while(!TI);
   TI=0;

   SBUF=Current_H;
   while(!TI);
   TI=0;
   SBUF=ReceiveData_L;
   while(!TI);
   TI=0;

      Current_H_7=Current_H&0x80;


   Read(bq2040_Command_BS);
   //   向串口發(fā)送電池狀態(tài),利用串口助手可以看到

   if(ack==0)   //讀數(shù)據(jù)成功,則執(zhí)行賦值
     BatteryStatus_L=ReceiveData_L;

   SBUF=bq2040_Command_BS;
   while(!TI);
   TI=0;

   SBUF=ReceiveData_H;
   while(!TI);
   TI=0;
   SBUF=BatteryStatus_L;
   while(!TI);
   TI=0;

    BatteryStatus_L_6=BatteryStatus_L&0x40;
    BatteryStatus_L_5=BatteryStatus_L&0x20;

    Read(bq2040_Command_RC);
    //   向串口發(fā)送剩余電量,利用串口助手可以看到

        if(ack==0)   //讀數(shù)據(jù)成功,則執(zhí)行賦值
    {
      RemainingCapacity_H=ReceiveData_H;
      RemainingCapacity_L=ReceiveData_L;
    }   

   SBUF=bq2040_Command_RC;
   while(!TI);
   TI=0;

   SBUF=RemainingCapacity_H;
   while(!TI);
   TI=0;
   SBUF=RemainingCapacity_L;
   while(!TI);
   TI=0;

   if(ack==0)
    LedDisplay_Battery(RemainingCapacity_H,RemainingCapacity_L);
   else if(ERROR==0xEE)
    LedDisplay_Adapter();
  }
}


1663311839329.jpg (32.55 KB, 下載次數(shù): 71)

1663311839329.jpg

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 91视频国产精品 | 久久久久免费精品国产小说色大师 | 日本爱爱 | 日日天天| 久久激情视频 | 国产一区二区欧美 | 狠狠操电影 | 日韩一区在线观看视频 | 国产一区二区三区四区在线观看 | 欧洲色综合| 日韩成人精品一区二区三区 | 成人影院av | 日韩在线视频免费观看 | 热久久性 | 国产99热精品 | 国产亚洲成av人在线观看导航 | 精品一区二区三区在线播放 | 成人国产精品久久 | 黄色网络在线观看 | 国产999精品久久久久久 | 欧美在线视频a | 成人在线日韩 | 亚洲欧美高清 | 欧美激情精品久久久久久变态 | 亚洲福利在线视频 | 91视频免费黄 | 欧美一级淫片免费视频黄 | 亚洲精品一区二区另类图片 | 午夜欧美 | 欧美日韩视频在线播放 | 97精品国产97久久久久久免费 | 欧美精品成人一区二区三区四区 | 欧美日韩中文字幕在线 | 中文字幕一区二区三区四区不卡 | 亚洲视频欧美视频 | 久久精品日| 久久精品成人热国产成 | 久久一级大片 | 午夜在线免费观看视频 | 国外成人在线视频网站 | 亚洲精品9999久久久久 |