📄 msbl21xx.c
字号:
0x00001 -> 0x00016 (Digital Output 0 -> Digital Output 15)
\*=========================================================================*/
int msOutWr(unsigned wCoil, int bState)
{
// Check to see if a valid output channel is being called.
if ( wCoil > (OUTPUT_AMOUNT) ) return MS_BADADDR;
// update the shadow used in the msOutRd function.
acShad[wCoil] = bState;
// Update the digital outpu;
digOut(wCoil,bState);
return 0;
}
/*=========================================================================*\
msIn: (02: Discrete Input Status)
Used for reading the state of the individual digital inputs.
registers used;
0x10001 -> 0x10024 (Digital Input 0 -> Digital Input 23)
\*=========================================================================*/
int msIn(unsigned wCoil, int *pnState)
{
// Check to see if a valid input channel is being called.
if (wCoil > INPUT_AMOUNT) return MS_BADADDR;
// Read the input and store it.
*pnState = digIn(wCoil);
return 0;
}
/*=========================================================================*\
msInput: (04: Reading from a Input Register)
For reading the individual CALIBRATED values of each adc inputs.
Since Modbus deals with unsigned ints (words), and our VDC input
function returns a float, the function will need to store the value
as two registers type casted into unsigned ints for the Modbus
protocol to accept properly. How this is done must be the same for
both the Master and the slave. This example shows one way to
accomplish that. The Master must use the same method for decoding
the two unsigned ints and convert it back to a float. A sample of
this is the msWrite function that converts 2 unsigned ints into a
float for use with the DAC outputs.
registers used;
0x30001 -> 0x30002 = Float val of ADC 0
0x30003 -> 0x30004 = Float val of ADC 1
0x30005 -> 0x30006 = Float val of ADC 2
0x30007 -> 0x30008 = Float val of ADC 3
0x30009 -> 0x30010 = Float val of ADC 4
0x30011 -> 0x30012 = Float val of ADC 5
0x30013 -> 0x30014 = Float val of ADC 6
0x30015 -> 0x30016 = Float val of ADC 7
0x30017 -> 0x30018 = Float val of ADC 8
0x30019 -> 0x30020 = Float val of ADC 9
0x30021 -> 0x30022 = Float val of ADC 10
\*=========================================================================*/
int msInput(unsigned wReg, unsigned *pwValue)
{
static float calVal;
static unsigned int uiVal[2];
// Since it will take two registers per input, you must double the
// amount of register neccessary.
if (wReg > (ADC_AMOUNT * 2) ) return MS_BADADDR;
// if the input is odd the get the new adc value
if ( !(wReg % 2) )
{
// You must divide the wReg value by 2 when getting the proper channel
calVal = anaInVolts(wReg/2);
// move the adc float value int a holding array of 4 bytes
*(float *) & uiVal[0] = calVal;
// copy the first 2 bytes of the holding array into the register value
*pwValue = uiVal[0];
}
// if the register is even
else
{
// copy the last 2 bytes of the holding array into the register value.
// DO NOT recalculate the input value.
*pwValue = uiVal[1];
}
return 0;
}
/*=========================================================================*\
msWrite: (03: Writing to Holding Registers)
Will write to the DAC channels (0-3) This function will take a
converted float valued (from 2 unsigned int values) and update the
DAC output values (in Volts 0-10VDC). It also will update the
analog output shadow register aoShad[analog output] used in the
msRead function.
registers used;
0x40001 -> 0x40002 = Float val for DAC 0
0x40003 -> 0x40004 = Float val for DAC 1
0x40005 -> 0x40006 = Float val for DAC 2
0x40007 -> 0x40008 = Float val for DAC 0
\*=========================================================================*/
nodebug
int msWrite(unsigned wReg, unsigned wValue)
{
static unsigned int uiVal[2];
static float fVal;
if (wReg > (DAC_AMOUNT * 2) ) return MS_BADADDR;
// Will store the first of the register pairs starting with the odd number
if ( !(wReg % 2) )
{
uiVal[0] = wValue;
}
// if the register is even
else
{
// store the next register value
uiVal[1] = wValue;
// typecast the two stored values and save it as a float value.
fVal = * (float *) &uiVal[0];
if (fVal <= MAX_DAC_VOLTS)
{
// update the new analog output value.
anaOutVolts(wReg/2, fVal);
// store the new updated value into its shadow register.
aoShad[wReg/2] = fVal;
}
else return MS_BADDATA;
}
return 0;
}
/*=========================================================================*\
msRead: (03: Reading Holding Registers)
Will read the DAC channels shadow register value.
The Data being sent comes from the shadow registers that are being
updated by msWrite.
registers used;
0x40001 -> 0x40002 float value of DAC channel 0
0x40003 -> 0x40004 float value of DAC channel 1
0x40005 -> 0x40006 float value of DAC channel 2
0x40007 -> 0x40008 float value of DAC channel 3
\*=========================================================================*/
int msRead (unsigned wReg, unsigned *pwValue)
{
static unsigned int uiVal[2];
// Since it will take two registers per input, you must double the
// amount of register neccessary.
if (wReg > (DAC_AMOUNT * 2) ) return MS_BADADDR;
if ( !(wReg % 2) )
{
// copy the first 2 bytes of the holding array into the register value
*(float *) & uiVal[0] = aoShad[wReg/2];
*pwValue = uiVal[0];
}
// if the register is even
else
{
// copy the last 2 bytes of the holding array into the register value.
*pwValue = uiVal[1];
}
return 0;
}
/******************* End of Modbus Functions ******************************/
/******************* Main Function *****************************************\
Basic setup of the controller. Once Modbus is setup, a call to msRun()
needs to be called continually called. Other functionalities can be
added as long as they do not block. (i.e while loops for loops etc.).
\***************************************************************************/
void main(void)
{
auto int loop;
// Clear the output shadow arrays at startup of this sample
memset(acShad, 0, sizeof(acShad));
memset(aoShad, 0, sizeof(aoShad));
// initialize the SBC
brdInit();
// initializing the outputs to be Sourcing.
digOutConfig(0xFFFF);
#if (!MODBUS_TYPE)
// Open Serial port D in ASCII mode
msaDinit(SLAVE_ADDRESS, MODBUS_BAUDRATE);
#else
// Open Serial port D in RTU mode
msrDinit(SLAVE_ADDRESS, MODBUS_BAUDRATE);
#endif
// If there are analog inputs required, get the cal. constants from the
// eeprom.
if (ADC_AMOUNT > 0 )
{
// read in the cal. constants.
for (loop = 0 ; loop < ADC_AMOUNT ; loop++) anaInEERd(loop);
}
// If there are analog outputs required, get the cal. constants from the
// eeprom.
if (DAC_AMOUNT > 0 )
{
// read in the cal. constants.
for (loop = 0 ; loop < DAC_AMOUNT ; loop++) anaOutEERd(loop);
}
for( ;; )
{
// Modbus slave handler function. It must be in a continous loop.
msRun();
// Other Costates Here!!! (Make sure your code does not block.)
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -