,,,,
(上海工程技术大学 汽车工程学院,上海 201620)
电动汽车车用锂电池发展十分迅速,预计未来几年动力电池将进入大量回收的阶段,因此需要考虑电池的回收、处理和再利用等问题。电动汽车的动力电池组寿命终结后,仍具有约70%~80%的容量,因此可将动力电池梯次利用于风光储能、智能电网的削峰填谷等[5]。本文设计了一套采集报文的装置,采用主控制芯片M2+CAN控制器,通过对电动汽车退役电池进行再测试,从BMS中获取与单体电池性能相关的报文,根据协议进行报文解析、计算,可筛选出一致性较好的电池,有助于提高能源利用率。
本文采用上海山意微电子技术有限公司研发的国产32位M2芯片作为主控制器,M2芯片有两个UART接口,但不带CAN接口,采用NXP公司的一种独立CAN控制器SJA1000,可在BasicCAN和PeliCAN两种协议下工作。其中BasicCAN支持CAN2.0A协议,PeliCAN工作方式支持CAN2.0B协议。CAN收发器采用TJA1050[1]。整体结构硬件模块包括:MCU主控制器、CAN 控制器、CAN 收发器,接收的报文可通过PC上位机软件窗口观察到。系统框图如图1所示。
图1 CAN总线报文采集系统框图
上海山意微电子技术有限公司自主研发的M2芯片,是基于MIPS架构的32位精简指令型处理器,拥有128 KB的Flash存储空间、2个UART/LIN通信串口、1个SPI通信接口、8路20位ADC采集模块以及丰富的I/O接口,温度稳定性高,满足使用需求。本文采用的SJA1000CAN控制器是NXP公司的一种独立CAN控制器,可在BasicCAN和PeliCAN两种协议下工作。其中PeliCAN工作方式可接收扩展帧,29位标识符。由于本文采集的是电池管理系统发出的CAN报文,均为扩展帧、数据帧,因此选择PeliCAN工作方式。
CAN控制器SJA1000内部包含128个8位的寄存器,不带有MCU处理器,相当于是主控制器M2的外部RAM空间,主控制器可通过读、写时序对SJA1000的寄存器进行访问和设置,因此首先要对访问时序进行软件编程,实现主控制器与CAN控制器之间的通信,本文采用Intel模式下的交流时序。
写时序图如图2所示。
图2 写时序图
WR_SJA_REG(volatile int ADD,volatile int DATA){
/*初始化引脚*/
MemoryWrite32(SPI_CTL_REG,0x8);
//关闭SPI复用引脚功能
MemoryWrite32(U1_CTL0_REG,0x10);
//关闭UART引脚功能
MemoryWrite32(A_SDV2P_CTL_REG,0x0);
//关闭SD引脚功能
int p,i;
/*芯片I/O口引脚配置,单向I/O SEG口引脚配置*/
RT_GDR_BIT_OFF(0); //SEG 20 ==GDR 0 ALE
RT_GDR_BIT_ON(1); //SEG 21 ==GDR 1 RD
RT_GDR_BIT_ON(2); //SEG 22 ==GDR 2WR
RT_GDR_BIT_ON(3); //SEG 23 ==GDR 3CS
RT_IOCTL_Set32(0xFFFF); //设置I/O口为输出
RT_GDR_BIT_ON(0); //ALE HIGN
for(i=0;i<5;i++);
ADD=ADD<<6;
RT_GPIO_Write32(ADD); //M2向SJA1000发送地址
for(i=0;i<5;i++);
RT_GDR_BIT_OFF(0); //ALE LOW
for(i=0;i<5;i++);
RT_GDR_BIT_OFF(3); //CS LOW
for(i=0;i<5;i++);
RT_IOCTL_Set32(0xFFFF); //设置I/O口为输出
for(i=0;i<5;i++);
RT_GDR_BIT_OFF(2); //WR LOW
for(i=0;i<5;i++);
DATA=DATA<<6;
RT_GPIO_Write32(DATA); //M2向SJA1000发送数据
p=RT_GPIO0_Read32();
p=p>>6;
p=p&0Xff;
for(i=0;i<5;i++);
RT_GDR_BIT_ON(2); //WR HIGN
for(i=0;i<5;i++);
RT_GDR_BIT_ON(3); //CS HIGN
for(i=0;i<5;i++);
return p;
}
由于脉宽保持时间需要保持大于一定的时间,且时序的正确配合十分重要,程序中利用for延时不同的时间来实现。同时,采用的GPIO口为复用引脚,需先关闭本控制芯片的SPI、UARTt和SD的复用引脚功能。同理,读交流时序如图3所示。
图3 读时序图
读时序与写时序都是主控制器锁定目标寄存器,但读操作是直接把SJA1000寄存器的值读取回来,当先向SJA1000发送完地址以后,把8路A/D总线I/O口设置为输入后,寄存器中的数据就会自动发送回来。一次读时序包括由主控制器向SJA1000发送寄存器地址后,把A/D数据地址总线设置为输入,读回数据。读时序程序如下:
RD_SJA_REG(volatile int ADD){
……
//向SJA1000发送地址部分内容和写时序部分相同
RT_IOCTL_Set32(0x0); //设置GPIO为输入
for(i=0;i<5;i++);
RT_GDR_BIT_OFF(1); //RD LOW
for(i=0;i<5;i++);
p=RT_GPIO1_Read();
p=p>>6;
p&=0xff;
for(i=0;i<5;i++);
RT_GDR_BIT_ON(1); //RD HIGN
for(i=0;i<5;i++);
RT_GDR_BIT_ON(3); //CS HIGN
for(i=0;i<5;i++);
return p;
}
读、写时序程序设计好以后,接下来的对寄存器的配置、SJA1000的初始化、报文的接收和发送都是基于此通信时序进行相关寄存器的配置,因此读写时序程序的设计十分重要。为测试此读写时序的正确性,采用逻辑分析仪进行观察检测,得到的读时序图和写时序分别图4和图5所示。
图4 逻辑分析仪读时序
图5 逻辑分析仪写时序
CAN控制器控制SJA1000进行报文的接收和发送之前,需要在复位模式下对SJA1000进行初始化操作[2]。主要操作内容包括配置时钟分频寄存器、操作模式、设置验收代码寄存器和验收屏蔽寄存器,设置通信波特率等。初始化程序如下:
int Sja1000_Init(){
int s,a;
s=ENTER_RSTMODE(); //置位复位请求和单滤波模式
s=TEST_COMMUNI_REG();
//写入测试寄存器,查看读写功能是否正确
s=SET_CLOCK_REG(0xC8);
//选择Pelican模式,禁能外部时钟引脚Intel模式
s=SET_ACCEPT_FILTER(0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF);//屏蔽寄存器,设为无关,可接收所有报文
//当屏蔽位为1不滤波,屏蔽为位0就表示可以导通相同ID
s=SET_BAUDRATE(ByteRate_125k);//选择波特率
WR_SJA_REG(REG_OCR,0x1A);
//输出控制寄存器——正常输出模式
WR_SJA_REG(REG_INTENABLE,0x1D);
//设置中断,接收和发送中断
//唤醒中断使能,数据溢出中断使能,错误报警中断使能,
//发送中断使能,接收中断使能
a=RD_SJA_REG(REG_CONTROL);
a&=0xfe;
WR_SJA_REG(REG_CONTROL,a);
//退出复位模式,进入工作模式,寄存器末尾功能位置0
return 0;
}
本文中需要接收的报文是扩展帧、数据帧,因此选择PeliCAN工作方式支持CAN2.0B协议。帧信息占一个字节,帧ID分配4个字节,使用29位,帧数据分配8个字节,设置单滤波模式,设置4个验收代码寄存器ACR和4个验收屏蔽寄存器AMR,下面以一个寄存器为例,验收代码寄存器定义如下:
位76543210功能AC.7AC.6AC.5AC.4AC.3AC.2AC.1AC.0
验收屏蔽寄存器AMR定义如下:
位76543210功能AM.7AM.6AM.5AM.4AM.3AM.2AM.1AM.0
ACR的每一位和AMR一一对应,验收屏蔽为0表示相关,即只接收和验收代码寄存器帧ID相同的报文。反之为1表示无关,即接收所有报文。本文中接收到的报文是把来自科列的报文导入到上位机软件USB_CAN TOOL中发送出来,所以设置为FF,接收所有报文即可。
一条完整的报文包含三部分内容:帧信息、帧ID、帧数据。帧信息解释了帧的格式和数据长度;标准帧ID为11位,扩展帧ID为29位标识符;帧数据寄存器中保存报文的数据。收到的报文CAN核心模块把串行位流转换成并行数据,经过验收滤波器存储在FIFO中。M2主控制器通过中断轮询的方式访问SJA1000。当接收到报文后产生接收中断,M2从缓冲区读取报文,并释放接收缓冲区,继续根据中断情况读取下一条报文。其CAN 报文接收程序如下:
while(1){
int0=RT_SEG_Read(1);
WR_SJA_REG(REG_INTENABLE,0x01);
//设置M2接收中断使能
if(int0==0){ //模拟下降沿触发
a=RD_SJA_REG(REG_INTERRUPT);
//读取中断寄存器只有读寄存器不会置位
if(a&0x01){
b=RD_SJA_REG(REG_RXBuffer1);
length=b&0x0f;
if((b&0x40)!=0x40){//数据帧=为远程帧
h=0;
for(i=0;i<4;i++){
f=RD_SJA_REG(REG_RXBuffer5-i);
g=f<<(8*i);
h+=g;
}
h=h>>3;//帧ID信息
puts(“ID:”);
puts(xtoa(h));
for(i=0;i //数据扩展帧从buffer6标准帧到buffer4 c=RD_SJA_REG(REG_RXBuffer6+i); puts(xtoa(c)); } …… WR_SJA_REG(REG_COMMAND,0x04);//释放缓冲区// } } M2通过判断在这之前的最后一次发送是否成功,若成功则将需要发送的报文通过A/D总线发送到发送缓冲区,发出发送命令后,将报文发出。在硬件上,当按下Key键时,进行报文发送。其CAN 报文发送程序部分如下: key=RT_SEG_Read(0); //按键key值写入寄存器数据// if(key==0){ e=RD_SJA_REG(REG_STATUS); e&=0x04; if(e==0x04){ //CPU可以向发送缓冲区写信息 WR_SJA_REG(REG_TXBuffer1,0x05); //发送报文的信息 WR_SJA_REG(REG_TXBuffer2,0x00); WR_SJA_REG(REG_TXBuffer3,0x01); WR_SJA_REG(REG_TXBuffer4,0x42); WR_SJA_REG(REG_TXBuffer5,0x42); WR_SJA_REG(REG_TXBuffer6,0x42); WR_SJA_REG(REG_TXBuffer7,0x42); WR_SJA_REG(REG_TXBuffer8,0x42); WR_SJA_REG(REG_TXBuffer9,0x42); WR_SJA_REG(REG_TXBuffer10,0x42); WR_SJA_REG(REG_TXBuffer11,0x42); WR_SJA_REG(REG_COMMAND,0x03);//发送命令 } } 本文主要使用的是报文的接收功能。以接收为实例,硬件连接完成后,将在与M2配套的编译环境Camel Studio中编写的软件程序下载到M2中,同时通过使用CAN分析仪来模拟BMS给该报文采集装置发送报文。 通过CAN分析仪提供的上位机软件USB_CAN TOOL模拟BMS发送CAN 报文,在USB_CAN TOOL上位机软件中导入所需发送的报文,本文摘取报文的部分信息,导入的报文信息如图6所示,报文信息来自科列公司提供的BMS的报文和报文解析协议。在PC机上打开Camel Studio软件,将编译后的CAN报文接收程序下载到M2中,运行后即可接收到USB_CAN TOOL发出的报文。实物连接图如图7所示。 图6 导入报文信息内容 图7 实验实物连接图 由CAN 分析仪发出的报文信息导入后如图8所示。由M2和其上位机软件Camel Studio接收到的报文及显示如图9所示。 图8 CAN 分析仪发出报文信息显示 图9 M2上位机软件Camel Studio接收报文显示 报文接收到以后,可根据电池厂家提供的协议进行翻译,本质上是匹配ID后对数据按照协议规则进行计算。报文解析如图10所示。 图10 报文解析 由此可以得到电池的电压值,根据这些值计算出单体电池的直流内阻。本实验的电池工况是先让电池处于开路状态,电流为0 A,测得电压值U1,再进行5 A放电,测得电压值为U2,时间为T2。从而可进一步计算T2时刻下电池的直流内阻,直流内阻=(U1-U2)/5。如图11所示。 图11 单体电池直流内阻分布图 图11的横坐标表示电池的序号,一共是84节电池。纵坐标表示电池的直流内阻,单位为欧姆。由图可知,有5颗电池的直流内阻值偏大,其余电池整体的一致性比较稳定。用此方法同时也可测得不同时间、不同工况下的直流内阻值。 本文根据接收退役电池组的BMS发出的CAN报文,设计了一套主控制芯片M2+SJA1000的装置,并为该装置芯片之间实现通信和控制芯片接收CAN报文设计编程,成功实现报文的获取。同时如需对验收滤波寄存器进行相应的配置,只需要在复位模式下在软件程序中修改相关寄存器值。3.4 发送CAN报文
4 实例验证
结 语