最好的学习方式是什么?模仿。有人会问,那不是山寨么?但是我认为,那是模仿的初级阶段,当把别人最好的设计已经融化到自己的血液里,变成自己的东西,而灵活运用的时候,才是真正高级阶段。正所谓画虎画皮难画骨。但初级阶段仍然是必须经历的过程,他会使你在达到高级阶段的过程中少走很多弯路,下面我们来迈出这一步。先研究一下别人的简单例子。

最好的例子莫过于Vector本身的Demo了,这个在安装完CANoe之后就会被自动安装。先看最简单的一个,名字叫Easy,但并不简单哦,比我们之前介绍的所有的东西都整合再一起了,很简单,但很全面。但是假如你说,这个我自己也可以完全自己写出来(并不是仅仅是看懂哦),那么我可以肯定的说,在工作中,你完全可以胜任一般的任务要求哦~,剩下的只是工作量的问题了。但我相信到现在为止,你们很多人,都无法写出这样的程序,所以我建议你们把这个程序好好的研究明白,这点很重要。废话不多说,上图,下面是打开运行后的界面。

通过面板可以控制,及显示很多动画效果,做的非常的漂亮。在其余的窗体也将主要的数据以图表等表现方式呈现出来。

我们先看一下DBC的内容吧

Signals:

EngineSpeed  车速信息

FlashLight      双跳灯

HeadLight      大灯

OnOff            引擎状态

Messages:

EngineState  引擎状态:包含的信号有OnOff,EngineSpeed

LightState    灯光状态:包含的信号有FlashLight,HeadLight

Network nodes:

Display        显示节点,接收所有消息

Engine        引擎节点,发送EngineState 消息

Light          灯光节点,发送LightState 消息

Environment variables:   环境变量,一般与界面的组件相关联,这样就实现了图形化界面的控制与显示,下面就是关联的界面组件

EnvEngineSpeedDspMeter  

EnvEngineSpeedDspText   

EnvEngineSpeedEntry       

EnvEngineStateDsp          

EnvEngineStateSwitch       

EnvHazardLightsSwitch     

EnvHeadLightSwitch         

EnvLightDsp                    

注意一下信号的信息:

Definition页面的,Init.Val的输入框使能了,之前是灰色的状态,为什么呢?点击一下蓝色的带下划线的连接,弹出窗台如下:

意思是说这个值的设置,必须要定义的属性才能有效,之前一直没有提到信号的属性,这次还是第一次遇到哦。个人理解信号属性是表明信号的特点的一系列参数,当然消息和节点也都有对应的属性。为了更加详细的了解这个属性,我们求助于帮助。

哦,明白了,原来是用来初始化数据的哦。其实在Definition表示的是物理值,都要转换成Raw值保存到GenSigStartValue属性中。在属性的创建我们之前也没有提到过,这里讲一下,请在CANdb++ Editor菜单中,View->Attribute Definitions

右键,New,填写好信息即可。属性背后跟行为是密切相关的,甚至跟底层dll,其他的一些属性请参考Help文档,当然重要的属性我们也会跟大家在后面提到。

dbc还有一些细节,就是接受的消息的定义,之间也没介绍过,例如Display节点只接收消息,那么你就应该在节点的属性上进行配置,方法是右击节点然后点Edit Node,在Mapped Rx Sig.中就可以定义接收的信号了,Add…

其实不定义接收消息也是可以的,但会在File->Consistency check 的检查中中显示出无接收节点等的报警。例如前面第一讲例子的dbc的检查如下:

再看一下CAPL程序。

engine.can 程序如下:

variables 
{
}

on envvar EnvEngineStateSwitch         //当拨动开关的时候,会更改发动机发出的信号
{
  $EngineState::OnOff = @this;           //注意信号和环境变量直接赋值时的符号,信号用$,环境变量用@
  if(@this)
    $EngineState::EngineSpeed = @EnvEngineSpeedEntry;
  else
    $EngineState::EngineSpeed = 0;
}

on envvar EnvEngineSpeedEntry         //当移动车速滑条时,会更改发动机发出的信号
{
  if(@EnvEngineStateSwitch) 
  {
    $EngineState::EngineSpeed = @this;
  }
}

on start                                         //程序开始运行的时候,将调用所有的环境变量的事件
{
  CallAllOnEnvVar();    // call all envvar procedures of this model and
                        // thus consider the START VALUES of all environment
                        // variables for:  
                        //  - initialization of all message variables
                        //  - starting of any timers
                        //  - sending messages (output) with start values
}

