📄 msbl21xx.c
字号:
/********* Sample Program ****************************************************
MSBl21xx.c Copyright(c) 2003 Z-World Engineering.
Legal Notice This program has been written by the Technical Support Staff at
Z-World in response to several customer requests. As such, it
has NOT had the testing and validation procedures which our
"standard" software products have. It is being made available
as a sample. There is no warranty, implied or otherwise.
DESCRIPTION: Sample program demonstrating modbus slave control via RS485
for the BL21xx SBC's.
This sample will allow control via a Modbus Master controller
of the following;
1. Read from/Write to digital outputs
2. Read the status of digital inputs
3. Read the Analog inputs (Cal. Data).
4. Read from/Write to the analog output channels (Cal. data).
MODBUS
COMMAND
FUNCTIONS
USED:
01: Discrete Coil Status
01: Discrete Coil Writing
02: Discrete Input Status
03: Holding Register Status
03: Holding Register Writing
04: Input Register Status
The modbus master software used with this sample can be
downloaded (Demo Version) via the following company link.
WinTECH Software Systems incorporated
http://www.win-tech.com
(modscan32.exe)
NOTES: This sample does show 1 technique on how to convert float
values (in this case the analog channel values), to unsigned
int register pairs for use with the Modbus master.
*****************************************************************************/
/****** Start of user configurable macros *********************************/
// Define the number of channels for each type of input
// Number of analog inputs/outputs.
#define ADC_AMOUNT 11
#define DAC_AMOUNT 4
// Maximum VDC output allowed, If the Master tries to send a value higher
// a MS_BADDATA (0x03) err will be sent back.
#define MAX_DAC_VOLTS 10.00
// Number of digitial I/O
#define INPUT_AMOUNT 24
#define OUTPUT_AMOUNT 16
// Provide an ID for the slave device. It MUST BE UNIQUE from any other
// Modbus device connected. (Address 0 is the Master device).
#define SLAVE_ADDRESS 0x01
// The baudrate used for the MODBUS protocol.
#define MODBUS_BAUDRATE 9600 // 9600 is default, 19200 works to.
// Choose the protocol type, 0 for ASCII, 1 for RTU. This MUST match the
// Modbus master protocol selection.
#define MODBUS_TYPE 1
/****** Done with user configurable macros *********************************/
// Setup up the serial port buffer size
#define DINBUFSIZE 31
#define DOUTBUFSIZE 31
// Modbus slave library, it also calls ms_rab.lib
#use "msz_rab.lib"
// Digital Output Shadow Registers
char acShad[OUTPUT_AMOUNT + 1];
// Analog Output Shadow Registers
float aoShad[DAC_AMOUNT + 1];
/************************ MODBUS FUNCTIONS *********************************\
The following are the individual Modbus functions. The function Names must
stay the same for they are used in the ms_rab.lib. The content of the
function will change for each application. The following functions are
required to be in you application;
msDone, msStart, and msRun
msXinit, msXrx, msXtx (X = A,B,C, or D for the serial port you are using).
/***************************************************************************/
/*=========================================================================*\
msDone:
Called just after a received Modbus command has been
processed and just before the reply is sent. This function is intended
to be used to unlock resources that were locked by msStart(). Locking
resources may or may not be required, depending on how the msIn(),
msInput(), msOutRd() and msOutWr() functions are implemented in a
particular Modbus slave application. Note that Modbus command handler
functions in MS_RAB.LIB may make multiple calls to those functions while
responding to a single Modbus command.
\*=========================================================================*/
nodebug
void msDone(void)
{
// place any locked resources required.
}
/*=========================================================================*\
msStart:
Called just before a received Modbus packet is processed,
this function is primarily intended to be used to lock resources so
that data returned in one Modbus response packet are atomic. Locking
resources may or may not be required, depending on how the msIn(),
msInput(), msOutRd() and msOutWr() functions are implemented in a
particular Modbus slave application. Note that Modbus command handler
functions in MS_RAB.LIB may make multiple calls to those functions while
responding to a single Modbus command.
\*=========================================================================*/
nodebug
void msStart(void)
{
// place any locked resources required.
}
/*=========================================================================*\
msDinit:
Sets up and opens the serial port. default settings are 8 data bits
1 stop bit, no parity, no flow control. You can change the settings
to match the Modbus serial control of your system.
\*=========================================================================*/
int msDinit(unsigned qBaud)
{
// Open the serial port. THIS MUST BE DONE PRIOR TO SETTING THE
// DATA BITS AND PARITY SETTINGS.
serDopen(qBaud);
// setup parity. Either PARAM_OPARITY, PARAM_EPARITY, PARAM_NOPARITY,
// or PARAM_2STOP
serDparity(PARAM_EPARITY);
// setup data bits. Either PARAM_7BIT, or PARAM_8BIT
serDdatabits(PARAM_8BIT);
// Set the Serial port mode. Used for Zworld SBC's only.
serMode(0);
return(1);
}
/*=========================================================================*\
msDtx:
User definable function for enabling the rs485 transmitter (if needed).
If you are doing RS232 simply leave the function blank. The function
itself must be present.
\*=========================================================================*/
void msDtx()
{
// Turn on the transmitter.
ser485Tx();
}
/*=========================================================================*\
msDrx:
User definable function for disabling the rs485 transmitter (if needed).
If you are doing RS232 simply leave the function blank. The function
itself must be present.
\*=========================================================================*/
void msDrx()
{
// Make sure all of the data has been sent by;
// 1.) checking the write buffer for any bytes left
// 2.) checking the status of the Write interrupt transmit bit (2).
// 3.) checking the status of the Write interrupt data bit (3)
while (serDwrUsed() || BitRdPortI(SDSR,2) || BitRdPortI(SDSR,3));
// turn off the transmitter
ser485Rx();
// Since we echo what we send, flush the read buffer, so that you are
// ready for the next packet.
serDrdFlush();
}
/*=========================================================================*\
msOutRd: (01: Discrete Coil Status)
Used for reading output coil status. A user defined shadow register
is required in your code which will be updated when digital
outputs change states using the msOutWr function.
registers used;
0x00001 -> 0x00016 Digital Output 0 -> Digital Output 15
\*=========================================================================*/
int msOutRd(unsigned wCoil, int *pnState)
{
// Check to see if a valid output channel is being called.
if (wCoil > (OUTPUT_AMOUNT) ) return MS_BADADDR;
// copy the contents of the coil shadow element.
*pnState = acShad[wCoil];
return 0;
}
/*=========================================================================*\
msOutWr: (01: Discrete Coil Writing)
Used for Writing to individual output coils, as well as updating
the shadow register used in the above function msOutRd.
registers used;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -