DE | EN | CN

ESE模块14 CAN-Bus 通讯

使用mySTM32 light板来使用CAN总线。这个练习需要两个人一起完成,或者至少需要两个mySTM32 light板。

在之前的教程中,您已经了解了I²C总线。这种总线用于连接同一块电路板上的不同控制器。如果要连接的控制器分布在较远的位置,例如在建筑机械上的传感器和执行器,可能需要几米的电缆长度,那么就会使用其他现场总线系统。特别是在车辆领域,CAN总线CAN-Bus是一种常用的总线系统。CAN代表Controller Area Network。因此,这个名字已经表明了它是一个面向微控制器的网络协议。与I²C协议不同,CAN发送的是所谓的帧。Frames这些帧包含了诸如消息ID和要传输的有效负载等控制信息。在标准模式下,每个帧提供8字节或8×8 = 64位的有效负载。在CAN中,信息通常不是一次性事件导向的,而是按照特定的更新速率周期性地发送,例如每20或100毫秒一次。更新速率与消息的重要性相关。消息的缺失意味着相应节点的故障。

两个控制器板将通过CAN总线联网。 每个板都应有一个按钮和一个LED。 当按一个板的按钮时,另一块板上的LED就会亮。

解决方案要求:

  • 发送按钮针脚A0
  • 接收LED针脚B0
  • CAN更新速率100毫秒
  • 消息ID板1 = 1,板2 = 2

SRS CAN

如果仍有一个类图已经打开,请在该图的上下文菜单(鼠标右键)中选择菜单项“上”。 如果没有,请再次打开SiSy UML项目。 进行以下准备工作:

  • 创建一个新的类图
  • 目标语言ARM C ++
  • 目标平台STM32F042 mySTM32板灯HAL
  • 为PEC的应用模板(XMC,STM32,AVR)加载应用程序的基本结构
  • STM32F0分配驱动程序包
  • (可选)分配模板stm32F042_48Mhz

实现一个CAN总线解决方案稍微复杂一些。在开始之前,我们应该对以下几个方面有清晰的认识:

  • 系统状态作为消息循环放置(发送)在总线上
  • 消息没有接收方的地址,但显示了系统状态的ID
  • 每个控制器都可以接收对其重要的系统状态并对它们做出反应
  • 控制器可以/必须过滤出所需的消息(ID)
  • 系统状态以64位用户数据(8字节)编码

让我们试着找出系统设计中的重要组件。要发送的系统状态是一个按钮状态。值得注意的是,用于编码按钮状态的消息只需要一个位。控制器周期性地检测按钮状态,例如每100毫秒一次,将状态(0/1)编码在一个CAN消息中,并将其发送到CAN总线上。接收控制器过滤和解码来自CAN总线的接收消息,并相应地切换LED。



软件包“ Middleware / CanSupport / pec_Can”包含适合当下任务的库模块。CAN总线以及发送和接收消息都有构建块。下图标记了对解决方案重要的元素。

以下CAN解决方案的设计图可以从系统组件中得出。
首先是发送方解决方案的设计图。

再是接收方解决方案的设计图。

CAN协议不是PEC基本软件包的一部分,而是包含在中间件软件包中。 要使用CAN库块,必须使用文件夹“ Middleware / CanSupport”中的相应驱动程序包“ pec_can”包含在类图中。

注意:使用中间件=分配适当的软件包

首先实现发送方的解决方案。
请注意,在类图中包含pec_can包。 操作中的简要总结:

  • • 准备一个新的类图
  • • 包含pec_Can软件包
  • • 创建并连接类SendButtonCanBusSendMessage
  • • 连接库块PecButtonClickAndHoldPecCanBusPecCanMsgSend
  • • 连接特定的控制器资源pinA0canPortA11A12_stm32f0
  • • 覆盖类控制器onEvent100ms的操作
  • • 覆盖SendMessage类的onConfig操作

MessageReceiver类的onConfig()操作中,我们将ID 1分配给消息对象。

SendMessage::onConfig():void
msgId=0x01; 

我们使用类控制器的100毫秒事件来循环发送按钮状态。 我们在消息的第一个数据字节中编码按钮状态,其中0表示未激活,1表示按钮已激活。

Controller::onEvent100ms():void
if (sendButton.isPressed())
{
	canBus.sendMessage.msgData.data8[0] = 1;
}
else
{
	canBus.sendMessage.msgData.data8[0] = 0;
}
canBus.sendMessage.send();

然后再做接收方的解决方案(和发送的解决方案 几乎相近)。 同样,请注意,在类图中包含pec_can包。
操作中的简要总结:

  • • 准备一个新的类图
  • • 包含pec_Can软件包
  • • 创建并连接类ReciveLED,CanBus和ReciveMessag
  • • 连接库块PecLed,PecCanBus,PecCanMsgRecv
  • • 连接特定的控制器资源pinB0和canPortA11A12_stm32f0
  • • 覆盖ReceiveMessage类的onReceive操作
  • • 覆盖ReciveMessage类的onConfig操作

为了接收正确的消息,我们将ID 1分配给期望的接收消息。

ReciveMessage::onConfig():void
msgId=0x01; 

我们只是在消息对象的接收事件中对消息进行解码。

ReciveMessage::onRecive():void
if (msgData.data8[0] == 1)
{
	app.reciveLED.on();
}
else
{
	app.reciveLED.off();
}

翻译解决方案。将可执行程序传送到控制器的程序存储器中。

  • 1. 创建(编译和链接)
  • 2. 烧录
  • 3. 将板上的按钮1连接到A0,将红色LED连接到B0
  • 4. 在板之间建立CAN连接,注意CAN Hi = Hi,GND = GND,Lo = Lo

视频总结

  • 1. 创建并打开类图
  • 2. 选择PEC应用程序的图模板
  • 3. 加载正确的驱动程序包
  • 4. 包含中间件软件包
  • 5. 在资源管理器中找到所需的构建块并将其拖动到图中
  • 6. 聚合类, 组件连接
  • 7. 覆盖操作
  • 8. 在操作中创建必要的源代码
  • 9. 在类图中创建并刻录ARM应用程序

练习12

扩展两个解决方案,以使它们每个都有一个发送按钮和一个接收LED,将板1发送到板2,将板2再发送到板1。

继续:

关键词