canOpen学习五之canOpen应用实现主从机PDO非循环同步

一、从机代码
从机字典

/* 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非循环同步

写作不易,点个赞呗。

猜你喜欢

转载自blog.csdn.net/qq_15181569/article/details/105856141