View previous topic :: View next topic |
Author |
Message |
wewa
Joined: 02 Jul 2008 Posts: 27
|
Configure PIC18F4525 as modbus-slave (ex_modbus.c) |
Posted: Mon Aug 09, 2010 9:38 am |
|
|
Hello,
Can anyone help me to configure a PIC18F4525 as a modbus-slave. Using the ccs-example-project "ex_modbus_slave.c"?
Here's the wiring:
Code: |
--------------------- --------------------------------
| |
PIN_B1 0------------0 1 (Receive) RS485-Transreceiver
| | SN75LBC184D
PIC PIN_C5 0-------+----0 2 (Receive Enable)
18F4525 | | |
| +----0 3 (Transmit Enable)
| |
PIN_D3 0------------0 4 (Transmit)
| |
--------------------- --------------------------------
|
How do I have to edit the config file?
Mine looks like this:
Code: |
#include <18F4525.h>
//#device *=16
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT, MCLR
#use delay(clock=20000000)
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
#ifndef USE_WITH_PC
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_EXT
#define MODBUS_SERIAL_TX_PIN PIN_D3 // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_B1 // Data receive pin
//The following should be defined for RS485 communication
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5 // Controls DE pin for RS485
//#define MODBUS_SERIAL_RX_ENABLE 0 // Controls RE pin for RS485
#else
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_EXT
#endif
#include "modbus.c"
|
I got this ex_modbus_slave.c working with a PIC16F87A (using the Pins B0, B1 and B2 of the pic). But with the PIC18F4525 I have problems.
Thanks for any help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 09, 2010 11:59 am |
|
|
The logical thing to do, if it works on a 16F but fails on an 18F would be to:
1. Look for hard-coded register addresses in the code, because they
are different between the two PIC families. I didn't see any of that.
2. Next, look for differences in pin features. Maybe the pins that are
used on a 16F are input-only on the 18F, or some other difference.
So I noticed that ex_modbus_slave.c has these pin definitions.
Quote: | #else
#define MODBUS_SERIAL_TX_PIN PIN_B1 // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_B0 // Data receive pin |
These aren't the hardware pins, so they're using a software UART.
I then wondered strongly if they are using #int_ext to do interrupt-driven
reception of the incoming bytes. That interrupt is available on Pin B0.
So I looked in the modbus.c and found that yes, they are using INT_EXT
for pin B0.
Quote: |
// Purpose: Interrupt service routine for handling incoming serial data
// Inputs: None
// Outputs: None
#elif (MODBUS_SERIAL_INT_SOURCE==MODBUS_INT_EXT)
#if defined(__PCD__)
#int_ext0
#else
#int_ext
#endif
|
Then I go back to your code and see that you have changed the Rx pin
into B1, which does not have the #int_ext interrupt on it.
Quote: |
#define MODBUS_SERIAL_TX_PIN PIN_D3 // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_B1 // Data receive pin |
Now, it does have another interrupt on it. It has #INT_EXT1.
You could edit modbus.c to use #int_ext1 instead of #int_ext.
But in my opinion it would be a lot cleaner and easier just to change
your hardware to use pin B0. Then you don't have to edit the driver code. |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Mon Aug 09, 2010 1:12 pm |
|
|
Thanks for your reply.
I think in the default configuration of ex_modbus_slave.c the interrupt is not used. Because interrupt is only used, when MODBUS_SERIAL_INT_SOURCE is set to MODBUS_INT_EXT. But in ex_modbus_slave.c MODBUS_SERIAL_INT_SOURCE is set to MODBUS_INT_RDA. (I think they are using software UART.) |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Tue Aug 10, 2010 7:57 am |
|
|
Sorry I was wrong, you were right.
By default MODBUS_SERIAL_INT_SOURCE is set to MODBUS_INT_EXT.
I don't have the possibility to use PIN_B0 instead of PIN_B1. Therefore I need to tell the program to use INT_EXT1.
But it seems that the program never goes into interrupt. Why? (I have changed all parts of ex_modbus_slave.c from INT_EXT to INT_EXT1 and ext_int_edge(H_TO_L); to ext_int_edge(1, H_TO_L);. Do I need to make further changes? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 10, 2010 1:46 pm |
|
|
Look at the .LST file to make sure that it's being compiled the way that
you want it to be. Look in the .LST file to see if an #int_ext1 routine
exists (look for the ASM code). |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Wed Aug 11, 2010 1:18 am |
|
|
I'm a fool.
You gave me the tip how to solve my problem. It was a really simple problem.
In the .LST file I saw that #int_ext1 not exists. And than i noticed that in ex_modbus_slave.c modbus.c was included. And I edited the file ex_modbus.c ......... Now it works.
Thank you very much for your help and patience. |
|
|
|