本系列以初学者角度记录学习CANOE,以《CANoe开发从入门到精通》参考学习,CANoe16 demo版就可以进行学习
创建工程
在一个路径中,创建这几个文件夹
创建工程,将工程命名Vehicle_System_CAN.cfg
创建Database dbc文件
在实际开发中,需要拿到整车厂的dbc文件。
VehicleSystem.dbc
创建message
创建 value Table
创建信号
剩下信号按前面类似操作创建
将signels和message进行关联
用鼠标点击对应的信号 拖到 报文下
创建网络节点 右键Network nodes
BCM 节点添加接受报文
添加发送报文
创建IPC和Gateway节点操作类似,需要添加对应的接受报文和发送报文
如果开始位和位的长度对不上,需要修改,修改报文下的信号的开始位,就是就是信号发送的顺序和信号的大小
有几个地方需要注意message 需要修改:
加入到工程中
创建系统变量
Cluster、Vehicle_Contrl和Vehicle_Key
Cluster
Vehicle_Contrl
Vehicle_Key
Panel
CAPL代码实现
右键总线,Insert Network Node,插入三个网络节点,分别命名IPC、BCM和Gateway
分别双击三个网络节点,编写CAPL代码(BCM.can、IPC.can、Gateway.can)
BCM.can
/*@!Encoding:1252*/
includes
{
//To add the head files
}
variables
{
msTimer msTcrank; //define the timer(ms) for crank delay
msTimer msTIL; //define the timer(ms) for deactivate CANoe IL
int flashPeriod=500; //Hazards flash cycle
int TurnLightStatus; //define the turn light status: 0 - both off; 1 - Left flash; 2 - Right flash; 3 - Hazards on
msTimer msTleftflash,msTrightflash; //define the timers(ms) for Left/Right Light flash
message Driver_Info Msgdriver; //define the message for driver info
}
on preStart
{
ILControlInit(); //Initialize CANoe IL
ILControlStop(); //Deactivate CANoe IL
}
//to process the key position
on sysvar_update Vehicle_Key::Key_State
{
$Ignition_Info::KeyState=@this;
if(@this==3)
{
@Vehicle_Control::Speed_Up=0;
setTimer(msTcrank,800); //Simulate the crank behavior
}
}
//return to Run status from Crank after 800ms
on timer msTcrank
{
$KeyState=2; //Simulate the crank behavior
@sysvar::Vehicle_Key::Key_State =2;
}
//to process the driver ID change
on sysvar_update Vehicle_Key::Car_Driver
{
//Set the value of driver ID based on system variable Car_Driver
if(@this==1)
{
Msgdriver.byte(0)=0;
}
else if(@this==2)
{
Msgdriver.byte(0)=0x1;
}
output(Msgdriver);
}
//to process the event of Unlock Car
on sysvar_update Vehicle_Key::Unlock_Car
{
if(@this==1)
{
ILControlStart();
$LockStatus=1;
@Vehicle_Key::Car_Driver=2;//driver 2 is set to default
}
}
//to process the event of Lock Car
on sysvar_update Vehicle_Key::Lock_Car
{
if(@this==1)
{
$LockStatus=0;
setTimer(msTIL,1500); //wait 1.5s to make sure other ECUs are offline
}
}
ON Timer msTIL
{
ILControlStop();
}
void LightOFF(void)
{
//Initilize the light status
$VehicleLight=0;
TurnLightStatus=0;
$LightStatus=0;
}
To realize the functions of turn left,turn right and Hazards///
on sysvar Vehicle_Control::Left_Turn_Enable
{
if(@this==1)
{
@sysvar::Vehicle_Control::Right_Turn_Enable=0;
$VehicleLight=1;TurnLightStatus=1;
settimer(msTleftflash,flashPeriod);
}
else
{
if(@Vehicle_Control::Right_Turn_Enable==0 && @Vehicle_Control::Hazards_Enable==0)
{
LightOFF();
}
cancelTimer(msTleftflash);
@Cluster::Left_Turn_Indicator=0;
}
}
on timer msTleftflash
{
$LightStatus=!$LightStatus;@Cluster::Left_Turn_Indicator=!@Cluster::Left_Turn_Indicator;
setTimer(msTleftflash,flashPeriod);
}
on sysvar Vehicle_Control::Right_Turn_Enable
{
if(@this==1)
{
@sysvar::Vehicle_Control::Left_Turn_Enable=0;
$VehicleLight=2;TurnLightStatus=2;
settimer(msTrightflash,flashPeriod);
}
else
{
if(@Vehicle_Control::Left_Turn_Enable==0 && @Vehicle_Control::Hazards_Enable==0)
{
LightOFF();
}
cancelTimer(msTrightflash);
@Cluster::Right_Turn_Indicator=0;
}
}
on timer msTrightflash
{
$LightStatus=!$LightStatus;@Cluster::Right_Turn_Indicator=!@Cluster::Right_Turn_Indicator;
setTimer(msTrightflash,flashPeriod);
}
on sysvar Vehicle_Control::Hazards_Enable
{
if(@this==1)
{
$VehicleLight=3;@Cluster::Left_Turn_Indicator=1;@Cluster::Right_Turn_Indicator=1;
settimer(msTleftflash,flashPeriod);setTimer(msTrightflash,flashPeriod);
}
else
{
$VehicleLight=TurnLightStatus;
switch(TurnLightStatus)
{
case 1: //Left Light flash
cancelTimer(msTrightflash);
@Cluster::Right_Turn_Indicator=0;
break;
case 2: //Right Light flash
cancelTimer(msTleftflash);
@Cluster::Left_Turn_Indicator=0;
break;
case 0: //swicth off both light
cancelTimer(msTrightflash);
cancelTimer(msTleftflash);
$LightStatus=0;
@Cluster::Left_Turn_Indicator=0;
@Cluster::Right_Turn_Indicator=0;
break;
}
}
}
IPC.can
/*@!Encoding:1252*/
includes
{
//To add the head files
}
variables
{
//To add the variables
int busflag=0; //current bus status: 0 - Deactivate CANoe IL ; 1 - Activate CANoe IL
}
on preStart
{
ILControlInit(); //Initialize CANoe IL
ILControlStop(); //Deactivate CANoe IL
}
on signal_update LockStatus
{
if(this!=busflag)
{
if(this==1)
{
ILControlStart(); //Activate CANoe IL
}
else if(this==0)
{
ILControlStop(); //Deactivate CANoe IL
}
busflag=this;
}
}
on signal_update Gear
{
@Cluster::Gear_Status= this; //To display current Gear status in panel
}
Gateway.can
/*@!Encoding:1252*/
includes
{
//To add the head files
}
variables
{
msTimer msTVehSpeedDown; //define the timer(ms) for Vehicle Speed down
msTimer msTEngSpeedDown; //define the timer(ms) for Engine Speed down
dword WritePage;
int busflag=0; //current bus status: 0 - Deactivate CANoe IL ; 1 - Activate CANoe IL
}
on preStart
{
ILControlInit(); //Initialize CANoe IL
ILControlStop(); //Deactivate CANoe IL
//Write simulation information in write window
writeLineEx(WritePage,1,"--------This demo demonstrated the CAN bus simulation!!--------");
writeLineEx(0,1,"Press <1> to start/stop CAN_logging");
}
on key '1'
{
int logflag;
if(logflag==0)
{
logflag=1;
write("CAN logging starts");
//start logging Logging CAN with a pretrigger with 500ms
startlogging("CAN_Logging",500);
}
else
{
logflag=0;
write("CAN logging ends");
//stop logging Logging CAN with a posttriggre with 1000ms
stoplogging("CAN_Logging",1000);
}
}
on signal_update LockStatus
{
if(this!=busflag)
{
if(this==1)
{
ILControlStart();
}
else if(this==0)
{
ILControlStop();
}
busflag=this;
}
}
on sysvar Vehicle_Control::Gear
{
$Gear=@this; //Change Gear status based on user operation
}
void EngineData_Init(void)
{
//Initialize the data of Engine
$VehicleSpeed=0;
$EngSpeed=0;
$EngTemp=0;
$PetrolLevel=0;
}
on signal_update KeyState
{
if(this==0)
{
EngineData_Init(); //Init engine data based on KeyState
}
if(this>0)
{
$PetrolLevel=255; //Init PetrolLevel based on KeyState
}
}
on sysvar_update Vehicle_Control::Eng_Speed
{
//Engine speed only available when Key is ON
if(@Vehicle_Key::Key_State==2)
{
$EngineData::EngSpeed=@this;
}
else
{
$EngineData::EngSpeed=0;
}
}
on sysvar_update Vehicle_Control::Veh_Speed
{
//Vehicle speed only available when Gear is Drive and Key is ON
if((@Vehicle_Control::Gear==3)&&(@Vehicle_Key::Key_State==2))
{
$VehicleData::VehicleSpeed=@this;
}
else
{
$VehicleData::VehicleSpeed=0;
}
}
//only for simulation
on sysvar_update Vehicle_Control::Speed_Up //Speed up when sysvar speed_up enabled
{
if($EngTemp<90)
{
$EngTemp=@this*1.5;
}
else
{
$EngTemp=90;
}
if($PetrolLevel<255)
{
$PetrolLevel=@this*8.5;
}
else
{
$PetrolLevel=255;
}
@Vehicle_Control::Veh_Speed=@this;
@Vehicle_Control::Eng_Speed=@this*40;
if(@this>120)
{
@this=60;
}
}
on sysvar Vehicle_Control::Brake //Speed down when Brake is enable
{
int i;
if(@this==1)
{
$GearLock=0;
setTimer(msTVehSpeedDown,50);
setTimer(msTEngSpeedDown,50);
}
else
{
$GearLock=1;
cancelTimer(msTVehSpeedDown);
cancelTimer(msTEngSpeedDown);
}
}
on timer msTVehSpeedDown //Implement speed down function
{
@Vehicle_Control::Veh_Speed=@Vehicle_Control::Veh_Speed-1;
setTimer(this,50);
if(@Vehicle_Control::Veh_Speed<=0)
{
cancelTimer(msTVehSpeedDown);
@Vehicle_Control::Veh_Speed=0;
}
}
on timer msTEngSpeedDown //Implement engine speed down function
{
@Vehicle_Control::Eng_Speed=@Vehicle_Control::Eng_Speed-40;
setTimer(this,50);
if(@Vehicle_Control::Eng_Speed<=0)
{
cancelTimer(msTEngSpeedDown);
@Vehicle_Control::Eng_Speed=0;
}
}
仿真
在空白桌面右键,新建一个新的桌面
右键 前面我们创建的Panel,将其固定在新的桌面上。
仿真
自动序列,播放以及录制运行序列,Simulation→Automation进行配置
添加loging block,并添加相关Channel Fiter模块
工程文件