ethercat master用户程序初始化

 

(1)定义配置信息 

键入命令:ethercat cstruct 得到从机的配置信息,复制下来(我用的从机是简单的io开发板)

信息如下:

chenpeng@chenpeng-M219F-6C:/lib/modules$ ethercat cstruct
/* Master 0, Slave 0, "ServoDrive_FSMC"
 * Vendor ID:       0x00000009
 * Product code:    0x26483052
 * Revision number: 0x00020111
 */

ec_pdo_entry_info_t slave_0_pdo_entries[] = {
    {0x7010, 0x01, 1}, /* LED 1 */
    {0x7010, 0x02, 1}, /* LED 2 */
    {0x7010, 0x03, 1}, /* LED 3 */
    {0x7010, 0x04, 1}, /* LED 4 */
    {0x7010, 0x05, 1}, /* LED 5 */
    {0x7010, 0x06, 1}, /* LED 6 */
    {0x7010, 0x07, 1}, /* LED 7 */
    {0x7010, 0x08, 1}, /* LED 8 */
    {0x0000, 0x00, 8}, /* Gap */
    {0x7011, 0x00, 32}, /* Var0x7011_OUTPUTS */
    {0x6000, 0x01, 1}, /* Switch 1 */
    {0x6000, 0x02, 1}, /* Switch 2 */
    {0x6000, 0x03, 1}, /* Switch 3 */
    {0x6000, 0x04, 1}, /* Switch 4 */
    {0x6000, 0x05, 1}, /* Switch 5 */
    {0x6000, 0x06, 1}, /* Switch 6 */
    {0x6000, 0x07, 1}, /* Switch 7 */
    {0x6000, 0x08, 1}, /* Switch 8 */
    {0x0000, 0x00, 8}, /* Gap */
    {0x6020, 0x01, 1}, /* Underrange */
    {0x6020, 0x02, 1}, /* Overrange */
    {0x6020, 0x03, 2}, /* Limit 1 */
    {0x6020, 0x05, 2}, /* Limit 2 */
    {0x0000, 0x00, 8}, /* Gap */
    {0x1802, 0x07, 1}, /* TxPDOState */
    {0x1802, 0x09, 1}, /* TxPDO Toggle */
    {0x6020, 0x11, 16}, /* Analog input */
};

ec_pdo_info_t slave_0_pdos[] = {
    {0x1601, 10, slave_0_pdo_entries + 0}, /* DO RxPDO-Map */
    {0x1a00, 9, slave_0_pdo_entries + 10}, /* DI TxPDO-Map */
    {0x1a02, 8, slave_0_pdo_entries + 19}, /* AI TxPDO-Map */
};

ec_sync_info_t slave_0_syncs[] = {
    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
    {2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE},
    {3, EC_DIR_INPUT, 2, slave_0_pdos + 1, EC_WD_DISABLE},
    {0xff}
};

 

 

 

 

自己再定义需要注册的pdo entry

我的是:

const static ec_pdo_entry_reg_t domain1_regs[] = {

    {IO_OPS, IO_INFO, 0x7010, 0x01, &off_led1,&off_led1_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x02, &off_led2,&off_led2_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x03, &off_led3,&off_led3_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x04, &off_led4,&off_led4_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x05, &off_led5,&off_led5_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x06, &off_led6,&off_led6_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x07, &off_led7,&off_led7_bit},
    {IO_OPS, IO_INFO, 0x7010, 0x08, &off_led8,&off_led8_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x01, &off_switch1,&off_switch1_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x02, &off_switch2,&off_switch2_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x03, &off_switch3,&off_switch3_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x04, &off_switch4,&off_switch4_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x05, &off_switch5,&off_switch5_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x06, &off_switch6,&off_switch6_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x07, &off_switch7,&off_switch7_bit},
    {IO_OPS, IO_INFO, 0x6000, 0x08, &off_switch8,&off_switch8_bit},
    {}
};

 

 

(2)程序初始化

 

在实时操作系统中请求一个master

master	  = ecrt_request_master( 0 );
	if(master == NULL) goto error_out;
	printf("master found\n");

 

 

创建新的过程数据domain,domain用来注册pods以及在循环周期中交换pdos的。

domain  = ecrt_master_create_domain(master);
	if (!domain) {
		printf("config domain failed\n");
        return 0;
    }

 

创建从机配置信息

