文献标识码: A
DOI:10.16157/j.issn.0258-7998.2016.04.014
中文引用格式: 何国锋,刘宇红. 基于SMBus协议的电池信息监测系统[J].电子技术应用,2016,42(4):49-52.
英文引用格式: He Guofeng,Liu Yuhong. Battery information monitoring system based on SMBus protocol[J].Application of Electronic Technique,2016,42(4):49-52.
0 引言
SMBus协议是Intel公司(联合其他公司)在PC-I2C基础上研发出来的系统管理总线协议。最初是为智能电池、充电电池和与其他系统通信的微控制器之间的通信链路而定义的[1],后来也被用来连接各种设备,包括电源相关设备、系统传感器、EEPROM通信设备等。其被广泛用于笔记本电脑上,检测各元件状态并更新硬件设置引脚。它为系统和电源管理这样的任务提供了一条控制总线,使用SMBus总线的系统,设备之间发送和接收消息都是通过SMBus总线,而不是使用单独的控制线,这样可以节省设备的管脚数。随后,Intel公司联合其他公司在此基础上创建了智能电池管理标准,SMBus成为在智能电池及低速率管理设备上被广泛采用的协议标准。
1 SMBus协议分析
SMBus由两根总线,即串行数据线(SDA)和串行时钟线(SCL)构成[2],主要用于主从系统。由于 SMBus是双向通信,因此在设计电路时两条线上都需要外接上拉电阻,数据可以在总线空闲时间进行传输。
1.1 SMBus启动和停止条件
在总线处于空闲状态时,SMBus总线上的SCL和SDA都被上拉电阻拉至高电平。此时,当SDA由高电平变为低电平,总线启动SMBus协议传输。启动条件产生后,总线就被视为忙的状态; 当SCL为高电平时,SDA由低电平变为高电平,SMBus传输停止[3],停止条件发生一段时间后,总线再次被视为空闲状态。启动条件和停止条件总是由主设备产生,图1为模拟SMBus协议启动和停止的时序图,S表示启动条件,P表示停止条件。
1.2 数据的有效性
SDA线上的数据必须在时钟的高电平周期保持稳定,数据线上的电平只有在SCL线为低电平时才可以改变[3]。图2为SMBus协议数据有效性的图示。
1.3 SMBus数据传输
图3是SMBus数据传输协议时序图,当SMBus启动信号产生后,数据以串行方式进行传输,每次传输以8 bit(1 B)为一组,每次可发送的字节数不受限制,但是每个字节后必须跟一个响应位。数据以高字节在前、低字节在后的顺序传输,第9位为应答位[2]。
总线上的所有器件都有一个唯一地址,并且都可以工作在接收或发送状态,构成了4种工作模式,即主发送、主接收、从发收、从接收[3]。SMBus总线还具有仲裁功能,保证同一时刻只有一个器件在控制总线。
2 硬件实验环境
2.1 主机系统实现
主机系统采用了以MSP430F149处理器为核心的开发板,MSP430是德州仪器公司推出的一款16位、具有超低功耗芯片及精简指令集(RISC)的混合信号处理器(Mixed Signal Processor)[4],被广泛用于智能便携电子设备中。开发板上拥有较丰富的外设资源,同时集成了RS232模块,可以将测得的数据信息等通过串口实时发送到上位机中,查看验证结果。
2.2 智能电池
目前大部分智能电池对外接口都遵循SMBus协议标准,本设计采用的智能电池是一块由4节锂电池组成的智能电池组,采用德州仪器的BQ3060电源管理芯片进行电池管理。BQ3060芯片可以对最多4节电池构成的电池组进行管理,将普通电池组变成智能电池,并通过SMBus总线接口与处理器通信。
将MSP430处理器与智能电池以及其他外围器件同时挂载到接有上拉电阻的SMBus总线上,如图4所示。MSP430处理器为主机,总线上的其他设备充当从机。当启动传输协议时,MSP430可以通过SMBus总线获得4节锂电池的相关信息。
3 SMBus协议软件实现
3.1 SMBus启动
在初始时刻,总线处于空闲状态,数据线和时钟线都被拉高,此时拉低数据线,SMBus启动。下面是模拟SMBus协议的启动代码:
void SMBus_Start()
{
SDA=1; delay(); //数据位置1
SCL=1; delay(); //时钟位置1
SDA=0; delay(); //数据位置0,启动
SCL=0; delay(); //时钟位置0
}
3.2 SMBus停止
在时钟线为高时,当数据线被拉高,SMBus停止。以下是模拟SMBus协议停止代码:
void SMBus_Stop()
{
SDA=0;delay(); //数据位置
SCL=1;delay(); //时钟位置1
SDA=1;delay(); //数据位置1,停止
}
3.3 SMBus检测应答
在数据传输的第9个时钟,主机需要检测总线上SDA的电平是否被拉低,如果规定的时钟周期内未检测到低电平,视为无应答,说明传输失败;如果检测到低电平,说明从机成功接收到数据,可以继续下一步传输。代码如下:
bit SMBus_CheckAck()
{
unsigned char i;
SCL = 1;delay();
while((SDA)&&(i<256)) //检测有无应答
i++; //数据位置1
SCL = 0;delay();
if(255 != i) //超时检测
return 0;
else
return 1;
}
3.4 SMBus发送应答
当主机接收完从机发来的8 bit数据后,需要在第9个时钟周期内做出应答,并且告诉从机是否继续通信。如果继续通信,则拉低SDA电平;如果希望终止通信,则拉高SDA上的电平。代码如下:
void SMBus_SendAck(bit n)
{
unsigned char i;
if(n) SDA = 1;
else SDA = 0;
SCL = 1;delay();
SCL = 0;
}
3.5 SMBus读取字节
从SMBus总线上读取字节按照从高位到低位的顺序逐位读取,编程时在时钟为高时读取到的值保存到变量中并返回。
unsigned SMBus_ReadByte()
{
unsigned char i,k=0;
for( i = 0;i < 8;i++ ) //读8 bit数据
{
SCL = 1;delay();
k = (k << 1) | SDA; //按位读取
SCL = 0;delay();
}
return k; //返回字节
}
3.6 SMBus写入字节
向SMBus总线上写入字节时从高位到低位依次写入,写入完一个字节后将数据总线拉高。
void SMBus_WriteByte(unsigned char data)
{
unsigned char i;
temp = data;
for(i=0;i<8;i++) //按位写入
{
SCL = 0;delay();
if((data<<i)&&0x80)
SDA = 1;
else
SDA = 0;delay();
SCL = 1;delay();
}
SCL=0;delay();
SDA=1;delay()://拉高数据线,为等待应答做准备
}
3.7 SMBus通信协议帧
使用SMBus协议对设备信息进行读取时有统一的标准要求,图5是SMBus设备间通信协议帧结构图。最先传输的是启动条件S,随后发送第一帧数据,由7位设备地址DevAdd、1位写标志W和1位应答Ack构成。第二帧由8位设备内的寄存器地址RegAdd和1位应答Ack构成,如要读取电池的温度,RegAdd则为温度寄存器。其中前两帧都是主设备向总线上写信息,告诉了总线要写入的设备地址,以及要获得设备中哪个寄存器的内容。接下来要再次发送启动信号S进行一次重启。第三帧数据由7位设备地址DevAdd、1位读标志位R、1位应答Ack构成;第四帧由8位数据Data1和1位应答Ack构成;第五帧也由8位数据Data2和1位应答Ack构成。其中第三帧数据告诉了总线要对哪个设备进行读取操作,第四帧和第五帧则由主机从总线上两次读取数据,得到Data1和Data2,这两个字节分别为读取值的高8位和低8位。最后是一位停止信号P。
将协议中包含的数据帧按照图5格式进行打包,统一写成函数以方便应用。代码如下:
unsigned int SMBus_ReadAdd(unsigned char addr)
{
unsigned char data;
SMBus_Start();//启动协议
SMBus_WriteByte(DEV_ADDW);//设备地址
SMBus_CheckAck();//等待应答
SMBus_WriteByte(addr);//Reg地址
SMBus_CheckAck();//等待应答
SMBus_Start();//再次启动
SMBus_WriteByte(DEV_ADDR);//设备地址
SMBus_CheckAck();//等待应答
data = SMBus_ReadByte();//读取低字节
SMBus_SendAck(0);//发送应答
data+=SMBus_ReadByte()<<8;//读取高字节
SMBus_SendAck(1);//发送应答
SMBus_Stop();//停止读取
return data;//返回数据
}
3.8 主程序设计
主程序中最先要通过SMBus总线向智能电池发送命令,对BQ3060芯片进行初始化配置,然后调用SMBus_ReadAdd函数即可获得电池相关信息,如电池电压和相对电量Reg地址分别为0x09、0x0d,其他寄存器请参考芯片手册。调用方法如下:
void main()
{
Init_Config();//初始化
Voltage =SMBus_ReadAdd(0x09)&0x7FFF;
delay_ms();//读取后要延迟一段时间
PowerState=SMBus_ReadAdd(0x0d)&0x7F;
delay_ms();
UartSend();//从串口输出
}
读取字节时,SMBus_ReadAdd(0x09)&0x7FFF和SMBus_ReadAdd(0x0d)&0x7F因为电压返回值范围是0~20 000 mV,电量状态范围为0~100%,为防止数据出错,要对有效位进行选取,同时读取数据后一定要进行延时操作,否则读数结果会出现错误。
4 设计结果与分析
IAR EW for MSP430是IAR公司为TI公司的MSP430系列处理器开发的一款集成开发环境,可对工程进行有效管理、编译、链接后生成目标文件,并结合MSP专门的USB烧录器进行程序下载。
通过MSP430F149开发板自带的RS232模块与笔记本USB口相连,MSP430将监测到的电池信息通过Uart0口发送到串口助手,最开始测得的所有数值都存在错误,通过对程序进行分析,发现在使用SMBus进行读取数据时没有设置一定的延时等待,加上延时函数后结果正常,但依然错误率很高。在查阅了BQ3060数据手册后才发现电压的有效值是0~20 000 mV,电量的有效值是0~100%,每次需要对读到的值进行有效位的提取,如SMBus_ReadAdd(0x09)&0x7FFF和SMBus_ReadAdd(0x0d)&0x7F语句处理后,输出结果正确,如图6。
用电压表测电池两端的电压为15.9 V,与系统的15 943 mV一致,室内空调显示温度为26 ℃,考虑到电池使用过程会发热,因此温度会比室温高一些。通过检测出来的数据可以看出,用SMBus协议可以很方便地对智能电池信息进行监测,同时不需要处理器亲自去检测电池的各种信息,节省了处理器的时钟,可以使处理器更多的时间用在算法、控制等处理上。
5 小结
本文实现了一个使用SMBus协议对电池信息进行实时监测的系统,系统准确监测到电池电压、电量、温度等重要信息。在实际应用中,可以根据需要对电池的其他信息进行监测,相关寄存器地址可以参考TI公司数据手册。虽然使用以BQ3060为管理芯片的智能电池作为实验平台,但是系统适合于对所有使用SMBus协议的智能电池进行监测,TI公司BQ系列电源管理芯片基本都支持SMBus协议,只需对设备地址、寄存器地址做相应改变就可达到通用的目的。
参考文献
[1] 路铁生.系统管理总线(SMBus)与智能充电[J].电源世界,2011(8):36-39.
[2] 陈涛,万亚坤.基于智能电池系统的SMBus总线研究及IP设计[J].中国集成电路.2008(11):48-51.
[3] 吴珍毅.基于SMBus的智能锂动力电池总线系统的实现[J].北京联合大学学报,2012,26(4):15.
[4] 郝建国.MSP430微控制器基础和应用[M].北京:电子工业出版社,2014.