light.can 的程序如下:

variables 
{
  msTimer tFlashLightFrequency;                 //定义闪灯定时器
  const int gFlashLightFrequency = 500;      //定义闪灯频率,初始化为500ms
  int gHazardLightsStatus = 0;                   //定义危险灯信号

int gDebugCounterTX = 0;                      //用于调试,记录TX报文个数
  int gDebugCounterTXRQ = 0;                  //用于调试,记录TXRQ报文个数
  int gDebugCounterRX = 0;                      //用于调试,记录RX报文个数
}

on envvar EnvHeadLightSwitch                   //大灯开关状态更改时,更新灯光消息的信号
{
  // assign EV value to the message signal
  $LightState::HeadLight = @this;
}

on start
{
  CallAllOnEnvVar();    // call all envvar procedures of this model and
                        // thus consider the START VALUES of all environment
                        // variables for:  
                        //  - initialization of all message variables
                        //  - starting of any timers
                        //  - sending messages (output) with start values

setWriteDbgLevel(0); // set DbgLevel = 1 to get more information in Write-Window
}

on message LightState    //调试用,打印相关信息
{
  if (this.dir == TX)
  {
    gDebugCounterTX++;
    if(gDebugCounterTX == 10)
    {
      writeDbgLevel(1,"LightState TX received by node %NODE_NAME%");
      gDebugCounterTX = 0;
    }     
  }
  if(this.dir == TXREQUEST)
  {
    gDebugCounterTXRQ++;
    if(gDebugCounterTXRQ == 10)
    {
      writeDbgLevel(1,"LightState TXREQUEST received by node %NODE_NAME%");
      gDebugCounterTXRQ = 0;
    } 
  }
  if (this.dir == RX)
  {
    gDebugCounterRX++;
    if(gDebugCounterRX == 10)
    {
      writeDbgLevel(1,"Error: LightState RX received by node %NODE_NAME%");
      gDebugCounterRX = 0;
    }
  }
}

on envVar EnvHazardLightsSwitch      //危险警示灯开关变化时,更新灯光消息的闪灯信号
{
  if (@this)
  {
    gHazardLightsStatus = 1;
    setTimer(tFlashLightFrequency, gFlashLightFrequency);
  }
  else
  {
    cancelTimer(tFlashLightFrequency);
    gHazardLightsStatus = 0;
  }

$LightState::FlashLight = gHazardLightsStatus;
}

on timer tFlashLightFrequency             //危险报警灯间隔闪烁的控制
{
  gHazardLightsStatus = (gHazardLightsStatus == 1 ? 0 : 1);
  $LightState::FlashLight = gHazardLightsStatus;
  setTimer(this, gFlashLightFrequency);
}

on key '0'                                      //按键事件,定义打印调试信息的等级
{
  setwriteDbgLevel(0);
}

on key '1'                                      //按键事件,定义打印调试信息的等级
{
  setwriteDbgLevel(1);                    
}

以上程序,有C语言基础的同学应该都可以看得懂,这里不用详细介绍了。

看完程序大家可能有个疑问,没有调用任何发送CAN消息的函数(只是更改其中的信号),但报文却真的发出去了,这是为什么呢?

这是因为周期发送消息的工作,已经在消息的属性中定义了,这样消息会自动周期的发送。如下:

这个在消息的属性查看中的界面,当然也可以在上面我们介绍的View->Attribute Definitions,进行修改和查看,但区别是,这个只是针对个别消息的,View->Attribute Definitions,是针对所有的情况。还有消息属性中,对此进行归类,以上归类到Interaction Layer这个是CAN通讯的交互层。上面的各个属性的具体含义,请参考帮助文档,都有详细的说明。

下面说一下界面。

选中一个界面组件,在状态栏中可显示他的类型,关联的对象等信息。右边为属性窗口,定义选中组件的属性

这个组件类型为:Switch/Indicator

属性栏中:

Image 表示该组件使用的图片,因为要表示几种状态,所以做成这样,尺寸105x34 pix

State Count 表示状态的个数

其他的属性不一一介绍了,自己试一下基本可以知道,实在不行求助帮助文档,这里不一 一介绍了。