slave   = ecrt_master_slave_config(master,0,0,IO_INFO);
    if (!slave) {
		printf("config slave failed\n");
        return 0;
    }
	

 

 

指定一个完整的pdo配置信息

if (ecrt_slave_config_pdos(slave, EC_END, slave_0_syncs))
	{
    	fprintf(stderr, "Failed to configure PDOs.\n");
    	return 1;
    }

 

把pdo的entry注册到domain中去

if (ecrt_domain_reg_pdo_entry_list(domain, domain1_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n" );
        return 1;
    }

 

激活master

if ( ecrt_master_activate((ec_master_t*)master) )
        return -1;

 

 

获取被映射的domain内存(在用户空间中,必须在激活master后来调用他)

if (!(domain_pd = ecrt_domain_data(domain))) {
		fprintf(stderr, "config Domain Data failed!\n" );
		return 1;
	}

 

执行周期任务

 while (1) {
	usleep( 1 );
	cyclic_task(master,domain,&(domain_pd));
    }

 

周期任务,仅当参考

void cyclic_task(ec_master_t* master,ec_domain_t* domain1, uint8_t **domain1_pd )
{
    static unsigned int counter = 0;

    /* receive process data */
    ecrt_master_receive(master);
    ecrt_domain_process(domain1);

    if (counter) {
        counter--;
    } else { /* do this at 1 Hz */
        counter = FREQUENCY;
       /* read process data */

       printf("SWITCH = %d ,  %d , %d\n",
	   EC_READ_U8(*domain1_pd + off_switch1),
	   EC_READ_U8(*domain1_pd + off_switch2),
	   EC_READ_U8(*domain1_pd + off_switch3)
       );

       printf( "LED= %d ,  %d , %d\n",
	   EC_READ_U8(*domain1_pd + off_led1),
	   EC_READ_U8(*domain1_pd + off_led2),
	   EC_READ_U8(*domain1_pd + off_led3)
       );
    }
    /* send process data */
	EC_WRITE_U8(*domain1_pd + off_led1,0x20);

    ecrt_domain_queue(domain1);
    ecrt_master_send(master);
}

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于EtherCAT总线的汇川伺服驱动器的示例程序: ```c++ #include <iostream> #include <cstdint> #include <cstring> #include <unistd.h> #include "ethercat.h" #define EC_TIMEOUTMON 500 using namespace std; int main(int argc, char **argv) { ec_master_t *master = ecrt_request_master(0); ec_master_state_t master_state; ec_master_state_t expected_state = { .al_states = EC_AL_STATES_OP, .link_up = true, .masters_responding = 1 }; int ret = ecrt_master_open(master, 0); if (ret < 0) { cerr << "Failed to open EtherCAT master: " << ecrt_strerror(-ret) << endl; return 1; } ret = ecrt_master_get_state(master, &master_state); if (ret < 0) { cerr << "Failed to get EtherCAT master state: " << ecrt_strerror(-ret) << endl; ecrt_master_close(master); return 1; } if (memcmp(&master_state, &expected_state, sizeof(ec_master_state_t)) != 0) { cerr << "EtherCAT master is not in the expected state" << endl; ecrt_master_close(master); return 1; } ec_slave_config_t *sc_motor = ecrt_master_slave_config(master, 0, 0x0001, 0x0000, EC_MAX_PORTS); if (!sc_motor) { cerr << "Failed to get slave configuration for motor" << endl; ecrt_master_close(master); return 1; } ret = ecrt_slave_config_dc(sc_motor, 0x0300, 1000000, 440000, 0, 0); if (ret < 0) { cerr << "Failed to configure DC for motor: " << ecrt_strerror(-ret) << endl; ecrt_master_close(master); return 1; } ec_domain_t *domain = ecrt_master_create_domain(master); if (!domain) { cerr << "Failed to create EtherCAT domain" << endl; ecrt_master_close(master); return 1; } if (ecrt_domain_reg_pdo_entry(domain, 0, 0, EC_REG_VENDOR_ID, EC_REG_VENDOR_ID_SIZE, EC_REG_VENDOR_ID_OFFSET, EC_REG_VENDOR_ID_SUBINDEX, EC_REG_VENDOR_ID_TYPE) < 0) { cerr << "Failed to register PDO entry for vendor ID" << endl; ecrt_master_close(master); return 1; } if (ecrt_domain_reg_pdo_entry(domain, 0, 0, EC_REG_PRODUCT_CODE, EC_REG_PRODUCT_CODE_SIZE, EC_REG_PRODUCT_CODE_OFFSET, EC_REG_PRODUCT_CODE_SUBINDEX, EC_REG_PRODUCT_CODE_TYPE) < 0) { cerr << "Failed to register PDO entry for product code" << endl; ecrt_master_close(master); return 1; } if (ecrt_domain_reg_pdo_entry(domain, 0, 0, EC_REG_CONTROL_WORD, EC_REG_CONTROL_WORD_SIZE, EC_REG_CONTROL_WORD_OFFSET, EC_REG_CONTROL_WORD_SUBINDEX, EC_REG_CONTROL_WORD_TYPE) < 0) { cerr << "Failed to register PDO entry for control word" << endl; ecrt_master_close(master); return 1; } if (ecrt_domain_reg_pdo_entry(domain, 0, 0, EC_REG_STATUS_WORD, EC_REG_STATUS_WORD_SIZE, EC_REG_STATUS_WORD_OFFSET, EC_REG_STATUS_WORD_SUBINDEX, EC_REG_STATUS_WORD_TYPE) < 0) { cerr << "Failed to register PDO entry for status word" << endl; ecrt_master_close(master); return 1; } ec_pdo_entry_reg_t pdo_entries[] = { { .alias = 0, .position = 0, .vendor_id = EC_REG_VENDOR_ID, .product_code = EC_REG_PRODUCT_CODE, .index = EC_REG_CONTROL_WORD_INDEX, .subindex = EC_REG_CONTROL_WORD_SUBINDEX, .bit_position = 0, .bit_length = 16, .name = "control_word", .data_type = EC_REG_CONTROL_WORD_TYPE, .access_type = EC_ACCESS_TYPE_RW }, { .alias = 0, .position = 0, .vendor_id = EC_REG_VENDOR_ID, .product_code = EC_REG_PRODUCT_CODE, .index = EC_REG_STATUS_WORD_INDEX, .subindex = EC_REG_STATUS_WORD_SUBINDEX, .bit_position = 0, .bit_length = 16, .name = "status_word", .data_type = EC_REG_STATUS_WORD_TYPE, .access_type = EC_ACCESS_TYPE_RO } }; if (ecrt_slave_config_pdo(sc_motor, EC_PDO_CONFIG_DEFAULT, pdo_entries, array_size(pdo_entries)) < 0) { cerr << "Failed to configure PDOs for motor" << endl; ecrt_master_close(master); return 1; } if (ecrt_domain_reg_callback(domain, &ecrt_domain_cb_stats, NULL) < 0) { cerr << "Failed to register domain callback" << endl; ecrt_master_close(master); return 1; } if (ecrt_master_activate(master) < 0) { cerr << "Failed to activate EtherCAT master" << endl; ecrt_master_close(master); return 1; } ec_pdo_entry_info_t pdo_info; if (ecrt_slave_config_pdos(sc_motor, EC_SDO_CONFIG_PERSIST, EC_TIMEOUTMON, &pdo_info) < 0) { cerr << "Failed to configure PDO mapping for motor" << endl; ecrt_master_close(master); return 1; } ecrt_domain_state_t domain_state; ecrt_master_receive(master); ecrt_domain_process(domain); ecrt_domain_state(domain, &domain_state); if (domain_state.working_counter == 0) { cerr << "Motor is not responding" << endl; ecrt_master_close(master); return 1; } uint16_t control_word = 0x0006; uint16_t status_word = 0x0000; if (ecrt_domain_queue(domain, &control_word, EC_REG_CONTROL_WORD_OFFSET, sizeof(control_word), EC_REG_CONTROL_WORD_TYPE, EC_WRITE_ACCESS) < 0) { cerr << "Failed to queue write access to control word" << endl; ecrt_master_close(master); return 1; } while (true) { ecrt_master_receive(master); ecrt_domain_process(domain); memcpy(&status_word, domain->data + EC_REG_STATUS_WORD_OFFSET, sizeof(status_word)); if (status_word & 0x0004) { cout << "Motor is in fault state" << endl; break; } if (status_word & 0x0028) { cout << "Motor is in operation enabled state" << endl; break; } usleep(1000); } ecrt_master_close(master); return 0; } ``` 这个示例程序假设你已经熟悉EtherCAT总线的基本概念,并且你已经熟悉如何置汇川伺服驱动器的PDO映射和监控状态字。如果你还没有这些知识,请先阅读相关文档和教程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值