很多人,无论做什么事情,刚起步当然难。
写了一个相当于Hello World的NC代码,给刚接触的初学者。
//以下是一个灯开关NC程序的示例,相当于Hello World吧,我一向喜欢用按键和灯来做第一个程序。
#pragma num_alias_table_entries 10#pragma run_unconfigured#pragma enable_sd_nv_names#pragma relaxed_casting_on
// --- Include files ---#include <io_types.h>#include <control.h>#include <addrdefs.h>#include <netmgmt.h>#include <msg_addr.h>#include <status.h>
extern system void _change_state(int state);
// --- predefine variable declarations ---#define STX 0x02 // start of packet#define ETX 0x00 // end of packet#define MAX 4 // max queue size#define BUFF_SIZE 31 //buffer size#define NM_SEND_TIME 10#define EDEV_DELAY_TIME 10000#define unconfigured 0x02#define config_on_line 0x04#define config_off_line 0x0c//--------------------------------#define ON 1#define OFF 0//--------------------------------
// io object declaration (new)-----------IO_0 output bit ioRelay01 = TRUE;IO_1 output bit ioRelay02 = TRUE;IO_2 output bit ioRelay03 = TRUE;IO_3 output bit ioRelay04 = TRUE;
IO_4 input bit ioButton01;IO_5 input bit ioButton02;IO_6 input bit ioButton03;IO_7 input bit ioButton04;//-----------------------------------------
// --- timer declarations ---mtimer repeating Nv_ack_timer;mtimer edev_info_timer; stimer edev_delay_timer;
// --- network variable declarations ---far network input SNVT_str_asc nviHostData;far network output SNVT_str_asc nvoData;
// --- function declarations ---void SelfBind(void);void CheckDomain(void);
// --- variable declarations ---typedef struct queue{ unsigned char buff[BUFF_SIZE];}queue;far queue rcv_que[MAX];
domain_struct new_domain;//-----------------------------------------------------------------------------------------------// --- eeprom variable declarations ---// e-device inforamtion initialize//-----------------------------------------------------------------------------------------------// 4ch., use the below dataeeprom unsigned int edev_info[31]={0x02,0x22,0x00,0x04,0x00,0x05,0x00,0x90,0x00,0xBF, 0x22,0x00,0x05,0x11,0x04,0x30,0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00}; // if 3ch., use the below data//eeprom unsigned int edev_info[31]={0x02,0x22,0x00,0x03,0x00,0x05,0x00,0x90,0x00,0xBF,// 0x22,0x00,0x05,0x11,0x03,0x30,0x30,0x30,0x30,0x30,// 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00};
// if 2ch., use the below data//eeprom unsigned int edev_info[31]={0x02,0x22,0x00,0x02,0x00,0x05,0x00,0x90,0x00,0xBF,// 0x22,0x00,0x05,0x11,0x02,0x30,0x30,0x30,0x30,0x30,// 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00};
// if 1ch., use the below data//eeprom unsigned int edev_info[31]={0x02,0x22,0x00,0x01,0x00,0x05,0x00,0x90,0x00,0xBF,// 0x22,0x00,0x05,0x11,0x01,0x30,0x30,0x30,0x30,0x30,// 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00};
//-----------------------------------------------------------------------------------------------
unsigned int sbuff_tmp[BUFF_SIZE];unsigned int ck_checksum;unsigned int rear_rptr, front_rptr;unsigned int f_txOK, f_rxOK;unsigned int ck_info_ctr;unsigned int f_uartOK;
/* Light State buffer & flag defince------------------------------------------------------------*/ unsigned int light_state[31]; // to save status msg temporarilyunsigned int led_state01,led_state02,led_state03,led_state04; // to save led status, i,e, flag variables /* ---------------------------------------------------------------------------------------------*/
//-----------------------------------------------------------//// [1] Initialize Block ////-----------------------------------------------------------when ( reset ){ unsigned int i,j; ck_info_ctr = 0; rear_rptr = 0; front_rptr = 0;// test = 3000; f_txOK = 1; f_rxOK = 1; Nv_ack_timer = 0; // 300ms timer stop for( i = 0; i< MAX; i++) for( j = 0; j< BUFF_SIZE; j++) // buffer clear rcv_que[i].buff[j] = 0;
/* ---------------------------*/ led_state01 = ON; led_state02 = ON; led_state03 = ON; led_state04 = ON; io_out(ioRelay01,0); // relay off io_out(ioRelay02,0); io_out(ioRelay03,0); io_out(ioRelay04,0); /* ---------------------------*/ CheckDomain();}
//-----------------------------------------------------------//// [2] Timer Block ////-----------------------------------------------------------when( timer_expires(edev_delay_timer)){ (void)service_pin_msg_send(); edev_info_timer = EDEV_DELAY_TIME;}
when( timer_expires(edev_info_timer)){ ck_info_ctr++; (void)service_pin_msg_send(); if( ck_info_ctr > 4) { ck_info_ctr = 0; edev_info_timer = 0; } else edev_info_timer = EDEV_DELAY_TIME;}
when( timer_expires(Nv_ack_timer)){ if(nv_update_succeeds( nvoData )) { rear_rptr = (rear_rptr + 1) & (MAX-1); // que rcv index increase f_txOK = 1; Nv_ack_timer = 0; // 300ms timer stop } else { if(nv_update_fails( nvoData )) { rear_rptr = (rear_rptr + 1) & (MAX-1); // que rcv index increase f_txOK = 1; Nv_ack_timer = 0; // 300ms timer stop } }}
//-----------------------------------------------------------//// [3] Receive Block //// : save the received PLC packet to buffer and do action according to msg//-----------------------------------------------------------when(nv_update_occurs(nviHostData)){ unsigned int i;
if(nviHostData.ascii[5] == 0x10) { new_domain = *(access_domain(0)); if(rear_rptr == ((front_rptr + 1)&(MAX-1))) rear_rptr = (rear_rptr + 1)&(MAX-1); // data loss rcv_que[front_rptr].buff[0] = STX; for(i=1; i<4; i++) rcv_que[front_rptr].buff[i] = edev_info[i]; rcv_que[front_rptr].buff[4] = 0; //Opt, PN rcv_que[front_rptr].buff[5] = 0x11; //SK,PT rcv_que[front_rptr].buff[6] = 0; //MODE
rcv_que[front_rptr].buff[7] = 0x10; //Version Inform 1.0 version if(read_only_data.model_num == 0) rcv_que[front_rptr].buff[8] = 0x01; //3150 Model Number else if(read_only_data.model_num == 1) rcv_que[front_rptr].buff[8] = 0x11; //PL 3150 Model Number else if((read_only_data.model_num >=8)&&(read_only_data.model_num <=14)) rcv_que[front_rptr].buff[8] = 0; // 3120 Model Number else if(read_only_data.model_num == 15) rcv_que[front_rptr].buff[8] = 0x10; // PL 3120 Model Number else rcv_que[front_rptr].buff[8] = 0x10; // PL 3120 Model Number for(i=0;i<6;i++) rcv_que[front_rptr].buff[i+9] = read_only_data.neuron_id[i]; for(i=0;i<6;i++) rcv_que[front_rptr].buff[i+15] = new_domain.id[i]; rcv_que[front_rptr].buff[21] = new_domain.subnet; rcv_que[front_rptr].buff[22] = new_domain.node; for(i=23; i<29; i++) rcv_que[front_rptr].buff[i] = 0x30; // dummy ck_checksum = 0; for(i=0; i<29; i++) ck_checksum = ck_checksum^rcv_que[front_rptr].buff[i]; rcv_que[front_rptr].buff[29] = ck_checksum; rcv_que[front_rptr].buff[30] = ETX; front_rptr = (front_rptr + 1)&(MAX-1); // receive que increase } else { if( f_uartOK != 0xf0 ) { for( i=0; i < 31; i++ ) sbuff_tmp[i] = nviHostData.ascii[i];
//--------------------------------------------------------------------------- // PLC Msg process // : do action according to msg (for example: command, requset syayus, ...) //--------------------------------------------------------------------------- if(sbuff_tmp[5]==0x01 && 0x0F) //is this packet type[PT] "command" ? { light_state[5]=0x02; if(sbuff_tmp[7]==0x01) //Does 1st byte of Data Field mean 'ON'? { io_out(ioRelay01,0); led_state01=ON; light_state[7]=0x01; for (i=0; i<31; i++) nvoData.ascii[i] = light_state[i]; } else if(sbuff_tmp[7]==0x00) //Does 1st byte of Data Field mean 'OFF'? { io_out(ioRelay01,1); led_state01=OFF; light_state[7]=0x00; for (i=0; i<31; i++) nvoData.ascii[i] = light_state[i]; } else //添加其他的按键,由网络变量传送的信息 ; } else if(sbuff_tmp[7]==0x00) //is this packet type[PT] "request Status"? { light_state[5]=0x02; nvoData.ascii[i] = light_state[i]; } else ; //-------------------------------------------------------------------- } }}
//-----------------------------------------------------------//// [4] Transmit Block //// : save PLC packet to Tx Que//-----------------------------------------------------------when((f_txOK == 1)&&(rear_rptr != front_rptr)){ unsigned int i; for (i=0; i<31; i++) nvoData.ascii[i] = rcv_que[rear_rptr].buff[i]; Nv_ack_timer = 300; // 300ms timer start f_txOK = 0; }
//-----------------------------------------------------------//// [5] Biding Block //// : bind and do someting //-----------------------------------------------------------when(msg_arrives){ if(msg_in.code == 0x31) { if(msg_in.data[15] == 0xf0) // Binding Start SelfBind(); else if(msg_in.data[15] == 0x0f) // go_unconfigured { _change_state(unconfigured); clear_status(); node_reset(); } else if(msg_in.data[15] == 0x07) { edev_info_timer = 0; ck_info_ctr = 0; } else ; } else ;}
//-----------------------------------------------------------//// [6] I/O process Block //// : check button and control relays or leds//-----------------------------------------------------------when (io_changes(ioButton01) to 0){ // The below codes are just example for our former product. // please, customize to your product. int i; light_state[5]=0x07; // event notification // to set PT field to 0x07
if(led_state01==ON) { io_out(ioRelay01,0); led_state01=OFF; light_state[7]=0x01; for (i=0; i<31; i++) nvoData.ascii[i] = light_state[i]; } else if(led_state01==OFF) { io_out(ioRelay01,1); led_state01=ON; light_state[7]=0x00; for (i=0; i<31; i++) nvoData.ascii[i] = light_state[i]; } else ;}
when (io_changes(ioButton02) to 0) //其他按键被直接近下时的动作{// insert your code here}
when (io_changes(ioButton03) to 0){// insert your code here}
when (io_changes(ioButton04) to 0){// insert your code here}
//-----------------------------------------------------------//// Subroutines////-----------------------------------------------------------void SelfBind(){ unsigned int i; address_struct my_address; nv_struct my_nv; my_address = *(access_address(1)); // set address table 1 my_address.sn.type = SUBNET_NODE; my_address.sn.domain = 0; my_address.sn.node = 127; my_address.sn.tx_timer = NM_SEND_TIME; my_address.sn.retry = 3; my_address.sn.subnet = 1; update_address(&my_address, 1);
my_nv = *(access_nv(1)); my_nv.nv_selector_hi = 0x00; my_nv.nv_selector_lo = 0x7C; my_nv.nv_addr_index = 1; update_nv(&my_nv, 1); if(rear_rptr == ((front_rptr + 1)&(MAX-1))) rear_rptr = (rear_rptr + 1)&(MAX-1); // data loss for(i=0;i<31;i++) rcv_que[front_rptr].buff[i] = edev_info[i]; front_rptr = (front_rptr + 1)&(MAX-1); // receive que increase}
void CheckDomain(){ unsigned int i; new_domain = *(access_domain(1)); new_domain.len = 0; for(i=0; i<6; i++) new_domain.id[i] = 0; new_domain.subnet = 0; new_domain.node = 0; update_domain(&new_domain, 1);}