|
|
View previous topic :: View next topic |
Author |
Message |
koray_duran
Joined: 04 Feb 2010 Posts: 37
|
problem with modbus library |
Posted: Thu Sep 15, 2011 1:23 am |
|
|
Hi,
I've trying to implement modbus slave example to my project. But even i am not successful to compile original codes. Nothing is modified in library.
Error is :
#byte TXSTA=getenv("sfr:TXSTA")
#bit TRMT=TXSTA.1
Undefined identifier
Expecting a (
Here is my codes :
Code: |
#include <18F67J60.h>
#fuses HS, NOWDT, NOPROTECT
#use delay(clock=25M)
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_RX_PIN PIN_C7 // Data receive pin
#define MODBUS_SERIAL_TX_PIN PIN_C6 // Data transmit pin
#include "modbus.c"
#define MODBUS_ADDRESS 0xF7
/*This function may come in handy for you since MODBUS uses MSB first.*/
int8 swap_bits(int8 c)
{
return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
|((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}
void main()
{
int8 coils = 0b00000101;
int8 inputs = 0b00001001;
int16 hold_regs[] = {0x8800,0x7700,0x6600,0x5500,0x4400,0x3300,0x2200,0x1100};
int16 input_regs[] = {0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800};
int16 event_count = 0;
modbus_init();
while(TRUE)
{
while(!modbus_kbhit());
//check address against our address, 0 is broadcast
if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0)
{
switch(modbus_rx.func)
{
case FUNC_READ_COILS: //read coils
case FUNC_READ_DISCRETE_INPUT: //read inputs
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int8 data;
if(modbus_rx.func == FUNC_READ_COILS)
data = coils>>(modbus_rx.data[1]); //move to the starting coil
else
data = inputs>>(modbus_rx.data[1]); //move to the starting input
data = data & (0xFF>>(8-modbus_rx.data[3])); //0 out values after quantity
if(modbus_rx.func == FUNC_READ_COILS)
modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
else
modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
event_count++;
}
break;
case FUNC_READ_HOLDING_REGISTERS:
case FUNC_READ_INPUT_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS)
modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]);
else
modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_COIL: //write coil
if(modbus_rx.data[0] || modbus_rx.data[3] || modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else if(modbus_rx.data[2] != 0xFF && modbus_rx.data[2] != 0x00)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_VALUE);
else
{
//coils are stored msb->lsb so we must use 7-address
if(modbus_rx.data[2] == 0xFF)
bit_set(coils,7-modbus_rx.data[1]);
else
bit_clear(coils,7-modbus_rx.data[1]);
modbus_write_single_coil_rsp(MODBUS_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_REGISTER:
if(modbus_rx.data[0] || modbus_rx.data[1] >= 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
//the registers are stored in little endian format
hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[3],modbus_rx.data[2]);
modbus_write_single_register_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
}
break;
case FUNC_WRITE_MULTIPLE_COILS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
modbus_rx.data[5] = swap_bits(modbus_rx.data[5]);
for(i=modbus_rx.data[1],j=0; i < modbus_rx.data[1]+modbus_rx.data[3]; ++i,++j)
{
if(bit_test(modbus_rx.data[5],j))
bit_set(coils,7-i);
else
bit_clear(coils,7-i);
}
modbus_write_multiple_coils_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
case FUNC_WRITE_MULTIPLE_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);
modbus_write_multiple_registers_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
default: //We don't support the function, so return exception
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
}
}
}
}
|
In this part of library doesn't expect error mode:
Code: |
#if( MODBUS_SERIAL_INT_SOURCE == MODBUS_INT_RDA )
#use rs232(baud=MODBUS_SERIAL_BAUD, UART1, parity=N, stream=MODBUS_SERIAL)
|
Here occurs error:
Code: |
#if (MODBUS_SERIAL_INT_SOURCE != MODBUS_INT_EXT)
#byte TXSTA=getenv("sfr:TXSTA")
#bit TRMT=TXSTA.1
#define WAIT_FOR_HW_BUFFER()\
{\
while(!TRMT);\
}
#endif
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 15, 2011 3:19 pm |
|
|
Quote: | But even i am not successful to compile original codes.
|
Post your compiler version so we can install it and try to duplicate your
problem. It could be a problem with your version only. Post it. |
|
|
koray_duran
Joined: 04 Feb 2010 Posts: 37
|
|
Posted: Mon Sep 19, 2011 6:57 am |
|
|
IDE 4.057
PCB 4.068
PCM 4.068
PCH 4.068
PCD 4.057 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 19, 2011 1:30 pm |
|
|
In vs. 4.068, I had to fix the following problems in modbus.c.
There are two #use rs232() statements near the start of the file that
have "error" as a parameter. It should be "errors", as shown in bold below:
Quote: |
if( MODBUS_SERIAL_INT_SOURCE == MODBUS_INT_RDA )
#use rs232(baud=MODBUS_SERIAL_BAUD, UART1, parity=N, stream=MODBUS_SERIAL, errors) // *** FIXED
#define RCV_OFF() {disable_interrupts(INT_RDA);}
#elif( MODBUS_SERIAL_INT_SOURCE == MODBUS_INT_RDA2 )
#use rs232(baud=MODBUS_SERIAL_BAUD, UART2, parity=N, stream=MODBUS_SERIAL, errors) // *** FIXED
#define RCV_OFF() {disable_interrupts(INT_RDA2);}
|
The fact that it has that simple error implies that the released version of
modbus.c was never tested fully in vs. 4.068. I tested Vs. 4.124 doesn't
have this problem.
The next problem is caused by your choice of a PIC. The 18F67J60 has
two hardware UARTs, so there is no TXSTA. There is instead, TXSTA1
and TXSTA2. So to fix the problem, edit the lines to say "TXSTA1".
Quote: |
#if (MODBUS_SERIAL_INT_SOURCE != MODBUS_INT_EXT)
#byte TXSTA1=getenv("sfr:TXSTA1")
#bit TRMT=TXSTA1.1
|
|
|
|
koray_duran
Joined: 04 Feb 2010 Posts: 37
|
|
Posted: Tue Sep 20, 2011 9:10 am |
|
|
Thanks PCM Programmer
I should mind it before! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|