发表于:2007-07-26 15:22:00
1楼
'=========================================================================
' Customer: Application Example
' Application: Modbus Slave
' Module: MODSLAVE.BAS
' Platform: Trio Motion Coordinator
'-------------------------------------------------------------------------
' Version: 1.0 Issued: 20 OCT 2005
' Author: Wang Ye
' Original: 8 OCT 2005
'-------------------------------------------------------------------------
' Copyright (c) 1999-2005 Trio Motion Technology Ltd.
'
' Trio Motion Technology Ltd.
' Web site: www.triomotion.com
'=========================================================================
'=========================================================================
' Communication protocol - Modbus RTU
'
' Run this as a fast program and connect OMRON 3G3MV to Port #mport
' The inverter is at address 1 to 4.
'=========================================================================
'######################################
'Initialise the communication paramter
'######################################
mport=2
'######################################
'Initialise the number of inverter
'######################################
number=3
'##############################################
'Initialise the offset in table area
'##############################################
c_base=0 'suppose the device address=n
'table(c_base+n) make order to device
' example: table(c_base+1,1)->enable inverter(address=1) accept the
' control order and setting pulse.This byte will be reset
' automatically.
'table(c_base+(n-1)*2+11) current pulse value
'table(c_base+(n-1)*2+12) current electrical current value
'table(c_base+(n-1)*2+21) The control order ="0000" in inverter
' =0 STOP command
' =1 FORWARD command
' =3 REVERSE command
'table(c_base+(n-1)*2+22) The pulse value that you want to transfer
t_base=100
'#################################################
'RS485 OR RS422 SETTING; if the cable is two wires,
'set rs485=1, otherwise set rs485=0
'#################################################
rs485=0
'#################################################
'#################################################
GOSUB table_init
GOSUB set_crc_hi
GOSUB set_crc_lo
GOSUB com_init
GOSUB clr_buffer
TICKS=timeout
FOR num=1 TO number
TABLE(c_base+num,0)
NEXT num
WHILE(1)
FOR num=1 TO number
'send order
GOSUB clr_buffer
enable=TABLE(c_base+num)
order=TABLE(c_base+(num-1)*2+21)
pulse=TABLE(c_base+(num-1)*2+22)
IF(enable=1) THEN
TABLE(t_base,num)
TABLE(t_base+1,$10)
TABLE(t_base+2,0)
TABLE(t_base+3,1)
TABLE(t_base+4,0)
TABLE(t_base+5,2)
TABLE(t_base+6,4)
TABLE(t_base+7,0)
TABLE(t_base+8,order)
data=pulse*10
IF(data<256) THEN
TABLE(t_base+9,0)
TABLE(t_base+10,data)
ELSE
data2=data MOD(256)
data1=(data-data2)/256
TABLE(t_base+9,data1)
TABLE(t_base+10,data2)
ENDIF
orderlen=12
GOSUB crc_send_calc
GOSUB sendorder
GoSub get_frame
If frame_flag=2 Then
TABLE(c_base+num,0) 'clear enable signal
WA(200)
endif
ENDIF
IF(enable=0) THEN
WA(200)
'receive the current data
TABLE(t_base,num)
TABLE(t_base+1,3)
TABLE(t_base+2,0)
TABLE(t_base+3,ordertype)
TABLE(t_base+4,0)
TABLE(t_base+5,1)
orderlen=7
GOSUB crc_send_calc
' GOSUB clearbuf
GOSUB sendorder
mod_addr=num
GOSUB get_frame
IF frame_flag=2 THEN
GOSUB chk_message
IF(ordertype=$27) THEN
elec=result
ELSE
pulse_read=result
ENDIF
ENDIF
'write to table memory
TABLE(c_base+(num-1)*2+11,pulse_read)
TABLE(c_base+(num-1)*2+12,elec)
ENDIF
NEXT num
IF(ordertype=$23) THEN
ordertype=$27
ELSE
ordertype=$23
ENDIF
WA(200)
WEND
com_init:
ADDRESS=255
SETCOM(9600,8,1,2,mport,OFF)
rx_pt=0
tx_pt=0
timeout=100 'Quiet time between frames
result=0
orderlen=0
ordertype=$23
RETURN
table_init:
' uses table between t_base and t_base+1024
st=t_base+1000't_base ' crc look up (hi byte)
s2=t_base+1256't_base+256 ' crc look up (low byte)
ts=t_base+512 'table start
tt=ts+256
FOR i=ts TO ts+512
TABLE(i,0)
NEXT i
RETURN
'=========================================================================
' GET_FRAME
' Call this routine when a character has been detected (KEY is TRUE)
' Tries to receive a frame and check the CRC
' frame_flag returns 2 for frame OK or 3 for frame error
' DATA is returned in TABLE(ts) to TABLE(ts+rx_pt-1)
'=========================================================================
get_frame:
IF(rs485=1) THEN
flag1=0
WHILE flag1=0
IF(KEY#mport) THEN
GET#mport,data
' PRINT#5,data
IF(data=sendlast1) THEN
GET#mport,data
IF(data=sendlast2) THEN flag1=1
ENDIF
ENDIF
WEND
ENDIF
'GOSUB test
frame_flag=0
rx_pt=0
WA(100)
REPEAT
IF KEY #mport THEN
GET #mport,in_chr
TICKS=timeout
' PRINT #5,HEX(in_chr)
IF rx_pt=0 AND frame_flag=0 THEN
IF in_chr=mod_addr THEN
TABLE(ts,in_chr)
rx_pt=rx_pt+1
ELSE
frame_flag=1
ENDIF
ELSE
IF rx_pt<255 THEN
TABLE(ts+rx_pt,in_chr)
rx_pt=rx_pt+1
ENDIF
ENDIF
ELSE
IF TICKS<0 THEN
IF rx_pt>2 THEN
GOSUB crc_check
ELSE
frame_flag=3
ENDIF
ENDIF
ENDIF
UNTIL frame_flag>=2
RETURN
'=========================================================================
' CHK_MESSAGE
' Routine checks message for recognised commands and sends appropriate
' reply.
' Enter with ts at start of message in table and rx_pt at end+1
'
'=========================================================================
chk_message:
recog_flag=0
TICKS=timeout
result=(TABLE(ts+3)*256+TABLE(ts+4))/10
RETURN
'#############################################################################
sendorder:
FOR i=0 TO orderlen
PRINT#mport,CHR(TABLE(t_base+i));
' PRINT#5,TABLE(t_base+i)
NEXT i
sendlast1=TABLE(t_base+orderlen-1)
sendlast2=TABLE(t_base+orderlen)
RETURN
crc_send_calc:
te=t_base+orderlen-2
css=t_base
cse=te
GOSUB crc_calc
TABLE(te+1,crchi)
TABLE(te+2,crclo)
RETURN
'=========================================================================
clr_buffer:
WHILE KEY #mport
GET #mport,in_chr
WEND
RETURN
crc_check:
te=ts+rx_pt-3
css=ts
cse=te
GOSUB crc_calc
IF TABLE(te+1)<>crchi THEN
frame_flag=3
ELSE
IF TABLE(te+2)=crclo THEN
frame_flag=2
ELSE
frame_flag=3
ENDIF
ENDIF
RETURN
crc_set:
css=tt
cse=tx_pt-3
GOSUB crc_calc
TABLE(tx_pt-2,crchi,crclo)
RETURN
crc_calc:
crchi=255 :crclo=255
FOR i=css TO cse
' PRINT#5,HEX(TABLE(i))
uindex=crchi XOR TABLE(i)
crchi=crclo XOR TABLE(st+uindex)
crclo=TABLE(s2+uindex)
NEXT i
crclo=crclo AND 255
'PRINT#5,HEX(crclo)
crchi=crchi AND 255
'PRINT#5,HEX(crchi)
RETURN
' Set up two look-up tables for fast crc
' generation.
set_crc_hi:
TABLE(st,0,193,129,64,1,192,128,65,1,192)
TABLE(st+10,128,65,0,193,129,64,1,192,128,65)
TABLE(st+20,0,193,129,64,0,193,129,64,1,192)
TABLE(st+30,128,65,1,192,128,65,0,193,129,64)
TABLE(st+40,0,193,129,64,1,192,128,65,0,193)
TABLE(st+50,129,64,1,192,128,65,1,192,128,65)
TABLE(st+60,0,193,129,64,1,192,128,65,0,193)
TABLE(st+70,129,64,0,193,129,64,1,192,128,65)
TABLE(st+80,0,193,129,64,1,192,128,65,1,192)
TABLE(st+90,128,65,0,193,129,64,0,193,129,64)
TABLE(st+100,1,192,128,65,1,192,128,65,0,193)
TABLE(st+110,129,64,1,192,128,65,0,193,129,64)
TABLE(st+120,0,193,129,64,1,192,128,65,1,192)
TABLE(st+130,128,65,0,193,129,64,0,193,129,64)
TABLE(st+140,1,192,128,65,0,193,129,64,1,192)
TABLE(st+150,128,65,1,192,128,65,0,193,129,64)
TABLE(st+160,0,193,129,64,1,192,128,65,1,192)
TABLE(st+170,128,65,0,193,129,64,1,192,128,65)
TABLE(st+180,0,193,129,64,0,193,129,64,1,192)
TABLE(st+190,128,65,0,193,129,64,1,192,128,65)
TABLE(st+200,1,192,128,65,0,193,129,64,1,192)
TABLE(st+210,128,65,0,193,129,64,0,193,129,64)
TABLE(st+220,1,192,128,65,1,192,128,65,0,193)
TABLE(st+230,129,64,0,193,129,64,1,192,128,65)
TABLE(st+240,0,193,129,64,1,192,128,65,1,192)
TABLE(st+250,128,65,0,193,129,64)
RETURN
set_crc_lo:
TABLE(s2,0,192,193,1,195,3,2,194,198,6)
TABLE(s2+10,7,199,5,197,196,4,204,12,13,205)
TABLE(s2+20,15,207,206,14,10,202,203,11,201,9)
TABLE(s2+30,8,200,216,24,25,217,27,219,218,26)
TABLE(s2+40,30,222,223,31,221,29,28,220,20,212)
TABLE(s2+50,213,21,215,23,22,214,210,18,19,211)
TABLE(s2+60,17,209,208,16,240,48,49,241,51,243)
TABLE(s2+70,242,50,54,246,247,55,245,53,52,244)
TABLE(s2+80,60,252,253,61,255,63,62,254,250,58)
TABLE(s2+90,59,251,57,249,248,56,40,232,233,41)
TABLE(s2+100,235,43,42,234,238,46,47,239,45,237)
TABLE(s2+110,236,44,228,36,37,229,39,231,230,38)
TABLE(s2+120,34,226,227,35,225,33,32,224,160,96)
TABLE(s2+130,97,161,99,163,162,98,102,166,167,103)
TABLE(s2+140,165,101,100,164,108,172,173,109,175,111)
TABLE(s2+150,110,174,170,106,107,171,105,169,168,104)
TABLE(s2+160,120,184,185,121,187,123,122,186,190,126)
TABLE(s2+170,127,191,125,189,188,124,180,116,117,181)
TABLE(s2+180,119,183,182,118,114,178,179,115,177,113)
TABLE(s2+190,112,176,80,144,145,81,147,83,82,146)
TABLE(s2+200,150,86,87,151,85,149,148,84,156,92)
TABLE(s2+210,93,157,95,159,158,94,90,154,155,91)
TABLE(s2+220,153,89,88,152,136,72,73,137,75,139)
TABLE(s2+230,138,74,78,142,143,79,141,77,76,140)
TABLE(s2+240,68,132,133,69,135,71,70,134,130,66)
TABLE(s2+250,67,131,65,129,128,64)
RETURN
test:
WHILE(KEY#2)
GET#2,daf
PRINT#5,daf
WEND
RETURN