到现在整个工程的剖析基本上结束了,但说过的这些不足以覆盖所有的细节,但基本脉络已经很清晰了,剩下的可以自己研究,都不难理解。个人建议,在实际工作中创建自己的工程,当遇到问题是,参考例子中的实现方式,这样更加帮助理解。进步也最快。

http://www.cnblogs.com/dongdonghuihui/archive/2012/09/26/2704623.html

CANoe 入门 Step by step系列(三)简单例子的剖析【转】的更多相关文章

  1. 【转载】CANoe 入门 Step by step系列(三)简单例子的剖析

    来源:http://www.cnblogs.com/dongdonghuihui/archive/2012/09/26/2704623.html 最好的学习方式是什么?模仿.有人会问,那不是山寨么?但 ...

  2. ASP.Net Core 2.2 MVC入门到基本使用系列 (三)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

  3. ASP.Net Core 2.2 MVC入门到基本使用系列 (三)(转)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

  4. sql server 备份与恢复系列三 简单恢复模式下的备份与还原

    一.概述 前面讲了备份的一些理论知识,这篇开始讲在简单恢复模式下的备份与还原.在简单模式下是不能做日志备份的,发生灾难后,数据库最后一次备份之后做的数据修改将是全部丢失的,所以在生产环境下,数据又很重 ...

  5. ASP.Net Core 2.2 MVC入门到基本使用系列 (四)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

  6. ASP.Net Core 2.2 MVC入门到基本使用系列 (二)

    本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ...

  7. Linux Kernel系列三:Kernel编译和链接中的linker script语法详解

    先要讲讲这个问题是怎么来的.(咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么). 我在编译内核的时候,发现arch/arm/kernel目录下有 ...

  8. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  9. WPF Step By Step 系列 - 开篇 ·

    WPF Step By Step 系列 - 开篇 公司最近要去我去整理出一个完整的WPF培训的教程,我刚好将自己学习WPF的过程和经验总结整理成笔记的方式来讲述,这里就不按照书上面的东西来说了,书本上 ...

随机推荐

  1. 使用GitHub管理源代码

    作为一个开发员,源码的管理是一个头等大事来的,想象一下,修改完成却发现文件丢失了,该怎么办?有了源代码管理工具,能够帮助我们查看某个代码文件的修改内存及历史修改记录. 作为.Net开发员,我使用过VS ...

  2. Linux 上的游戏 Supertuxkart

    Linux 上玩游戏 Supertuxkart 中午休息的时候,打开Supertuxkart游戏,这个是GNU下的一款3D赛车游戏,制作精美,玩法简单.最有趣的是,我连接笔记本的外接键盘被侦测出来是M ...

  3. Java经典封装JDBC模板(充分体现面向对象思想)(转)

    程序清单一览 bean类 package com.software.usermanager.bean; public class Users { private String id; private ...

  4. 统计中的PV,UV是的意思(转)

    PV(访问量):即Page View, 即页面浏览量或点击量,用户每次刷新即被计算一次. UV(独立访客):即Unique Visitor,访问您网站的一台电脑客户端为一个访客.00:00-24:00 ...

  5. Context

    Context,中文直译为“上下文”,SDK中对其说明如下: Interface to global information about an application environment. Thi ...

  6. Linux 性能优化之 IO 子系统 系列 图

    http://blog.sina.com.cn/s/articlelist_1029388674_11_1.html Linux 性能优化之 IO 子系统(一) 本文介绍了对 Linux IO 子系统 ...

  7. Elasticsearch .Net Client NEST使用说明 2.x

    Elasticsearch .net client NEST使用说明 2.x Elasticsearch.Net与NEST是Elasticsearch为C#提供的一套客户端驱动,方便C#调用Elast ...

  8. http 与https 安全链接

    安全连接 Web应用最常见的用途之一是电子商务,可以利用Web服务器端程序使人们能够网络购物,需要指出一点是,缺省情况下,通过Internet发送信息是不安全的,如果某人碰巧截获了你发给朋友的一则消息 ...

  9. jQuery 分页插件 jqPagination的使用

    jqPagination 是一个简单易用的轻量级 jQuery分页插件,其使用了 HTML5 和 CSS3 技术来实现.此插件提供了几个参数设置选项,通过简单的配置即可生成分页控件.此外,它的外观样式 ...

  10. 最近有机会接触到了angularJs

    记点笔记  概念多了 理顺还待时日: 总的来说: 1.ng-src src属性 2.ng-href href属性 3.ng-checked 选中状态 4.ng-selected 被选择状态 5.ng- ...