实验5 CAN通信实验

1. 实验目的

按照指定协议,解析can报文,显示电压温度等信息。

说明:4.3寸及以上带can版本的串口屏,支持can通信。

2. 页面设计

(1)整数控件,显示电压值

(2)整数控件,显示温度值

(3)整数控件,显示SOC

(4)文本控件,显示故障信息

(5)can协议解析器控件,可以编写脚本代码,解析can报文。

图片资源,使用了一个480*272分辨率的背景图片。页面的背景图片额可以使用专业的绘图软件更加丰富、绚烂的背景图片。图片素材决定了显示的整体外观,让界面的设计更加容易。

字体字体除了工程自带的字库Tahoma_4x_ASCII(包括英文和数字),另外创建了一个中文的字库,双击这个字库,可以看到详细的信息。字库详细制作方法可以参考第三章的添加字库小节。

3. 串口屏协议处理

该例程使用了can解析器。串口屏每次收到一帧can数据,都会触发一次can解析器的脚本,和单片机的can中断函数类似。

协议定义(仅供参考)

扩展数据帧,波特率250K

ExdId

data[0~7]

0x1800AB01

[0~1]电池1电压值
[2~3]电池2电压值
[4~5]电池3电压值
[6~7]电池4电压值

小端模式,单位mV

0x1800AB02

[0~1]电池5电压值
[2~3]电池6电压值

小端模式,单位mV

0x1800AB10

[0] 温度1
[1] 温度2

小端模式,单位℃

0x1800AB11

[1] 温度3
[2] 温度4

小端模式,单位℃

0x1800AB12

[0]SOC

范围0~100

0x1800AB13

[0]故障信息
00 无故障
01 电池故障
02 温度故障
03 系统故障

选中can解析器,可看到事件编辑窗口,事件代码如下:

if(can.rxId == 0x1800AB01)
{
    cell1.val = (can.rxDataBuf[1]<<8)|can.rxDataBuf[0];  //电池1
    cell2.val = (can.rxDataBuf[3]<<8)|can.rxDataBuf[2];  //电池2
    cell3.val = (can.rxDataBuf[5]<<8)|can.rxDataBuf[4];  //电池3
    cell4.val = (can.rxDataBuf[5]<<8)|can.rxDataBuf[6];  //电池4
} 
else if(can.rxId == 0x1800AB02)
{
    cell5.val = (can.rxDataBuf[1]<<8)|can.rxDataBuf[0];  //电池5
    cell6.val = (can.rxDataBuf[3]<<8)|can.rxDataBuf[2];  //电池6
}
else if(can.rxId == 0x1800AB11)
{
    t1.val = can.rxDataBuf[0];//温度1
    t2.val = can.rxDataBuf[1];//温度2
    t3.val = can.rxDataBuf[2];//温度3
    t4.val = can.rxDataBuf[3];//温度4
}
else if(can.rxId == 0x1800AB12)
{
    soc.val = can.rxDataBuf[0];//SOC
}
else if(can.rxId == 0x1800AB13)  //故障信息
{
    if(can.rxDataBuf[0] == 0x00)
        fault.txt = "无故障";
    else if(can.rxDataBuf[0] == 0x01)
        fault.txt = "电池故障";
    else if(can.rxDataBuf[0] == 0x02)
        fault.txt = "温度故障";    
    else if(can.rxDataBuf[0] == 0x03)
        fault.txt = "系统故障";    
}

事件解析器的代码很简单,can.rxId存放报文id, can.rxDataBuf存放数据,数组长度8字节。按照协议解析数据即可。

4. 硬件过滤器的配置

显示屏接入can总线时,可以设置硬件过滤器。硬件上过滤掉不需要接收的报文,减少显示屏处理过多无用报文的压力,提高显示屏刷屏流畅度。设计can程序时,配置过滤器很有必要。

显示屏can收发调试过程中,可以不配置过滤器,方便调试。工程调试完成后,再将掩码和滤码设置成合适的值。

显示屏过滤器最多有14个,编号0~13,每个过滤器有两种过滤模式:屏蔽位模式、标识符列表模式

屏蔽位模式:

需要设置过滤标识符filter 和过滤掩码mask。硬件收到一帧can报文id时,按照mask为1的bit,与过滤标识符对比,全部mask位相同时,则接收该报文,否则拒收。换个说法:如果( id & mask) == filter , 接收此报文;否则不符合过滤要求, 不接收此报文。 适用于要接收can报文比较多且报文id有一定规律。

