tt99166 发表于 2023-11-20 14:21:58

在MATLAB中通过CAN总线与ECU(C37)实现通信

1、简介

首先说一下目前实现的功能吧。目前这个程序只是能实现基本的控制器与PC信息的互传,通过PC上的MATLAB发送信息给控制器,控制器通过相应的库函数实现信息的上传。至于为什么实现类似上位机软件的功能用MATLAB而不是用其它的软件或者语言(如C#等)来写,原因也很简单,因为我太喜欢MATLAB这个软件了。虽然现在只是实现了简单的信息的收发,后面可以使用MATLAB的GUI做相关的人机交互页面,也可以直接把数据保存成MATLAB的变量为进一步的数据分析做准备。这两天为了实现这个功能看了一些资料,但使用MATLAB实现这个功能的帖子好像不是很多,所以这篇文章就当是抛砖引玉啦,也为了以后哪一天我要是忘记了一些操作能给我提供一些提醒。

2、硬件准备   

ECU控制器(C37)、USB-CAN模块(乐电新南 USB/CAN转换器 隔离型)、ECU下载线一条
3、软件准备

MATLAB R2019a、Codesys V2.3、串口调试助手以及CAN模块配置软件(USB-CAN模块的商家应该会提供)
4、实现路线

      实现路线会按照控制器—>USB/CAN转换模块—>MATLAB这个思路来。
4.1、控制器部分

       控制器部分按照正常的控制器(C37)中CAN通信的库函数写好,要注意控制器设置的CAN总线的波特率,这个参数在下面的模块参数配置中会用到。下面的控制器程序中略去了相关初始化的部分(其中波特率设置为250kbps)。
变量区:
PROGRAM PLC_PRG
VAR
        CAN_read_message:FB_CAN_READ_MSG;(*CAN读取信息的功能块实例化*)
        CAN_send_message:FB_CAN_SEND_MSG;(*CAN发送信息的功能块实例化*)
        canton:TON;
        data_send:ARRAYOF BYTE;
        data_receive:ARRAYOF BYTE;
        ii:BYTE;
        booting:BOOL:=TRUE;
        status_configure_read:INT:=5;      (*函数状态返回量*)
        status_configure_send:INT:=5;
        status_read:BOOL:=FALSE;
        status_configure_read_Msg50: INT:=5;
        bootingnmt: BOOL:=TRUE;
END_VAR程序主体:
(****相关的库函数参考C37库函数介绍****)
init();(*控制器初始化程序*)

IF booting=TRUE THEN
status_configure_read:=CAN_MSG_CONFIG(MsgObj:=Msg151,Mode:=Rx,ID:=16#01,Mask:=16#FFFFFFFF,IdFormat:=Standard,LEN:=8);
status_configure_send:=CAN_MSG_CONFIG(MsgObj:=Msg61,Mode:=Tx,ID:=16#281,Mask:=16#FFFFFFFF,IdFormat:=Standard,LEN:=8);
status_configure_send:=CAN_MSG_CONFIG(MsgObj:=Msg150,Mode:=Tx,ID:=16#FFFF,Mask:=16#FFFFFFFF,IdFormat:=Standard,LEN:=8);
booting:=FALSE;
END_IF


IF CAN_NEWDATA(Msg151)=1 THEN
    CAN_read_message(MsgObj:=Msg151);
    IF CAN_read_message.Status=1 THEN
      FOR ii:=0 TO 7 BY 1 DO
            data_receive:=CAN_read_message.Data;
      END_FOR
    END_IF
END_IF



FOR ii:=0 TO 7 BY 1 DO
    data_send:=16*ii;
END_FOR


canton(IN:=TRUE,PT:=T#50ms);

IF canton.Q=TRUE THEN
    (*CAN_send_message(MsgObj:=Msg61,ID:=16#281,IdFormat:=Standard,LEN:=8,Data:=data_send);
*)
    CAN_send_message(MsgObj:=Msg150,ID:=16#FFFF,IdFormat:=Standard,LEN:=8,Data:=data_send);
    canton(IN:=FALSE);
END_IF控制器内的程序实现的功能仅仅是接收与发送程序。
4.2、USB/CAN转换模块

      转换模块部分的参数设置如图1所示:


图1:CAN模块配置软件中相关参数的设置
      图1中的串口号在自己电脑的设备管理器中查看,串口波特率参数在接下来的MATLAB串口通信中会用到,CAN波特率与控制器(这里指C37)匹配,包模式以及接收设置参考乐电新南的模块使用说明(他们家的说明我感觉很nice!!),模块实物图如图2、图3所示:


图2:USB/CAN转换器正面图


图3:USB/CAN转换器模块反面图
这里要注意一下,即使按照模块资料操作配置模块的参数依然可能参数配置不成功(我就是因为这一点折腾了大半个下午)。如果在使用串口调试助手测试接收到的信息时,在你设置的串口波特率下接收到的信息不是你控制器设置的发送的信息,这个时候要考虑是不是USB/CAN模块配置参数不成功(即使CAN模块配置软件显示已经配置成功了,实际上依然没有配置成功)。可以把模块上mode的两个针脚短接来强制进入配置模式,具体操作参考USB/CAN模块的使用方法资料。
4.3、MATLAB端

      MATLAB端的操作依次为下图所示(这里是MATLAB R2019的情况下):








(补充:完成操作5之后单击右上角的“Connect”键)




注意:上图的参数设置中“Size(optional)”的值不是固定的,这个要根据模块生产厂家的报文格式决定,乐电新南的报文格式是16位,微雪的报文格式是20位(微雪技术支持说是13位,然后在MATLAB中实际得到的是20位)。确定位数的方法是:在控制器循环发送同一组数据并且波特率等参数的设置正确时,数据有多少位会循环,n位循环一次报文格式就是n位,也可以参考厂商的报文格式。


通过上图的最后一步操作可把接收到的报文数据导出到MATLAB的变量区。报文的数据格式如下图(该报文格式仅为乐电新南模块的报文格式,不同厂商生产的模块,其报文格式可能会有不同):


在发送报文时要把报文按照格式写好,各位之间用空格间隔,例如:


至此,已完成MATLAB与控制器之间通过CAN总线实现通信,如果要生成脚本代码,操作如下图:


完整例程如下:
%% Instrument Connection

clear
clc
% Find a serial port object.
obj1 = instrfind('Type', 'serial', 'Port', 'COM3', 'Tag', '');

% Create the serial port object if it does not exist
% otherwise use the object that was found.
if isempty(obj1)
    obj1 = serial('COM3');
else
    fclose(obj1);
    obj1 = obj1(1);
end

%% Disconnect and Clean Up

% Disconnect from instrument object, obj1.
fclose(obj1);

%% Instrument Connection

% *******串口通信波特率默认9600*********
% 串口USB转CAN模块相关参数设置
% 串口波特率9600
% CAN信号波特率250K(在codesys程序中定义,模块CAN波特率要和控制器程序中设置的相同)
set(obj1, 'BaudRate', 9600);
set(obj1, 'InputBufferSize', 4096);
set(obj1, 'OutputBufferSize', 4096);

% Connect to instrument object, obj1.
fopen(obj1);
%% Instrument Configuration and Controldata1

% Communicating with instrument object, obj1.
data1 = fread(obj1, 16, 'uint8');
data2 = fread(obj1, 16, 'uint8');
data3 = fread(obj1, 16, 'uint8');
data4 = fread(obj1, 16, 'uint8');
%% Instrument Configuration and Control

% Communicating with instrument object, obj1.
fwrite(obj1, , 'uint8');
% fwrite(obj1, , 'uint8');5、其它

1、当在MATLAB端接收到的信息不是控制器设置的发出的信息,首先怀疑是不是USB/CAN转换模块的相关参数(尤其是串口波特率和CAN波特率)配置的问题,尤其要注意CAN模块配置软件的虚假配置成功,是否是虚假配置成功可以通过串口调试助手在(虚假)配置成功的波特率下是否能接收到预期的信息,如果不是预期信息,考虑CAN串口配置助手的虚假配置成功。
2、当MATLAB端遇到Error时考虑接收信息参数设置中接收数据位数是否设置为报文格式规定的位数。
3、MATLAB端的信息接收的操作应为:首先设置好相关参数只差点击“Read”键,如果控制器发送数据之后才设置相关参数做数据接收准备会出现接收报文信息缺失的情况,比如16位的报文缺失前面几位,后面的报文的前面几位又顶到前面报文的后面几位,出现数据错位。
4、串口调试助手出现串口错误时考虑把模块拔下来重新插上去可解决这个问题。
5、在MATLAB端设置串口参数时会出现参数设置迟缓的问题,可以检查它Session log相应的代码是否写上,一般是波特率设置和输入输出缓存区大小的设置会有代码。
      至此,我能想到的,能出现的问题基本都写完了,如果后期在这个基础上加一些其它操作再见后文。
祝各位早安、午安、晚安!

life 发表于 2024-1-3 10:40:18

感谢分享 学习一下
页: [1]
查看完整版本: 在MATLAB中通过CAN总线与ECU(C37)实现通信