一、从机代码
从机字典

/* index 0x1400 :   Receive PDO 1 Parameter. */
UNS8 slave_objdict_highestSubIndex_obj1400 = 6; /* number of subindex - 1*/
UNS32 slave_objdict_obj1400_COB_ID_used_by_PDO = 0x200; /* 512 */
UNS8 slave_objdict_obj1400_Transmission_Type = 0x0; /* 0 */
UNS16 slave_objdict_obj1400_Inhibit_Time = 0x0; /* 0 */
UNS8 slave_objdict_obj1400_Compatibility_Entry = 0x0; /* 0 */
UNS16 slave_objdict_obj1400_Event_Timer = 0x0; /* 0 */
UNS8 slave_objdict_obj1400_SYNC_start_value = 0x0; /* 0 */
subindex slave_objdict_Index1400[] =
{
{ RO, uint8, sizeof (UNS8), (void*)&slave_objdict_highestSubIndex_obj1400, NULL },
{ RW, uint32, sizeof (UNS32), (void*)&slave_objdict_obj1400_COB_ID_used_by_PDO, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1400_Transmission_Type, NULL },
{ RW, uint16, sizeof (UNS16), (void*)&slave_objdict_obj1400_Inhibit_Time, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1400_Compatibility_Entry, NULL },
{ RW, uint16, sizeof (UNS16), (void*)&slave_objdict_obj1400_Event_Timer, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1400_SYNC_start_value, NULL }
};

/* index 0x1600 : Receive PDO 1 Mapping. */
UNS8 slave_objdict_highestSubIndex_obj1600 = 1; /* number of subindex - 1*/
UNS32 slave_objdict_obj1600[] =
{
0x20010008 /* 536936456 */
};
subindex slave_objdict_Index1600[] =
{
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_highestSubIndex_obj1600, NULL },
{ RW, uint32, sizeof (UNS32), (void*)&slave_objdict_obj1600[0], NULL }
};

/* index 0x1800 : Transmit PDO 1 Parameter. */
UNS8 slave_objdict_highestSubIndex_obj1800 = 6; /* number of subindex - 1*/
UNS32 slave_objdict_obj1800_COB_ID_used_by_PDO = 0x180; /* 384 */
UNS8 slave_objdict_obj1800_Transmission_Type = 0x0; /* 0 */
UNS16 slave_objdict_obj1800_Inhibit_Time = 0x0; /* 0 */
UNS8 slave_objdict_obj1800_Compatibility_Entry = 0x0; /* 0 */
UNS16 slave_objdict_obj1800_Event_Timer = 0x0; /* 0 */
UNS8 slave_objdict_obj1800_SYNC_start_value = 0x0; /* 0 */
subindex slave_objdict_Index1800[] =
{
{ RO, uint8, sizeof (UNS8), (void*)&slave_objdict_highestSubIndex_obj1800, NULL },
{ RW, uint32, sizeof (UNS32), (void*)&slave_objdict_obj1800_COB_ID_used_by_PDO, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1800_Transmission_Type, NULL },
{ RW, uint16, sizeof (UNS16), (void*)&slave_objdict_obj1800_Inhibit_Time, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1800_Compatibility_Entry, NULL },
{ RW, uint16, sizeof (UNS16), (void*)&slave_objdict_obj1800_Event_Timer, NULL },
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_obj1800_SYNC_start_value, NULL }
};

/* index 0x1A00 : Transmit PDO 1 Mapping. */
UNS8 slave_objdict_highestSubIndex_obj1A00 = 1; /* number of subindex - 1*/
UNS32 slave_objdict_obj1A00[] =
{
0x20000008 /* 536870920 */
};
subindex slave_objdict_Index1A00[] =
{
{ RW, uint8, sizeof (UNS8), (void*)&slave_objdict_highestSubIndex_obj1A00, NULL },
{ RW, uint32, sizeof (UNS32), (void*)&slave_objdict_obj1A00[0], NULL }
};

/* index 0x2000 : Mapped variable pdo1TransmitDate */
subindex slave_objdict_Index2000[] =
{
{ RW, uint8, sizeof (UNS8), (void*)&pdo1TransmitDate, NULL }
};

/* index 0x2001 : Mapped variable pdo1ReceiveDate */
subindex slave_objdict_Index2001[] =
{
{ RW, uint8, sizeof (UNS8), (void*)&pdo1ReceiveDate, NULL }
};

从机函数

int main(void)
{
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
cantimer_init(10-1,8400-1);
can_init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_Normal);//CAN初始化环回模式,波特率500Kbps
setNodeId(&slave_objdict_Data, 0x01);
setState(&slave_objdict_Data, Initialisation);
setState(&slave_objdict_Data, Pre_operational);
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)//KEY0按下,改变一次数据
{
pdo1TransmitDate++;
}
else if(key==WKUP_PRES)//WK_UP按下,改变CAN的工作模式
{

}
}

}

从机字典中主要看索引0x1800中发送PDO一的设置​​UNS8 slave_objdict_obj1800_Transmission_Type = 0x0; /* 0 */​​​发送类型设置为非循环同步
二、主机代码

int main(void)
{
u8 key;
Message msg;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
cantimer_init(10-1,8400-1);
can_init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_Normal);//CAN初始化环回模式,波特率500Kbps
setNodeId(&master_objdict_Data, 0x00);
setState(&master_objdict_Data, Initialisation);
setState(&master_objdict_Data, Operational);
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES) //暗笑K0键启动从节点1
{
masterSendNMTstateChange(&master_objdict_Data,0x01,NMT_Start_Node);
}
else if(key==KEY1_PRES) //按下K1发送PDO请求
{
sendPDOrequest(&master_objdict_Data,0x1400);
}
else if(key==KEY2_PRES) //按下K2发送SYNC帧数据
{
msg.cob_id = (UNS16)0x80;
msg.len = (UNS8)0x00;
msg.rtr = (UNS8)0;
canSend(&master_objdict_Data.canHandle,&msg );
}
else if(key==WKUP_PRES)
{

}
}

}

三、说明
非循环同步只能异步发送(即接收到发送请求或者主动发送),接收到SYNC帧不会发送。两块板子上电后先按下主机的K0启动从节点,然后按K2主机发送同步帧但是从机不会有数据过来的,当按下从节点K0后修改从机中发送的值,值改变后从机就会自动发送数据。

四、源码
​STM32F4移植canfestival实现canOPen协议实现PDO非循环同步​​

写作不易,点个赞呗。