久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機讀BQ2040電池電量程序 原理圖
[打印本頁]
作者:
gzyanbo
時間:
2022-9-16 15:10
標題:
單片機讀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)
下載附件
2022-9-16 15:09 上傳
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
999久久久
|
亚洲国产成人精品久久
|
久久国产精品一区二区
|
户外露出一区二区三区
|
激情在线视频
|
亚洲一区二区三区在线视频
|
日韩中文字幕第一页
|
神马久久香蕉
|
亚洲午夜精品一区二区三区
|
日韩在线免费视频
|
亚洲成人一区二区三区
|
国产成人精品免费
|
国产欧美精品一区二区三区
|
aaaa一级毛片
|
久久激情视频
|
九九久久99
|
91最新在线视频
|
欧美日韩在线精品
|
国产精品国产三级国产播12软件
|
北条麻妃一区二区三区在线观看
|
va在线
|
日韩精品成人一区二区三区视频
|
免费一区二区三区
|
孰女乱色一区二区三区
|
国产高清精品一区
|
日韩成人免费视频
|
在线不卡av
|
日韩欧美亚洲
|
日本在线中文
|
99久久日韩精品免费热麻豆美女
|
亚洲狠狠
|
在线观看日韩
|
91视频在线
|
国产精品成人一区二区三区吃奶
|
亚洲一区二区三区免费在线
|
久久精品网
|
久久9视频
|
日日噜噜噜夜夜爽爽狠狠视频,
|
久久网站免费视频
|
第一色在线
|
狠狠操狠狠操
|