很多人,无论做什么事情,刚起步当然难。
写了一个相当于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 data
eeprom 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 temporarily
unsigned 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);
}