CANopen从站协议在stm32分析和说明 下载本文

if (sizeData != *pSize) { MSG_WAR1(0x2052, \of data different than (size in mapping / 8) : \sizeData);

} memcpy(&process_var.data[offset], pMappedAppObject, sizeData);//封装pdo报文

图6 从站发送错误事件

图6是一个从站发送错误事件的报文,当从站内部程序出现异常时(譬如取不到索引数据等),从站会进行报错,这里错误码和内容可以自己配置。01 83是由主站设置的发送错误事件标识ID,55 1F 00 00代表错误码,CD AB 00 00代表错误的数据。

发送错误事件涉及的函数代码为: MSG_ERR(num, str, val) ,此函数功能是将错误码和错误数值存入由主站设置的特定索引并封装成PDO报文发送(封装由sendPDOevent函数完成),代码片段为:

MSG_ERR(0x1F55, \可发送图6的错误报文

MSG_ERR(num, str, val)//函数原型 { if(nodeState == Operational ){

canopenErrNB=num; canopenErrVAL=val;

sendPDOevent(0,&canopenEr

rNB); //发送pdo报文 } }

图7 从站异步传输数据

图7是一个异步传输数据报文,当内部达到一定条件是,会自动发送PDO报文,笔者将条件设定为如果时间在每小时56分时则发送PDO报文,01 82是主站设置给从站发送异步数据的标识ID,数据为当前时间戳,(0x86转换成十进制是56。)

异步传输数据所涉及函数也是sendPDOevent函数,此函数功能是将数据 if(minutes==56) {

sendPDOevent( 0, &minutes ); }

7 CANOPEN从站协议在STM32F103ZET6单片机上的实现

7.1 硬件设置

首先需要对管脚进行设置,由原理图(见图8)可以看出CAN数据传输端CANTX接PB9管脚,CAN数据接收端CANRX接PB8管脚。需要编写gpio_config()函数进行配置,代码片段:

/* Configure CAN pin: RX */

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//输入模式

GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure CAN pin: TX */

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//输出模式

GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);//重映射

图8 STM32F103ZET6 CAN原理图

硬件方面设置完毕后,对程序进行设计,程序主要分为两大部分。 7.2主程序介绍及设计

第一部分为main函数部分:程序运行时,进行初始化操作(设置节点ID、中断服务、管脚、发送邮箱、接收邮箱和波特率等),完成后进入对节点对状态进行检测和处理的无限循环程序:从站启动运行后会有四个状态,分别是初始化、预运行、运行、停止。代码中分别用initialization、pre_operational、operational、stopped

initialization(),preoperational(),operational(),stopped(),这些功能函数的主要作用是发送当前状态的心跳报文。用switch语句实现不同状态之间的切换及函数处理。

以下是主程序流程图:

图9 主程序流程图

代码框架大致为: While(1) {

switch(nodestatus){ case initialization:

initialization(); break;

case pre_operational:

pre_operat ional(); break;

case operational:

operational(); break; case stopped:

stopped(); break; } }

7.3 中断服务程序介绍及设计 第二部分为中断服务程序:从节点上电启动后,中断等待来自主节点的管理报文,当报文到来的时候,基于中断的接收报文机制产生中断,中断由stm32的硬件进入void usb_lp_can_rx0_irqhandler(void)处理接收报文。can接收中断触发了CAN报文接收函数canreceive(&m)。然后通过不同功能码来实现报文的解析和处理。功能函数包括:proceednmtstatechange()函数,处理主站NMT报文,改变从节点状态;proceedsync()函数,用于接收同步报文;proceedpdo()函数,处理 pdo报文;proceedsdo()函数,处理sdo报文。通过功能函数的解析后来执行相应的处理。从而来实现对节点的控制。

以下是中断服务程序流程图:

图10 中断服务程序流程图