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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2192|回復: 0
打印 上一主題 下一主題
收起左側

單片機讀BQ2040電池電量程序 原理圖

[復制鏈接]
跳轉到指定樓層
樓主
#include <AT89X51.H>
#include <absacc.h>
#include <intrins.h>

sbit  SMBC=P1^6;//sbit  SMBC=P1^4;          //bq2040中SMbus的時鐘端
sbit  SMBD=P1^7;//sbit  SMBD=P1^5;          //bq2040中SMbus的數據端
sbit  led3=P1^3;          //LED指示燈的最高位,4位中的第3位,0表示指示燈亮,1表示指示燈滅,即對讀出數據取反
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;     //讀電池狀態
unsigned char ReceiveData_L,ReceiveData_H,Current_H_7,BatteryStatus_L_6,BatteryStatus_L_5;
      //從BQ2040接收數據的低位,高位,電流正負位(正表示充電,負表示放電),電池狀態充放電判斷(0表示充電,0x40表示放電),電池狀態滿充判斷(0表示未充滿,0x20表示充滿)
unsigned char ack;      //用于判斷接收確認是否超時,超時為1,未超時為0

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

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

//以下函數詳見SMbus原理
void Star(void)  //開始子程序      當SMBC為高電平時,SMBD上出現一個下降沿。該條件啟動一次傳輸過程
{
  SMBC=0;
  Delay();
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  SMBD=0;
  Delay();
}


void Stop(void)  //停止子程序      當SMBC為高電平時,SMBD上出現一個上升沿。該條件停止一次傳輸過程
{
  SMBC=0;
  Delay();
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
  SMBD=1;
  Delay();
}


void Ackw(void)  //ACKNOWLEDGE寫子程序     SMBC為高時,采樣到SMBD為低電平
{
  unsigned char a=0;
  ack=0;
  SMBC=0;
  Delay();
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  while(SMBD)
  {
    a++;
        ack=0;
    if(a==250)     //   向串口發送EE,表示發送出錯,未收到確認。利用串口助手可以看到
    {
      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為高時,采樣到SMBD為低電平
{
  SMBC=0;
  Delay();
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
}


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


void Send(unsigned char b)  //發送子程序      將b按從最高位到最低位的順序,逐位的發送給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中的數據逐位的讀出
{
  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();      //開始
  a=0x16;
  Send(a);    //發送器件地址0x16
  Ackw();     //發送確認
  if(ack)     //未確認則重新發送
    return;
  Send(Command);  //發送讀剩余電量指令
  Ackw();     //發送確認
  if(ack)     //未確認則重新發送
    return;
  Star();
  a=0x17;    //發送器件地址0x17
  Send(a);
  Ackw();    //發送確認
  if(ack)    //未確認則重新發送
    return;
  ReceiveData_L=Receive();  //接收剩余電量低8位數據
  Ackr();    //接收確認
  ReceiveData_H=Receive();  //接收剩余電量高8位數據
  Nack();    //非確認
  Stop();    //結束
}




void Delay2(void)   //4s顯示延時
{
  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快閃延時
{
  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特快閃延時,speaker響延時
{
  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慢閃延時
{
  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)  //充電充滿時,指示燈顯示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)  //充電時,指示燈顯示0 1 0 1=10
  {     
    power_led=0;
    speaker=1;
    led0=1;
    led1=0;
    led2=1;
    led3=0;
    Delay2();
  }
             //放電時,指示燈指示電量0-9共10份
  else
  {
    if(h>0x22)     //超出電量范圍(當讀出的剩余電量16位的高8位大于0x22,即電量大于8960mah時1,表示錯誤,所有燈不亮)
    {
      power_led=0;
      speaker=1;
      led0=1;
      led1=1;
      led2=1;
      led3=1;
    }

    if(h<=0x22&&h>=0x17)  //顯示09(當剩余電量在5888mah~8960mah之間時,指示燈表示 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(當剩余電量在5376mah~5888mah之間時,指示燈表示 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(當剩余電量在4608mah~5376mah之間時,指示燈表示 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(當剩余電量在3840mah~4608mah之間時,指示燈表示 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(當剩余電量在3328mah~3840mah之間時,指示燈表示 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(當剩余電量在2560mah~3328mah之間時,指示燈表示 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(當剩余電量在2048mah~2560mah之間時,指示燈表示 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(當剩余電量在1280mah~2048mah之間時,指示燈表示 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(當剩余電量在256mah~1280mah之間時,指示燈表示 1 1 1 0=1)
    {
      power_led=0;
      speaker=1;
      led0=0;
      led1=1;
      led2=1;
      led3=1;
      Delay2();
    }

    if(h<0x01)  //顯示01在閃爍(當剩余電量在0mah~256mah之間時,指示燈表示 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,無校驗,數據位8,停止位1.
  TH1=0xFD;
  TL1=0xFD;
  PCON=0x00;
  TR1=1;
  SCON=0xD8;

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

   if(ack==0)   //讀數據成功,則執行賦值
     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);
   //   向串口發送電池狀態,利用串口助手可以看到

   if(ack==0)   //讀數據成功,則執行賦值
     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);
    //   向串口發送剩余電量,利用串口助手可以看到

        if(ack==0)   //讀數據成功,則執行賦值
    {
      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, 下載次數: 71)

1663311839329.jpg

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 福利精品在线观看 | 99久久免费精品国产男女高不卡 | 免费的av网站 | 国产96在线| 无码国模国产在线观看 | 亚洲一区二区三区在线观看免费 | 国产精品视频免费 | 91国内外精品自在线播放 | 欧美成人免费在线视频 | 欧美在线a | 日韩国产黄色片 | 精品无码久久久久久国产 | 一级二级三级在线观看 | 精品国产一级 | 国产精品女人久久久 | www.夜夜骑| 黄色a级一级片 | 一二三四在线视频观看社区 | 操久久 | 日本小电影在线 | 精品久久久久久久久久 | 在线一区二区三区 | 一区二区在线免费观看 | 日韩精品 电影一区 亚洲 | 亚洲协和影视 | 国产1区2区3区 | 亚洲一区精品在线 | 国产一级黄色网 | 国产91中文 | 免费在线黄色av | www.天天操 | av久久 | 成年人黄色一级毛片 | 人人爽日日躁夜夜躁尤物 | 亚洲国产精品一区 | 国产精品成av人在线视午夜片 | 中国黄色毛片视频 | 日日夜夜操天天干 | 黄色福利 | 国产美女在线观看 | 欧美一级在线免费观看 |