MAX17043锂电池电量测量芯片C51驱动
生活随笔
收集整理的這篇文章主要介紹了
MAX17043锂电池电量测量芯片C51驱动
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
MAX17043/MAX17044為結(jié)構(gòu)緊湊、低成本、主機(jī)側(cè)電量計(jì),用于手持及便攜產(chǎn)品的鋰離子(Li+)電池的電量計(jì)量。MAX17043配置為單節(jié)鋰電池計(jì)量,MAX17044配置為兩節(jié)2S電池組計(jì)量。
MAX17043/MAX17044采用成熟的Li+電池建模方案(稱為ModelGauge?),在整個(gè)充/放電過程中連續(xù)跟蹤電池的相對(duì)充電狀態(tài)(SOC)。與傳統(tǒng)的電量計(jì)不同,ModelGauge算法省去了電池的再學(xué)習(xí)過程以及外部檢流電阻。器件提供溫度補(bǔ)償,使得μC與器件之間的交互操作降至最少。
需要注意的是,MAX17043僅支持單節(jié)鋰電池計(jì)量或者鋰電池的并聯(lián)計(jì)量,常見的18650單節(jié)或者并聯(lián)多節(jié)都是可以的。MAX17043不帶電池保護(hù)功能,所以在18650鋰電池的輸出端需要先接鋰電池保護(hù)板,再將保護(hù)板的輸出接到MAX17043上。
max17043_iic.h
#ifndef __MAX17043_IIC_H_ #define __MAX17043_IIC_H_#include <STC8.H>#define MAX17043_SCL P43 #define MAX17043_SDA P44void MAX17043_IIC_Start(); void MAX17043_IIC_Stop(); void MAX17043_IIC_WriteACK(unsigned char ack); unsigned char MAX17043_IIC_WaitACK(); void MAX17043_IIC_WriteByte(unsigned char wdata); unsigned char MAX17043_IIC_ReadByte();#endifmax17043_iic.c
#include "max17043_iic.h" #include "intrins.h"static void MAX17043_Delay() {unsigned char i;_nop_();_nop_();i = 20;while(--i); }void MAX17043_IIC_Start() {MAX17043_SDA = 1;MAX17043_SCL = 1;MAX17043_Delay();MAX17043_SDA = 0;MAX17043_Delay();MAX17043_SCL = 0; }void MAX17043_IIC_Stop() {MAX17043_SDA = 0;MAX17043_SCL = 0;MAX17043_Delay();MAX17043_SCL = 1;MAX17043_Delay();MAX17043_SDA = 1;MAX17043_Delay(); }void MAX17043_IIC_WriteACK(unsigned char ack) {MAX17043_SDA = ack;MAX17043_Delay();MAX17043_SCL = 1;MAX17043_Delay();MAX17043_SCL = 0; }unsigned char MAX17043_IIC_WaitACK() { unsigned char errtime = 50;MAX17043_Delay(); /*讀ACK*/MAX17043_SCL = 1;while(MAX17043_SDA){ errtime--;if(!errtime) {MAX17043_IIC_Stop();return 0;}}MAX17043_SCL = 0;MAX17043_Delay();return 1; }void MAX17043_IIC_WriteByte(unsigned char wdata) {unsigned char i;for(i=0; i<8; i++){MAX17043_SDA = wdata&0x80;wdata <<= 1;MAX17043_SCL = 1;MAX17043_Delay();MAX17043_SCL = 0;} }unsigned char MAX17043_IIC_ReadByte() {unsigned char i, bytedata;MAX17043_SDA = 1;for(i=0; i<8; i++){MAX17043_SCL = 1; bytedata <<= 1;bytedata |= MAX17043_SDA;MAX17043_SCL = 0;MAX17043_Delay();}return bytedata; }max17043.h
#ifndef __MAX17043_H_ #define __MAX17043_H_#define MAX17043_WRITE_ADDR 0x6C #define MAX17043_READ_ADDR 0x6D#define MAX17043_VCELL_MSB 0x02 #define MAX17043_VCELL_LSB 0x03 #define MAX17043_SOC_MSB 0x04 #define MAX17043_SOC_LSB 0x05 #define MAX17043_MODE_MSB 0x06 #define MAX17043_MODE_LSB 0x07 #define MAX17043_VERSION_MSB 0x08 #define MAX17043_VERSION_LSB 0x09 #define MAX17043_CONFIG_MSB 0x0C #define MAX17043_CONFIG_LSB 0x0D #define MAX17043_COMMAND_MSB 0xFE #define MAX17043_COMMAND_LSB 0xFF#define MAX17043_ALT P32 #define MAX17043_QST P40float MAX17043_GetBatteryPercent(); void MAX17043_QuickStart(); void MAX17043_EnterSleepMode(); void MAX17043_Restart(); void MAX17043_ClearAlert(); void MAX17043_SetAlertThreshold(unsigned char threshold);#endifmax17043.c
#include "max17043.h" #include "max17043_iic.h" #include "debug.h" #include "intrins.h"static void MAX17043_Delayms(unsigned int ms) //@24.000MHz {unsigned char i, j;while(ms){_nop_();i = 32;j = 40;do{while (--j);} while (--i);ms--;} }// 寫寄存器,MAX17043寫入的時(shí)候地址會(huì)自動(dòng)增,所以可以連續(xù)寫 // addr:芯片寄存器起始地址 // buf:寫數(shù)組值 // count:寫的長(zhǎng)度 // lastBitAck: 最后寫的字節(jié)寫完之后,主機(jī)是否發(fā)送應(yīng)答 // // 返回:0--寫入失敗,1--寫入成功 static unsigned char MAX17043_WriteReg(unsigned char addr, unsigned char *buf, unsigned char count, unsigned char lastBitAck) {unsigned char ret;unsigned char i;MAX17043_IIC_Start();MAX17043_IIC_WriteByte(MAX17043_WRITE_ADDR);ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write AddrCMD error, device not ack!\r\n");return 0;}MAX17043_IIC_WriteByte(addr);ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write Addr error, device not ack!\r\n");return 0;}for(i=0; i<count; i++){MAX17043_IIC_WriteByte(buf[i]); /*寫數(shù)據(jù)*/if(i < count-1 || lastBitAck){ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write data error, device not ack!\r\n");return 0;}}}MAX17043_IIC_Stop();return 1; }// 讀寄存器,MAX17043讀取的時(shí)候地址會(huì)自動(dòng)增,所以可以連續(xù)讀 // addr:芯片寄存器起始地址 // buf:讀取存放數(shù)組 // count:讀的長(zhǎng)度 // // 返回:0--讀取失敗,1--讀取成功 static unsigned char MAX17043_ReadReg(unsigned char address, unsigned char * buf, unsigned char count) /*多字節(jié)*/ { unsigned char ret;unsigned char i;MAX17043_IIC_Start();MAX17043_IIC_WriteByte(MAX17043_WRITE_ADDR); //寫命令ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write AddrCMD error, device not ack!\r\n");return 0;}MAX17043_IIC_WriteByte(address); //寫地址ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write AddrCMD error, device not ack!\r\n");return 0;}MAX17043_IIC_Start();MAX17043_IIC_WriteByte(MAX17043_READ_ADDR); //讀命令ret = MAX17043_IIC_WaitACK();if(!ret){Debug_UartSendStr("MAX17043: Write ReadCMD error, device not ack!\r\n");return 0;}for(i=0; i<count; i++){*buf++ = MAX17043_IIC_ReadByte();if(i < count-1){MAX17043_IIC_WriteACK(0);}else{MAX17043_IIC_WriteACK(1);}} MAX17043_IIC_Stop();return 1; } // 獲取百分比單位的電池剩余電量 float MAX17043_GetBatteryPercent() {unsigned char buf[2] = {0};float percent = 0.0;MAX17043_ReadReg(MAX17043_SOC_MSB, buf, sizeof(buf));percent = buf[0] + buf[1]/256.0; // buf[0]是1%精度的剩余電量// buf[1]是1/256%精度的剩余電量return percent; }// 快速啟動(dòng) // 這里使用了硬件直接在QST引腳給上升沿的方式 // 也可以向MAX17043寫寄存器的方式實(shí)現(xiàn),參考數(shù)據(jù)手冊(cè) void MAX17043_QuickStart() {MAX17043_QST = 0;MAX17043_Delayms(2);MAX17043_QST = 1;MAX17043_Delayms(2); }// 進(jìn)入睡眠模式 // 這里將SCL和SDA拉低2.5s進(jìn)入睡眠模式 // 同樣也可以寫寄存器使之進(jìn)入睡眠模式 void MAX17043_EnterSleepMode() {MAX17043_SCL = 0;MAX17043_SDA = 0;MAX17043_Delayms(2600); }// 重啟,效果和斷電重啟一樣 void MAX17043_Restart() {unsigned char buf[2] = {0x00, 0x54};// 最后一位寫入的時(shí)候,MAX17043是不應(yīng)答的,需要注意MAX17043_WriteReg(MAX17043_COMMAND_MSB, buf, sizeof(buf), 0); }// 設(shè)置電量警報(bào)閾值 // threshold:整數(shù)百分比單位的閾值,范圍是32~1,也就是32%~1%之間 void MAX17043_SetAlertThreshold(unsigned char threshold) {unsigned char buf[2] = {0x97, 0x1C};if(threshold > 0x1f) // 如果閾值大于32%,那么限制成32%{threshold = 0x1f;}buf[1] = (0x1F - threshold) | 0x20; // 設(shè)置成寄存器格式,并打開中斷// 最后一位寫入的時(shí)候,MAX17043會(huì)應(yīng)答MAX17043_WriteReg(MAX17043_CONFIG_MSB, buf, sizeof(buf), 1); }// 清除閾值電量中斷標(biāo)志位 void MAX17043_ClearAlert() {unsigned char buf[2] = {0x97, 0x1C};MAX17043_ReadReg(MAX17043_CONFIG_MSB, buf, sizeof(buf));buf[1] &= 0xDF;MAX17043_WriteReg(MAX17043_CONFIG_MSB, buf, sizeof(buf), 1); }總結(jié)
以上是生活随笔為你收集整理的MAX17043锂电池电量测量芯片C51驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 区块链会计案例_会计中区块链的特征 区块
- 下一篇: 懒人修仙传ce修改方法_凡人修仙传:韩立