标识符列表模式:

硬件收到一帧can报文id时,与过滤器列表一一对应,如果有匹配的报文id则接收该报文,否则拒收。每个过滤器可以设置两个ID,所以最多可设置28个。适用于要接收的can报文比较少的情况,可以实现can报文的精准过滤。

——————————————————————————————————————————————————————

串口屏的过滤器设置可以通过项目设置界面配置(只能配置过滤器0的屏蔽位模式),也能在脚本里调用can控件的方法setFilter来配置(通过参数来配置过滤器的参数,可以灵活的设置的工作模式)。

1、项目设置界面;

打开 ”can通信实验.pix”工程,点击项目设置图标 ,可以查看到can的波特率、过滤报文的掩码和滤码。

这种配置方式,只能设置过滤器0的屏蔽位模式。适用于过滤器简单的设置,优点是配置简单

计算掩码mask和滤码filter的时候,考虑所有要接收的报文id,找出相同的bit和有差异的bit。该例程的所有要接收的报文有6个id,如下:

0x1800AB01

0x1800AB02

0x1800AB10

0x1800AB11

0x1800AB12

0x1800AB13

有差异的bit有[1:0]、[4],其余bit都是相同的。则mask的[1:0]、[4]为0,其他为1,即mask=0xFFFFFFEB。相同的bit即为filter,即filter=0x1800AB00。最后可将上面5个验证 是否( id & mask) == filter .

2、调用can控件的方法setFilter

当过滤的规则比较复杂时,建议使用setFilter方法来配置过滤器。

打开 ”can通信实验_setFilter.pix”工程,点击page0空白处,可以看到加载页面事件,脚本代码如下

这里需要注意的是,该脚本是首页的加载页面事件,用了一个变量startup来标记该脚本只执行一次,因为配置过滤器只需上电配置一次就可以了。

void  setFilter(u8 filterid,u8 mode,u32 param1, u32 param2);
/*
函数功能:配置can接收过滤器
参数1:filterid,过滤器编号,0~13
参数2:mode,过滤器模式,0屏蔽位模式,1标识符列表模式
参数3:param1,过滤器参数1,参数位定义见下表
参数4:param2,过滤器参数2,参数位定义见下表
*/

过滤器param1和param2位定义:

位31:21

STID[10:0]/EXID[28:18]:标准标识符或扩展标识符
依据IDE位的内容,这些位 或是标准标识符(11bit), 或是扩展标识符的高11bit

位20:3

EXID[17:0]扩展标识符低18bit

位2

IDE:标识符类型
0:标准帧
1:扩展帧

位1

RTR:远程发送请求
0:数据帧
1:远程帧

位0

保留位

标识符列表模式

can.setFilter(0,1,(0x1800AB01<<3)|0x04,(0x1800AB02<<3)|0x04); //过滤器0
can.setFilter(1,1,(0x1800AB10<<3)|0x04,(0x1800AB11<<3)|0x04); //过滤器1
can.setFilter(2,1,(0x1800AB12<<3)|0x04,(0x1800AB13<<3)|0x04); //过滤器2

屏蔽位模式

can.setFilter(0,0,(0xFFFFFFEB<<3)|0x04,(0x1800AB00<<3)|0x04); //过滤器0

方法setFilter的参数patam1和param2都与0x04按位或运算,表示只接收扩展帧。

注:

假如要接收标准帧,如0x6A1(标准帧),0x6A2(标准帧),可以这样设置:

CAN_Set_Filter2(0,1,0x6A1<<21,0x6A2<<21); //过滤器0,标识符列模式

或者

CAN_Set_Filter2(0,0,0xFFC<<21,0x6A0<<21); //过滤器0,屏蔽位模式

至于这里为什么是左移21位,可以参考上表param1和param2位定义。

5. 下载验证

编译成功后,点击下载按钮,选择正确的端口号和波特率,下载到串口屏。将串口屏接到can总线上,串口屏收到正确报文时,会解析并显示。

调试时,用任意can收发器的助手,给显示屏发报文测试即可。界面如下:

can调试工具发送数据

测试命令如下:

报文ID

数据

说明

1800AB01

E4 0C E4 0C E4 0C E4 0C

设置电池1~4

1800AB02

E4 0C E4 0C

设置电池5~6

1800AB10

20 20

设置温度1~2

1800AB11

20 20

设置温度3~4

1800AB12

60

设置SOC

1800AB13

00

故障信息